File: rotfish-double-count.patch

package info (click to toggle)
quakespasm 0.96.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,520 kB
  • sloc: ansic: 56,156; sh: 325; makefile: 271; xml: 69
file content (152 lines) | stat: -rw-r--r-- 3,788 bytes parent folder | download | duplicates (2)
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;
 }