Reset gibsthisframe and lastgibframe at map change

Without this change the conditionals at g_misc.c:199 and 381 wouldn't
trigger until level.framenum reach it's previous value, resulting in
much to few debris or gibs being thrown. This fixes #104.

Many thanks to maraakate for the analysis and the idea how to fix it.
This commit is contained in:
Yamagi Burmeister 2015-10-24 13:14:31 +02:00
parent 0516300a11
commit 8a40cd5e9f
3 changed files with 29 additions and 22 deletions

View file

@ -279,7 +279,7 @@ EndDMLevel(void)
ent = G_Find(NULL, FOFS(classname), "target_changelevel"); ent = G_Find(NULL, FOFS(classname), "target_changelevel");
if (!ent) if (!ent)
{ {
/* the map designer didn't include a changelevel, /* the map designer didn't include a changelevel,
so create a fake ent that goes back to the same level */ so create a fake ent that goes back to the same level */
BeginIntermission(CreateTargetChangeLevel(level.mapname)); BeginIntermission(CreateTargetChangeLevel(level.mapname));
@ -384,6 +384,9 @@ ExitLevel(void)
ent->health = ent->client->pers.max_health; ent->health = ent->client->pers.max_health;
} }
} }
gibsthisframe = 0;
lastgibframe = 0;
} }
/* /*

View file

@ -1,7 +1,7 @@
#include "header/local.h" #include "header/local.h"
int gibsthisframe = 0; int gibsthisframe;
int lastgibframe = 0; int lastgibframe;
/* /*
* QUAKED func_group (0 0 0) ? * QUAKED func_group (0 0 0) ?
@ -972,7 +972,7 @@ void
SP_func_explosive(edict_t *self) SP_func_explosive(edict_t *self)
{ {
if (deathmatch->value) if (deathmatch->value)
{ {
/* auto-remove for deathmatch */ /* auto-remove for deathmatch */
G_FreeEdict(self); G_FreeEdict(self);
return; return;
@ -1147,7 +1147,7 @@ void
SP_misc_explobox(edict_t *self) SP_misc_explobox(edict_t *self)
{ {
if (deathmatch->value) if (deathmatch->value)
{ {
/* auto-remove for deathmatch */ /* auto-remove for deathmatch */
G_FreeEdict(self); G_FreeEdict(self);
return; return;
@ -1438,7 +1438,7 @@ void
SP_misc_deadsoldier(edict_t *ent) SP_misc_deadsoldier(edict_t *ent)
{ {
if (deathmatch->value) if (deathmatch->value)
{ {
/* auto-remove for deathmatch */ /* auto-remove for deathmatch */
G_FreeEdict(ent); G_FreeEdict(ent);
return; return;
@ -2136,7 +2136,7 @@ teleporter_touch(edict_t *self, edict_t *other, cplane_t *plane,
/* set angles */ /* set angles */
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
other->client->ps.pmove.delta_angles[i] = other->client->ps.pmove.delta_angles[i] =
ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]);
} }

View file

@ -29,7 +29,7 @@
#include "shared.h" #include "shared.h"
/* define GAME_INCLUDE so that game.h does not define the /* define GAME_INCLUDE so that game.h does not define the
short, server-visible gclient_t and edict_t structures, short, server-visible gclient_t and edict_t structures,
because we define the full size ones in this file */ because we define the full size ones in this file */
#define GAME_INCLUDE #define GAME_INCLUDE
@ -259,8 +259,8 @@ typedef struct gitem_s
char *precaches; /* string of all models, sounds, and images this item will use */ char *precaches; /* string of all models, sounds, and images this item will use */
} gitem_t; } gitem_t;
/* this structure is left intact through an entire game /* this structure is left intact through an entire game
it should be initialized at dll load time, and read/written to it should be initialized at dll load time, and read/written to
the server.ssv file for savegames */ the server.ssv file for savegames */
typedef struct typedef struct
{ {
@ -271,7 +271,7 @@ typedef struct
gclient_t *clients; /* [maxclients] */ gclient_t *clients; /* [maxclients] */
/* can't store spawnpoint in level, because /* can't store spawnpoint in level, because
it would get overwritten by the savegame restore */ it would get overwritten by the savegame restore */
char spawnpoint[512]; /* needed for coop respawns */ char spawnpoint[512]; /* needed for coop respawns */
@ -288,7 +288,7 @@ typedef struct
qboolean autosaved; qboolean autosaved;
} game_locals_t; } game_locals_t;
/* this structure is cleared as each map is entered /* this structure is cleared as each map is entered
it is read/written to the level.sav file for savegames */ it is read/written to the level.sav file for savegames */
typedef struct typedef struct
{ {
@ -333,8 +333,8 @@ typedef struct
int power_cubes; /* ugly necessity for coop */ int power_cubes; /* ugly necessity for coop */
} level_locals_t; } level_locals_t;
/* spawn_temp_t is only used to hold entity field values that /* spawn_temp_t is only used to hold entity field values that
can be set from the editor, but aren't actualy present can be set from the editor, but aren't actualy present
in edict_t during gameplay */ in edict_t during gameplay */
typedef struct typedef struct
{ {
@ -446,6 +446,10 @@ extern spawn_temp_t st;
extern int sm_meat_index; extern int sm_meat_index;
extern int snd_fry; extern int snd_fry;
extern int gibsthisframe;
extern int lastgibframe;
/* means of death */ /* means of death */
#define MOD_UNKNOWN 0 #define MOD_UNKNOWN 0
#define MOD_BLASTER 1 #define MOD_BLASTER 1
@ -543,7 +547,7 @@ extern cvar_t *sv_maplist;
#define DROPPED_PLAYER_ITEM 0x00020000 #define DROPPED_PLAYER_ITEM 0x00020000
#define ITEM_TARGETS_USED 0x00040000 #define ITEM_TARGETS_USED 0x00040000
/* fields are needed for spawning from the entity string /* fields are needed for spawning from the entity string
and saving / loading games */ and saving / loading games */
#define FFL_SPAWNTEMP 1 #define FFL_SPAWNTEMP 1
@ -793,7 +797,7 @@ typedef struct
char netname[16]; char netname[16];
int hand; int hand;
qboolean connected; /* a loadgame will leave valid entities that qboolean connected; /* a loadgame will leave valid entities that
just don't have a connection yet */ just don't have a connection yet */
/* values saved and restored from edicts when changing levels */ /* values saved and restored from edicts when changing levels */
@ -842,7 +846,7 @@ typedef struct
int helpchanged; int helpchanged;
} client_respawn_t; } client_respawn_t;
/* this structure is cleared on each PutClientInServer(), /* this structure is cleared on each PutClientInServer(),
except for 'client->pers' */ except for 'client->pers' */
struct gclient_s struct gclient_s
{ {
@ -872,7 +876,7 @@ struct gclient_s
gitem_t *newweapon; gitem_t *newweapon;
/* sum up damage over an entire frame, so /* sum up damage over an entire frame, so
shotgun blasts give a single big kick */ shotgun blasts give a single big kick */
int damage_armor; /* damage absorbed by armor */ int damage_armor; /* damage absorbed by armor */
int damage_parmor; /* damage absorbed by power armor */ int damage_parmor; /* damage absorbed by power armor */
@ -941,9 +945,9 @@ struct gclient_s
struct edict_s struct edict_s
{ {
entity_state_t s; entity_state_t s;
struct gclient_s *client; /* NULL if not a player struct gclient_s *client; /* NULL if not a player
the server expects the first part the server expects the first part
of gclient_s to be a player_state_t of gclient_s to be a player_state_t
but the rest of it is opaque */ but the rest of it is opaque */
qboolean inuse; qboolean inuse;
@ -1000,7 +1004,7 @@ struct edict_s
vec3_t avelocity; vec3_t avelocity;
int mass; int mass;
float air_finished; float air_finished;
float gravity; /* per entity gravity multiplier (1.0 is normal) float gravity; /* per entity gravity multiplier (1.0 is normal)
use for lowgrav artifact, flares */ use for lowgrav artifact, flares */
edict_t *goalentity; edict_t *goalentity;