diff --git a/src/g_combat.c b/src/g_combat.c index 9444df4..b86d074 100644 --- a/src/g_combat.c +++ b/src/g_combat.c @@ -82,9 +82,6 @@ void Killed (edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, v return; } - if (targ->health < -999) - targ->health = -999; - targ->enemy = attacker; if ((targ->svflags & SVF_MONSTER) && (targ->deadflag != DEAD_DEAD)) diff --git a/src/g_spawn.c b/src/g_spawn.c index 6f9f4ac..9581391 100644 --- a/src/g_spawn.c +++ b/src/g_spawn.c @@ -117,6 +117,7 @@ void SP_monster_mutant (edict_t *self); void SP_monster_supertank (edict_t *self); void SP_monster_boss2 (edict_t *self); void SP_monster_jorg (edict_t *self); +void SP_monster_makron (edict_t *self); void SP_monster_boss3_stand (edict_t *self); void SP_monster_commander_body (edict_t *self); @@ -259,6 +260,7 @@ spawn_t spawns[] = { {"monster_supertank", SP_monster_supertank}, {"monster_boss2", SP_monster_boss2}, {"monster_boss3_stand", SP_monster_boss3_stand}, + {"monster_makron", SP_monster_makron}, {"monster_jorg", SP_monster_jorg}, {"monster_commander_body", SP_monster_commander_body}, diff --git a/src/monster/boss3/boss32.c b/src/monster/boss3/boss32.c index c87df6b..084aa2f 100644 --- a/src/monster/boss3/boss32.c +++ b/src/monster/boss3/boss32.c @@ -696,7 +696,6 @@ void makron_attack(edict_t *self) Makron Torso. This needs to be spawned in --- */ - void makron_torso_think (edict_t *self) { if (!self) @@ -704,34 +703,97 @@ void makron_torso_think (edict_t *self) return; } - if (++self->s.frame < 365) - self->nextthink = level.time + FRAMETIME; - else + /* detach from the makron if the legs are gone completely */ + if (self->owner && (!self->owner->inuse || (self->owner->health <= self->owner->gib_health))) { - self->s.frame = 346; - self->nextthink = level.time + FRAMETIME; + self->owner = NULL; } + + /* if the makron is revived the torso was put back on him */ + if (self->owner && self->owner->deadflag != DEAD_DEAD) + { + G_FreeEdict(self); + return; + } + + if (++self->s.frame >= FRAME_death320) + { + self->s.frame = FRAME_death301; + } + + self->nextthink = level.time + FRAMETIME; } -void makron_torso (edict_t *ent) +static void makron_torso_origin (edict_t *self, edict_t *torso) { - if (!ent) + vec3_t v; + trace_t tr; + + AngleVectors(self->s.angles, v, NULL, NULL); + VectorMA(self->s.origin, -84.0f, v, v); + + tr = gi.trace(self->s.origin, torso->mins, torso->maxs, v, self, MASK_SOLID); + + VectorCopy (tr.endpos, torso->s.origin); +} + +void makron_torso_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + + if (self->health > self->gib_health) { return; } - ent->movetype = MOVETYPE_NONE; - ent->solid = SOLID_NOT; - VectorSet (ent->mins, -8, -8, 0); - VectorSet (ent->maxs, 8, 8, 8); - ent->s.frame = 346; - ent->s.modelindex = gi.modelindex ("models/monsters/boss3/rider/tris.md2"); - ent->think = makron_torso_think; - ent->nextthink = level.time + 2 * FRAMETIME; - ent->s.sound = gi.soundindex ("makron/spine.wav"); - gi.linkentity (ent); + gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0); + + 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); + } + + G_FreeEdict(self); } +void makron_torso (edict_t *self) +{ + edict_t *torso; + + if (!self) + { + return; + } + + torso = G_Spawn(); + + VectorCopy(self->s.angles, torso->s.angles); + VectorSet(torso->mins, -24, -24, 0); + VectorSet(torso->maxs, 24, 24, 16); + makron_torso_origin(self, torso); + + torso->gib_health = -800; + torso->takedamage = DAMAGE_YES; + torso->die = makron_torso_die; + torso->deadflag = DEAD_DEAD; + + torso->owner = self; + torso->movetype = MOVETYPE_TOSS; + torso->solid = SOLID_BBOX; + torso->svflags = SVF_MONSTER|SVF_DEADMONSTER; + torso->clipmask = MASK_MONSTERSOLID; + torso->s.frame = FRAME_death301; + torso->s.modelindex = gi.modelindex("models/monsters/boss3/rider/tris.md2"); + torso->think = makron_torso_think; + torso->nextthink = level.time + 2 * FRAMETIME; + torso->s.sound = gi.soundindex("makron/spine.wav"); + + gi.linkentity(torso); +} // // death @@ -744,8 +806,8 @@ void makron_dead (edict_t *self) return; } - VectorSet (self->mins, -60, -60, 0); - VectorSet (self->maxs, 60, 60, 72); + VectorSet (self->mins, -48, -48, 0); + VectorSet (self->maxs, 48, 48, 24); self->movetype = MOVETYPE_TOSS; self->svflags |= SVF_DEADMONSTER; self->nextthink = 0; @@ -755,8 +817,6 @@ void makron_dead (edict_t *self) void makron_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { - edict_t *tempent; - int n; if (!self) @@ -786,14 +846,13 @@ void makron_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag self->deadflag = DEAD_DEAD; self->takedamage = DAMAGE_YES; - tempent = G_Spawn(); - VectorCopy (self->s.origin, tempent->s.origin); - VectorCopy (self->s.angles, tempent->s.angles); - tempent->s.origin[1] -= 84; - makron_torso (tempent); + makron_torso (self); + + /* lower bbox since the torso is gone */ + self->maxs[2] = 64; + gi.linkentity (self); self->monsterinfo.currentmove = &makron_move_death2; - } qboolean Makron_CheckAttack (edict_t *self) @@ -1011,6 +1070,7 @@ void MakronToss (edict_t *self) } ent = G_Spawn (); + ent->classname = "monster_makron"; ent->nextthink = level.time + 0.8; ent->think = MakronSpawn; ent->target = self->target; diff --git a/src/player/hud.c b/src/player/hud.c index 8c9b6c6..17f7c01 100644 --- a/src/player/hud.c +++ b/src/player/hud.c @@ -408,7 +408,7 @@ void G_SetStats (edict_t *ent) // health // ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health; - ent->client->ps.stats[STAT_HEALTH] = ent->health; + ent->client->ps.stats[STAT_HEALTH] = (ent->health < -99) ? -99 : ent->health; // // ammo diff --git a/src/savegame/tables/gamefunc_decs.h b/src/savegame/tables/gamefunc_decs.h index a70e2f7..2b5009a 100644 --- a/src/savegame/tables/gamefunc_decs.h +++ b/src/savegame/tables/gamefunc_decs.h @@ -747,6 +747,7 @@ extern void SP_monster_makron ( edict_t * self ) ; extern void MakronPrecache ( void ) ; extern qboolean Makron_CheckAttack ( edict_t * self ) ; extern void makron_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void makron_torso_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void makron_dead ( edict_t * self ) ; extern void makron_torso ( edict_t * ent ) ; extern void makron_torso_think ( edict_t * self ) ; diff --git a/src/savegame/tables/gamefunc_list.h b/src/savegame/tables/gamefunc_list.h index 7e8805c..2a88ffa 100644 --- a/src/savegame/tables/gamefunc_list.h +++ b/src/savegame/tables/gamefunc_list.h @@ -747,6 +747,7 @@ {"MakronPrecache", (byte *)MakronPrecache}, {"Makron_CheckAttack", (byte *)Makron_CheckAttack}, {"makron_die", (byte *)makron_die}, +{"makron_torso_die", (byte *)makron_torso_die}, {"makron_dead", (byte *)makron_dead}, {"makron_torso", (byte *)makron_torso}, {"makron_torso_think", (byte *)makron_torso_think},