Quake Style - Quake 3 Tutorials Freeze Tag - Freeze Tag Part 1 Starting off the freeze tag tuts.. |
self->r.maxs[2] = -8; // don't allow respawn until the death anim is done // g_forcerespawn may force spawning at some later time /*freeze self->client->respawnTime = level.time + 1700; freeze*/ // remove powerups memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) ); //freeze player_freeze( self, attacker, meansOfDeath ); self->client->respawnTime = level.time + 1700; //freeze // never gib in a nodrop if ( self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) && g_blood.integer ) { // gib death GibEntity( self, killer ); } else { // normal death static int i;
void player_freeze( gentity_t *targ, gentity_t *attacker, int mod ) { // Don't freeze anyone if we're not in team play or during warmup time if ( g_gametype.integer < GT_TEAM || level.warmupTime ) { return; } // If they just (3 sec) respawned then don't freeze them // Note we check their respawnTime so earlier I made sure this didn't get reset until after player_freeze was called if ( level.time - targ->client->respawnTime < 3000 ) { return; } // Don't freeze someone for certain cases switch ( mod ) { case MOD_WATER: case MOD_CRUSH: case MOD_TELEFRAG: case MOD_FALLING: case MOD_SUICIDE: case MOD_TARGET_LASER: case MOD_TRIGGER_HURT: case MOD_GRAPPLE: return; } // Did a teammate kill us or did we kill ourselves? if ( OnSameTeam( targ, attacker ) && targ != attacker ) { return; } targ->client->ps.powerups[ PW_BALL ] = INT_MAX; targ->client->noclip = qtrue; targ->health = 0; G_AddEvent( targ, EV_DEATH1, 0 ); targ->client->ps.pm_time = 4000; }
qboolean IsFrozen( gentity_t *ent ) { // For clients and bots if ( ent->client && ent->client->ps.powerups[ PW_BALL ] ) { return qtrue; // For my fake bodies } else if ( ent->s.powerups & ( 1 << PW_BALL ) ) { return qtrue; } return qfalse; }
case EV_DEATH1: //freeze if ( es->number == cg.snap->ps.clientNum ) { cg.powerupTime = cg.time; } break; //freeze case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, va("*death%i.wav", event - EV_DEATH1 + 1) ) ); break;
if ( cg.showScores || cg.predictedPlayerState.pm_type == PM_DEAD || //freeze ( cg.predictedPlayerState.pm_type == PM_NOCLIP && cg.powerupTime + 4000 > cg.time ) || //freeze cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { fade = 1.0; fadeColor = colorWhite; } else {
self->client->ps.torsoAnim = ( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; //freeze if ( IsFrozen( self ) ) { CopyToBody( self ); } else { //freeze G_AddEvent( self, EV_DEATH1 + 1, killer ); //freeze } //freeze // the body can still be gibbed self->die = body_die;
void CopyToBody( gentity_t *ent ) { gentity_t *body; // Create a game entity (our lovely frozen body) body = G_Spawn(); if ( !body ) { return; } body->classname = "body"; // This is basically a copy of g_client.c CopyToBodyQue (normal body created when dead player respawns) body->s = ent->s; body->s.eFlags = EF_DEAD; // This body's frozen body->s.powerups = ( 1 << PW_BALL ); body->s.loopSound = 0; body->s.number = body - g_entities; body->timestamp = level.time; body->physicsObject = qtrue; body->physicsBounce = 0; // This is special // This means we can shoot and bounce this body around G_SetOrigin( body, ent->r.currentOrigin ); body->s.pos.trType = TR_GRAVITY; body->s.pos.trTime = level.time; // Make sure to copy dead player's velocity to our body so it goes flying VectorCopy( ent->client->ps.velocity, body->s.pos.trDelta ); body->s.event = 0; switch ( body->s.legsAnim & ~ANIM_TOGGLEBIT ) { case BOTH_DEATH1: case BOTH_DEAD1: body->s.torsoAnim = body->s.legsAnim = BOTH_DEAD1; break; case BOTH_DEATH2: case BOTH_DEAD2: body->s.torsoAnim = body->s.legsAnim = BOTH_DEAD2; break; case BOTH_DEATH3: case BOTH_DEAD3: default: body->s.torsoAnim = body->s.legsAnim = BOTH_DEAD3; break; } body->r.svFlags = ent->r.svFlags; // I am making the body have the default player's bounding box // This isn't right though // Could put body outside map so I need to fix this for later version VectorSet ( body->r.mins, -15, -15, -24 ); VectorSet ( body->r.maxs, 15, 15, 32 ); VectorCopy( ent->r.absmin, body->r.absmin ); VectorCopy( ent->r.absmax, body->r.absmax ); body->clipmask = CONTENTS_SOLID | CONTENTS_PLAYERCLIP; // Make the body something solid body->r.contents = CONTENTS_BODY; body->r.ownerNum = ent->s.number; body->nextthink = level.time + FRAMETIME; body->think = BodyThink; body->die = Body_die; body->takedamage = qtrue; trap_LinkEntity( body ); body->noise_index = G_SoundIndex( "sound/player/tankjr/jump1.wav" ); // I use splashDamage to remember what team this body is on body->splashDamage = level.clients[ ent->s.clientNum ].sess.sessionTeam; // This will be used for when you look at the body and see a player's name body->s.otherEntityNum = ent->s.number; ent->health = GIB_HEALTH; // Don't let bullets and rockets hit us ent->r.contents = 0; // So they don't move after free to move around (push from explosion they died from) VectorClear( ent->client->ps.velocity ); }
if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR ) { s->eType = ET_INVISIBLE; } else if ( ps->stats[STAT_HEALTH] <= GIB_HEALTH ) { s->eType = ET_INVISIBLE; } else { s->eType = ET_PLAYER; }