void body_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */, int damage, vec3_t point /* unused */) { int n; if (!self) { return; } if (self->health < -40) { gi.sound(self, CHAN_BODY, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0); for (n = 0; n < 4; n++) { ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); } self->s.origin[2] -= 48; ThrowClientHead(self, damage); self->takedamage = DAMAGE_NO; } }
/* * body_die */ static void body_die( edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t point ) { if( self->health >= GIB_HEALTH ) return; ThrowSmallPileOfGibs( self, damage ); self->s.origin[2] -= 48; ThrowClientHead( self, damage ); self->nextThink = level.time + 3000 + random() * 3000; }
/* ================== player_die ================== */ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { int n; // if we're in a camera, get out if (self->client->zCameraTrack) { stopCamera(self); } VectorClear (self->avelocity); self->takedamage = DAMAGE_YES; self->movetype = MOVETYPE_TOSS; self->s.modelindex2 = 0; // remove linked weapon model self->s.angles[0] = 0; self->s.angles[2] = 0; self->s.sound = 0; self->client->weapon_sound = 0; self->maxs[2] = -8; // self->solid = SOLID_NOT; self->svflags |= SVF_DEADMONSTER; if (!self->deadflag) { self->client->respawn_time = level.time + 1.0; LookAtKiller (self, inflictor, attacker); self->client->ps.pmove.pm_type = PM_DEAD; ClientObituary (self, inflictor, attacker); TossClientWeapon (self); if (deathmatch->value) Cmd_Help_f (self); // show scores } // remove powerups self->client->quad_framenum = 0; self->client->invincible_framenum = 0; self->client->breather_framenum = 0; self->client->enviro_framenum = 0; self->client->a2kFramenum = 0; // clear inventory memset(self->client->pers.inventory, 0, sizeof(self->client->pers.inventory)); if (self->health < -40) { // gib gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); for (n= 0; n < 4; n++) ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ThrowClientHead (self, damage); self->takedamage = DAMAGE_NO; } else { // normal death if (!self->deadflag) { static int i; i = (i+1)%3; // start a death animation self->client->anim_priority = ANIM_DEATH; if (self->client->ps.pmove.pm_flags & PMF_DUCKED) { self->s.frame = FRAME_crdeath1-1; self->client->anim_end = FRAME_crdeath5; } else switch (i) { case 0: self->s.frame = FRAME_death101-1; self->client->anim_end = FRAME_death106; break; case 1: self->s.frame = FRAME_death201-1; self->client->anim_end = FRAME_death206; break; case 2: self->s.frame = FRAME_death301-1; self->client->anim_end = FRAME_death308; break; } gi.sound (self, CHAN_VOICE, gi.soundindex(va("*death%i.wav", (rand()%4)+1)), 1, ATTN_NORM, 0); } } self->deadflag = DEAD_DEAD; gi.linkentity (self); }
/* * CopyToBodyQue */ static edict_t *CopyToBodyQue( edict_t *ent, edict_t *attacker, int damage ) { edict_t *body; int contents; if( GS_RaceGametype() ) return NULL; contents = G_PointContents( ent->s.origin ); if( contents & CONTENTS_NODROP ) return NULL; G_Client_UnlinkBodies( ent ); // grab a body que and cycle to the next one body = &game.edicts[gs.maxclients + level.body_que + 1]; level.body_que = ( level.body_que + 1 ) % BODY_QUEUE_SIZE; // send an effect on the removed body if( body->s.modelindex && body->s.type == ET_CORPSE ) ThrowSmallPileOfGibs( body, 10 ); GClip_UnlinkEntity( body ); memset( body, 0, sizeof( edict_t ) ); //clean up garbage //init body edict G_InitEdict( body ); body->classname = "body"; body->health = ent->health; body->mass = ent->mass; body->r.owner = ent->r.owner; body->s.type = ent->s.type; body->s.team = ent->s.team; body->s.effects = 0; body->r.svflags = SVF_CORPSE; body->r.svflags &= ~SVF_NOCLIENT; body->activator = ent; if( g_deadbody_followkiller->integer ) body->enemy = attacker; //use flat yaw body->s.angles[PITCH] = 0; body->s.angles[ROLL] = 0; body->s.angles[YAW] = ent->s.angles[YAW]; body->s.modelindex2 = 0; // <- is bodyOwner when in ET_CORPSE, but not in ET_GENERIC or ET_PLAYER body->s.weapon = 0; //copy player position and box size VectorCopy( ent->s.old_origin, body->s.old_origin ); VectorCopy( ent->s.origin, body->s.origin ); VectorCopy( ent->s.origin, body->olds.origin ); VectorCopy( ent->r.mins, body->r.mins ); VectorCopy( ent->r.maxs, body->r.maxs ); VectorCopy( ent->r.absmin, body->r.absmin ); VectorCopy( ent->r.absmax, body->r.absmax ); VectorCopy( ent->r.size, body->r.size ); VectorCopy( ent->velocity, body->velocity ); body->r.maxs[2] = body->r.mins[2] + 8; body->r.solid = SOLID_YES; body->takedamage = DAMAGE_YES; body->r.clipmask = CONTENTS_SOLID | CONTENTS_PLAYERCLIP; body->movetype = MOVETYPE_TOSS; body->die = body_die; body->think = body_think; // body self destruction countdown if( ent->health < GIB_HEALTH || meansOfDeath == MOD_ELECTROBOLT_S /* electrobolt always gibs */ ) { ThrowSmallPileOfGibs( body, damage ); // reset gib impulse VectorClear( body->velocity ); ThrowClientHead( body, damage ); // sets ET_GIB body->s.frame = 0; body->nextThink = level.time + 3000 + random() * 3000; body->deadflag = DEAD_DEAD; } else if( ent->s.type == ET_PLAYER ) { // copy the model body->s.type = ET_CORPSE; body->s.modelindex = ent->s.modelindex; body->s.bodyOwner = ent->s.number; // bodyOwner is the same as modelindex2 body->s.skinnum = ent->s.skinnum; body->s.teleported = true; // launch the death animation on the body { static int i; i = ( i+1 )%3; G_AddEvent( body, EV_DIE, i, true ); switch( i ) { default: case 0: body->s.frame = ( ( BOTH_DEAD1&0x3F )|( BOTH_DEAD1&0x3F )<<6|( 0 &0xF )<<12 ); break; case 1: body->s.frame = ( ( BOTH_DEAD2&0x3F )|( BOTH_DEAD2&0x3F )<<6|( 0 &0xF )<<12 ); break; case 2: body->s.frame = ( ( BOTH_DEAD3&0x3F )|( BOTH_DEAD3&0x3F )<<6|( 0 &0xF )<<12 ); break; } } body->think = body_ready; body->takedamage = DAMAGE_NO; body->r.solid = SOLID_NOT; body->nextThink = level.time + 500; // make damageable in 0.5 seconds } else // wasn't a player, just copy it's model { VectorClear( body->velocity ); body->s.modelindex = ent->s.modelindex; body->s.frame = ent->s.frame; body->nextThink = level.time + 5000 + random()*10000; } GClip_LinkEntity( body ); return body; }
/* ================== player_die ================== */ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { int n; // debut mod : scanner ClearScanner(self->client); // fin mod : scanner VectorClear (self->avelocity); self->takedamage = DAMAGE_YES; self->movetype = MOVETYPE_TOSS; self->s.modelindex2 = 0; // remove linked weapon model self->s.angles[0] = 0; self->s.angles[2] = 0; self->s.sound = 0; self->client->weapon_sound = 0; self->maxs[2] = -8; // self->solid = SOLID_NOT; self->svflags |= SVF_DEADMONSTER; if (!self->deadflag) { self->client->respawn_time = level.time + 1.0; LookAtKiller (self, inflictor, attacker); self->client->ps.pmove.pm_type = PM_DEAD; ClientObituary (self, inflictor, attacker); TossClientWeapon (self); if (deathmatch->value) Cmd_Help_f (self); // show scores // clear inventory // this is kind of ugly, but it's how we want to handle keys in coop for (n = 0; n < game.num_items; n++) { if (coop->value && itemlist[n].flags & IT_KEY) self->client->resp.coop_respawn.inventory[n] = self->client->pers.inventory[n]; self->client->pers.inventory[n] = 0; } } // remove powerups self->client->quad_framenum = 0; self->client->invincible_framenum = 0; self->client->breather_framenum = 0; self->client->enviro_framenum = 0; self->flags &= ~FL_POWER_ARMOR; if (self->health < -40) { // gib gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); for (n= 0; n < 4; n++) ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ThrowClientHead (self, damage); self->takedamage = DAMAGE_NO; } else { // normal death if (!self->deadflag) { static int i; i = (i+1)%3; // start a death animation self->client->anim_priority = ANIM_DEATH; if (self->client->ps.pmove.pm_flags & PMF_DUCKED) { self->s.frame = FRAME_crdeath1-1; self->client->anim_end = FRAME_crdeath5; } else switch (i) { case 0: self->s.frame = FRAME_death101-1; self->client->anim_end = FRAME_death106; break; case 1: self->s.frame = FRAME_death201-1; self->client->anim_end = FRAME_death206; break; case 2: self->s.frame = FRAME_death301-1; self->client->anim_end = FRAME_death308; break; } gi.sound (self, CHAN_VOICE, gi.soundindex(va("*death%i.wav", (rand()%4)+1)), 1, ATTN_NORM, 0); } } self->deadflag = DEAD_DEAD; gi.linkentity (self); }