1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
From: David Banks <amoebae@gmail.com>
Date: Wed, 14 Jan 2015 21:41:00 +0000
Subject: Avoid double-counting rotfish
Bug: https://sourceforge.net/p/quakespasm/bugs/7/
---
Quake/pr_edict.c | 20 ++++++++++++++++++++
Quake/progs.h | 1 +
Quake/server.h | 1 +
Quake/sv_main.c | 2 ++
Quake/sv_phys.c | 25 ++++++++++++++++++++++++-
5 files changed, 48 insertions(+), 1 deletion(-)
--- a/Quake/pr_edict.c
+++ b/Quake/pr_edict.c
@@ -85,6 +85,7 @@
cvar_t saved2 = {"saved2", "0", CVAR_ARCHIVE};
cvar_t saved3 = {"saved3", "0", CVAR_ARCHIVE};
cvar_t saved4 = {"saved4", "0", CVAR_ARCHIVE};
+extern cvar_t sv_fishfix;
/*
=================
@@ -985,6 +986,8 @@
dfunction_t *func;
edict_t *ent = NULL;
int inhibit = 0;
+ int oldcount;
+ sv.fish_counted = false;
pr_global_struct->time = sv.time;
@@ -1048,7 +1051,20 @@
SV_ReserveSignonSpace (512);
pr_global_struct->self = EDICT_TO_PROG(ent);
+
+ if (!sv.fish_counted && sv_fishfix.value && !strcmp(PR_GetString(func->s_name), "monster_fish"))
+ {
+ oldcount = pr_global_struct->total_monsters;
+ }
+ else oldcount = -1;
+
PR_ExecuteProgram (func - pr_functions);
+
+ if (oldcount != -1)
+ {
+ if (pr_global_struct->total_monsters > oldcount)
+ sv.fish_counted = true;
+ }
}
Con_DPrintf ("%i entities inhibited\n", inhibit);
@@ -1328,6 +1344,10 @@
}
}
+const char *PR_GetFunctionName(int num) {
+ return PR_GetString(pr_functions[num].s_name);
+}
+
int PR_SetEngineString (const char *s)
{
int i;
--- a/Quake/progs.h
+++ b/Quake/progs.h
@@ -77,6 +77,7 @@
void PR_LoadProgs (void);
const char *PR_GetString (int num);
+const char *PR_GetFunctionName (int num);
int PR_SetEngineString (const char *s);
int PR_AllocString (int bufferlength, char **ptr);
--- a/Quake/server.h
+++ b/Quake/server.h
@@ -78,6 +78,7 @@
unsigned protocol; //johnfitz
unsigned protocolflags;
+ int fish_counted;
} server_t;
--- a/Quake/sv_main.c
+++ b/Quake/sv_main.c
@@ -87,6 +87,7 @@
extern cvar_t sv_idealpitchscale;
extern cvar_t sv_aim;
extern cvar_t sv_altnoclip; //johnfitz
+ extern cvar_t sv_fishfix;
sv.edicts = NULL; // ericw -- sv.edicts switched to use malloc()
@@ -105,6 +106,7 @@
Cvar_RegisterVariable (&sv_nostep);
Cvar_RegisterVariable (&sv_freezenonclients);
Cvar_RegisterVariable (&sv_altnoclip); //johnfitz
+ Cvar_RegisterVariable (&sv_fishfix);
Cmd_AddCommand ("sv_protocol", &SV_Protocol_f); //johnfitz
--- a/Quake/sv_phys.c
+++ b/Quake/sv_phys.c
@@ -47,7 +47,7 @@
cvar_t sv_maxvelocity = {"sv_maxvelocity","2000",CVAR_NONE};
cvar_t sv_nostep = {"sv_nostep","0",CVAR_NONE};
cvar_t sv_freezenonclients = {"sv_freezenonclients","0",CVAR_NONE};
-
+cvar_t sv_fishfix = {"sv_fishfix", "1", CVAR_ARCHIVE};
#define MOVE_EPSILON 0.01
@@ -123,6 +123,7 @@
qboolean SV_RunThink (edict_t *ent)
{
float thinktime;
+ int oldcount;
thinktime = ent->v.nextthink;
if (thinktime <= 0 || thinktime > sv.time + host_frametime)
@@ -140,8 +141,30 @@
pr_global_struct->time = thinktime;
pr_global_struct->self = EDICT_TO_PROG(ent);
pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
+
+ if ((sv.time == 1.0) && sv_fishfix.value && sv.fish_counted &&
+ !strcmp(PR_GetString(ent->v.classname), "monster_fish") &&
+ !strcmp(PR_GetFunctionName(ent->v.think), "swimmonster_start_go"))
+ {
+ oldcount = pr_global_struct->total_monsters;
+ }
+ else oldcount = -1;
+
PR_ExecuteProgram (ent->v.think);
+ if (oldcount != -1)
+ {
+ if (pr_global_struct->total_monsters - oldcount == 1)
+ {
+ pr_global_struct->total_monsters -= 1;
+ if (sv.fish_counted == 1)
+ {
+ Con_Printf ("Detected fish-count bug in progs.dat; monster count has been adjusted\n");
+ sv.fish_counted++;
+ }
+ }
+ }
+
return !ent->free;
}
|