diff --git a/include/QF/progs.h b/include/QF/progs.h index 2ecbcbac8..cac7dc518 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -78,6 +78,7 @@ edict_t *PR_InitEdicts (progs_t *pr, int num_edicts); void PR_Profile_f (void); +void ED_ClearEdict (progs_t * pr, edict_t *e, int val); edict_t *ED_Alloc (progs_t *pr); void ED_Free (progs_t *pr, edict_t *ed); @@ -256,6 +257,7 @@ struct progs_s { int (*parse_field)(progs_t *pr, const char *key, const char *value); int (*prune_edict)(progs_t *pr, edict_t *ent); + void (*free_edict)(progs_t *pr, edict_t *ent); builtin_t *builtins; int numbuiltins; diff --git a/libs/gamecode/pr_edict.c b/libs/gamecode/pr_edict.c index f6e04386e..2a9127a8d 100644 --- a/libs/gamecode/pr_edict.c +++ b/libs/gamecode/pr_edict.c @@ -196,7 +196,10 @@ ED_Free (progs_t * pr, edict_t *ed) if (pr_deadbeef->int_val) { ED_ClearEdict (pr, ed, 0xdeadbeef); } else { - ED_ClearEdict (pr, ed, 0); + if (pr->free_edict) + pr->free_edict (pr, ed); + else + ED_ClearEdict (pr, ed, 0); } ed->free = true; ed->freetime = *(pr)->time; diff --git a/qw/source/sv_progs.c b/qw/source/sv_progs.c index b56856945..2939035d9 100644 --- a/qw/source/sv_progs.c +++ b/qw/source/sv_progs.c @@ -54,6 +54,7 @@ progs_t sv_pr_state; cvar_t *r_skyname; cvar_t *sv_progs; cvar_t *pr_checkextentions; +cvar_t *sv_old_entity_free; func_t EndFrame; func_t SpectatorConnect; @@ -63,6 +64,25 @@ func_t UserInfoCallback; static int reserved_edicts = MAX_CLIENTS; +static void +free_edict (progs_t *pr, edict_t *ent) +{ + if (sv_old_entity_free->int_val) { + ent->v[sv_fields.model].entity_var = 0; + ent->v[sv_fields.takedamage].float_var = 0; + ent->v[sv_fields.modelindex].float_var = 0; + ent->v[sv_fields.colormap].float_var = 0; + ent->v[sv_fields.skin].float_var = 0; + ent->v[sv_fields.frame].float_var = 0; + ent->v[sv_fields.nextthink].float_var = -1; + ent->v[sv_fields.solid].float_var = 0; + memset (ent->v[sv_fields.origin].vector_var, 0, 3*sizeof (float)); + memset (ent->v[sv_fields.angles].vector_var, 0, 3*sizeof (float)); + } else { + ED_ClearEdict (pr, ent, 0); + } +} + static int prune_edict (progs_t *pr, edict_t *ent) { @@ -300,6 +320,7 @@ SV_Progs_Init (void) sv_pr_state.numbuiltins = 0; sv_pr_state.parse_field = parse_field; sv_pr_state.prune_edict = prune_edict; + sv_pr_state.free_edict = free_edict; // eww, I hate the need for this :( SV_PR_Cmds_Init (); @@ -324,4 +345,8 @@ SV_Progs_Init_Cvars (void) pr_checkextentions = Cvar_Get ("sv_progs", "1", CVAR_ROM, NULL, "indicate the presence of the " "checkextentions qc function"); + sv_old_entity_free = Cvar_Get ("sv_old_entity_free", "0", CVAR_NONE, NULL, + "set this for buggy mods that rely on the" + " old behaviour of entity freeing (eg," + " *TF)"); }