From ee945625d3c8ddd79a22944e2cc396ac4c1cadec Mon Sep 17 00:00:00 2001 From: Yamagi Date: Tue, 30 Mar 2021 11:11:56 +0200 Subject: [PATCH] Add a cvar `g_commanderbody_nogod` to make the com. body destructable. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commanders body entity is special, because it's spawned in god mode. That's no problem in the baseq2 and addons campaigns. But it may break some custom maps and prevents some hacks, one example is putting the entity inside an killbox. Submitted by Евгений T. --- doc/040_cvarlist.md | 4 ++ src/game/g_main.c | 1 + src/game/g_misc.c | 47 +++++++++++++++++++++++- src/game/header/local.h | 1 + src/game/savegame/savegame.c | 1 + src/game/savegame/tables/gamefunc_decs.h | 1 + src/game/savegame/tables/gamefunc_list.h | 1 + 7 files changed, 55 insertions(+), 1 deletion(-) diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index 8f3b1734..42550afb 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -138,6 +138,10 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` disable it again before playing Ground Zero maps in co-op. By default this cvar is disabled (set to 0). +* **g_commanderbody_nogod**: If set to `1` the tank commanders body + entity can be destroyed. If the to `0` (the default) it is + indestructible. + * **g_footsteps**: If set to `1` (the default) footstep sounds are generated when the player faster than 255. This is the behaviour of Vanilla Quake II. If set to `2` footestep sound always generated. If diff --git a/src/game/g_main.c b/src/game/g_main.c index f6fc9314..666d825d 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -56,6 +56,7 @@ cvar_t *g_select_empty; cvar_t *dedicated; cvar_t *g_footsteps; cvar_t *g_fix_triggered; +cvar_t *g_commanderbody_nogod; cvar_t *filterban; diff --git a/src/game/g_misc.c b/src/game/g_misc.c index 0b2abf29..664c09f3 100644 --- a/src/game/g_misc.c +++ b/src/game/g_misc.c @@ -1610,6 +1610,40 @@ commander_body_drop(edict_t *self) self->s.origin[2] += 2; } +void +commander_body_die(edict_t *self, edict_t *inflictor /* unused */, + edict_t *attacker /* unused */, int damage, vec3_t point /* unused */) +{ + int n; + + if (!self) + { + return; + } + + /* check for gib */ + if (self->health <= self->gib_health) + { + gi.sound(self, CHAN_BODY, gi.soundindex("tank/pain.wav"), 1, ATTN_NORM, 0); + + for (n = 0; n < 1; n++) + { + ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); + } + + for (n = 0; n < 4; n++) + { + ThrowGib(self, "models/objects/gibs/sm_metal/tris.md2", damage, GIB_METALLIC); + } + + ThrowGib(self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC); + ThrowHead(self, "models/objects/gibs/gear/tris.md2", damage, GIB_METALLIC); + self->deadflag = DEAD_DEAD; + + return; + } +} + void SP_monster_commander_body(edict_t *self) { @@ -1626,8 +1660,19 @@ SP_monster_commander_body(edict_t *self) VectorSet(self->maxs, 32, 32, 48); self->use = commander_body_use; self->takedamage = DAMAGE_YES; - self->flags = FL_GODMODE; self->s.renderfx |= RF_FRAMELERP; + + if (g_commanderbody_nogod->value) + { + self->deadflag = DEAD_DEAD; + self->svflags |= SVF_MONSTER | SVF_DEADMONSTER; + self->die = commander_body_die; + } + else + { + self->flags = FL_GODMODE; + } + gi.linkentity(self); gi.soundindex("tank/thud.wav"); diff --git a/src/game/header/local.h b/src/game/header/local.h index a1ff0304..861fae0c 100644 --- a/src/game/header/local.h +++ b/src/game/header/local.h @@ -521,6 +521,7 @@ extern cvar_t *g_select_empty; extern cvar_t *dedicated; extern cvar_t *g_footsteps; extern cvar_t *g_fix_triggered; +extern cvar_t *g_commanderbody_nogod; extern cvar_t *filterban; diff --git a/src/game/savegame/savegame.c b/src/game/savegame/savegame.c index 0c7ef225..8e0fa192 100644 --- a/src/game/savegame/savegame.c +++ b/src/game/savegame/savegame.c @@ -238,6 +238,7 @@ InitGame(void) maxentities = gi.cvar("maxentities", "1024", CVAR_LATCH); g_footsteps = gi.cvar("g_footsteps", "1", CVAR_ARCHIVE); g_fix_triggered = gi.cvar ("g_fix_triggered", "0", 0); + g_commanderbody_nogod = gi.cvar("g_commanderbody_nogod", "0", CVAR_ARCHIVE); /* change anytime vars */ dmflags = gi.cvar("dmflags", "0", CVAR_SERVERINFO); diff --git a/src/game/savegame/tables/gamefunc_decs.h b/src/game/savegame/tables/gamefunc_decs.h index 8cad0879..847a954e 100644 --- a/src/game/savegame/tables/gamefunc_decs.h +++ b/src/game/savegame/tables/gamefunc_decs.h @@ -812,6 +812,7 @@ extern void misc_deadsoldier_die ( edict_t * self , edict_t * inflictor , edict_ extern void SP_misc_banner ( edict_t * ent ) ; extern void misc_banner_think ( edict_t * ent ) ; extern void SP_monster_commander_body ( edict_t * self ) ; +extern void commander_body_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void commander_body_drop ( edict_t * self ) ; extern void commander_body_use ( edict_t * self , edict_t * other , edict_t * activator ) ; extern void commander_body_think ( edict_t * self ) ; diff --git a/src/game/savegame/tables/gamefunc_list.h b/src/game/savegame/tables/gamefunc_list.h index adbc184d..3c1c6f04 100644 --- a/src/game/savegame/tables/gamefunc_list.h +++ b/src/game/savegame/tables/gamefunc_list.h @@ -812,6 +812,7 @@ {"SP_misc_banner", (byte *)SP_misc_banner}, {"misc_banner_think", (byte *)misc_banner_think}, {"SP_monster_commander_body", (byte *)SP_monster_commander_body}, +{"commander_body_die", (byte *)commander_body_die}, {"commander_body_drop", (byte *)commander_body_drop}, {"commander_body_use", (byte *)commander_body_use}, {"commander_body_think", (byte *)commander_body_think},