/* =============== CheckGauntletAttack =============== */ qboolean CheckGauntletAttack( gentity_t *ent ) { trace_t tr; vec3_t end; gentity_t *tent; gentity_t *traceEnt; int damage; // set aiming directions AngleVectors (ent->client->ps.viewangles, forward, right, up); CalcMuzzlePoint ( ent, forward, right, up, muzzle ); VectorMA (muzzle, 32, forward, end); trap_Trace (&tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT); if ( tr.surfaceFlags & SURF_NOIMPACT ) { return qfalse; } traceEnt = &g_entities[ tr.entityNum ]; // send blood impact if ( traceEnt->takedamage && traceEnt->client ) { tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); tent->s.otherEntityNum = traceEnt->s.number; tent->s.eventParm = DirToByte( tr.plane.normal ); tent->s.weapon = ent->s.weapon; } if ( !traceEnt->takedamage) { return qfalse; } if (ent->client->ps.powerups[PW_QUAD] ) { G_AddEvent( ent, EV_POWERUP_QUAD, 0 ); s_quadFactor = g_quadfactor.value; } else { s_quadFactor = 1; } damage = 50 * s_quadFactor; G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_GAUNTLET ); return qtrue; }
//----------------------------- void G_PlayEffect( int fxID, vec3_t origin, vec3_t fwd ) { gentity_t *tent; vec3_t temp; tent = G_TempEntity( origin, EV_PLAY_EFFECT ); tent->s.eventParm = fxID; VectorSet( tent->maxs, FX_ENT_RADIUS, FX_ENT_RADIUS, FX_ENT_RADIUS ); VectorScale( tent->maxs, -1, tent->mins ); VectorCopy( fwd, tent->pos3 ); // Assume angles, we'll do a cross product on the other end to finish up MakeNormalVectors( fwd, tent->pos4, temp ); gi.linkentity( tent ); }
void Team_CaptureFlagSound( gentity_t *ent, int team ) { gentity_t *te; if (ent == NULL) { G_Printf ("Warning: NULL passed to Team_CaptureFlagSound\n"); return; } te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND ); if( team == TEAM_BLUE ) { te->s.eventParm = GTS_BLUE_CAPTURE; } else { te->s.eventParm = GTS_RED_CAPTURE; } te->r.svFlags |= SVF_BROADCAST; }
/* =========== ClientDisconnect Called when a player drops from the server. Will not be called between levels. This should NOT be called directly by any game logic, call trap_DropClient(), which will call this and do server system housekeeping. ============ */ void ClientDisconnect( int clientNum ) { gentity_t *ent; gentity_t *tent; int i; ent = g_entities + clientNum; if ( !ent->client || ent->client->pers.connected == CON_DISCONNECTED ) { return; } G_LeaveTeam( ent ); G_namelog_disconnect( ent->client ); G_Vote( ent, TEAM_NONE, qfalse ); // stop any following clients for ( i = 0; i < level.maxclients; i++ ) { // remove any /ignore settings for this clientNum Com_ClientListRemove( &level.clients[ i ].sess.ignoreList, clientNum ); } // send effect if they were completely connected if ( ent->client->pers.connected == CON_CONNECTED && ent->client->sess.spectatorState == SPECTATOR_NOT ) { tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_OUT ); tent->s.clientNum = ent->s.clientNum; } G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s^7\"\n", clientNum, ent->client->pers.ip.str, ent->client->pers.guid, ent->client->pers.netname ); trap_UnlinkEntity( ent ); ent->inuse = qfalse; ent->classname = "disconnected"; ent->client->pers.connected = CON_DISCONNECTED; ent->client->sess.spectatorState = ent->client->ps.persistant[ PERS_SPECSTATE ] = SPECTATOR_NOT; trap_SetConfigstring( CS_PLAYERS + clientNum, "" ); CalculateRanks(); }
void teslaFire( gentity_t *ent ) { trace_t tr; vec3_t end; gentity_t *traceEnt, *tent; VectorMA( muzzle, TESLAGEN_RANGE, forward, end ); trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); if( tr.entityNum == ENTITYNUM_NONE ) return; traceEnt = &g_entities[ tr.entityNum ]; if( !traceEnt->client ) return; if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS && !traceEnt->client->pers.bleeder ) return; //so the client side knows ent->s.eFlags |= EF_FIRING; if( traceEnt->takedamage ) { G_Damage( traceEnt, ent, ent, forward, tr.endpos, TESLAGEN_DMG, 0, MOD_TESLAGEN ); } // snap the endpos to integers to save net bandwidth, but nudged towards the line SnapVectorTowards( tr.endpos, muzzle ); // send railgun beam effect tent = G_TempEntity( tr.endpos, EV_TESLATRAIL ); VectorCopy( muzzle, tent->s.origin2 ); tent->s.generic1 = ent->s.number; //src tent->s.clientNum = traceEnt->s.number; //dest // move origin a bit to come closer to the drawn gun muzzle VectorMA( tent->s.origin2, 28, up, tent->s.origin2 ); }
void teslaFire( gentity_t *self ) { trace_t tr; vec3_t origin, target; gentity_t *tent; if ( !self->enemy ) { return; } // Move the muzzle from the entity origin up a bit to fire over turrets VectorMA( muzzle, self->r.maxs[ 2 ], self->s.origin2, origin ); // Don't aim for the center, aim at the top of the bounding box VectorCopy( self->enemy->s.origin, target ); target[ 2 ] += self->enemy->r.maxs[ 2 ]; // Trace to the target entity trap_Trace( &tr, origin, NULL, NULL, target, self->s.number, MASK_SHOT ); if ( tr.entityNum != self->enemy->s.number ) { return; } // Client side firing effect self->s.eFlags |= EF_FIRING; // Deal damage if ( self->enemy->takedamage ) { vec3_t dir; VectorSubtract( target, origin, dir ); G_Damage( self->enemy, self, self, dir, tr.endpos, TESLAGEN_DMG, 0, MOD_TESLAGEN ); } // Send tesla zap trail tent = G_TempEntity( tr.endpos, EV_TESLATRAIL ); tent->s.generic1 = self->s.number; // src tent->s.clientNum = self->enemy->s.number; // dest }
/* =============== RespawnItem =============== */ void RespawnItem( gentity_t *ent ) { if(!ent) return; // randomly select from teamed entities if (ent->team) { gentity_t *master; int count; int choice; if ( !ent->teammaster ) { G_Error( "RespawnItem: bad teammaster"); } master = ent->teammaster; for (count = 0, ent = master; ent; ent = ent->teamchain, count++) ; choice = rand() % count; for (count = 0, ent = master; count < choice && ent; ent = ent->teamchain, count++) ; } if(!ent) return; ent->r.contents = CONTENTS_TRIGGER; ent->s.eFlags &= ~(EF_NODRAW | EF_ITEMPLACEHOLDER); ent->r.svFlags &= ~SVF_NOCLIENT; trap_LinkEntity (ent); if ( ent->item->giType == IT_POWERUP ) { // play powerup spawn sound to all clients gentity_t *te; te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_SOUND ); te->s.eventParm = G_SoundIndex( "sound/items/poweruprespawn.wav" );//cgs.media.poweruprespawn te->r.svFlags |= SVF_BROADCAST; } // play the normal respawn sound only to nearby clients G_AddEvent( ent, EV_ITEM_RESPAWN, 0 ); ent->nextthink = 0; }
void massDriverFire( gentity_t *ent ) { trace_t tr; vec3_t end; gentity_t *tent; gentity_t *traceEnt; G_CombatStats_Fire( ent, CSW_MDRIVER, MDRIVER_DMG ); VectorMA( muzzle, 8192.0f * 16.0f, forward, end ); G_UnlaggedOn( ent, muzzle, 8192.0f * 16.0f ); trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); G_UnlaggedOff( ); if( tr.surfaceFlags & SURF_NOIMPACT ) return; traceEnt = &g_entities[ tr.entityNum ]; // snap the endpos to integers, but nudged towards the line SnapVectorTowards( tr.endpos, muzzle ); // send impact if( traceEnt->takedamage && (traceEnt->s.eType == ET_BUILDABLE || traceEnt->s.eType == ET_PLAYER ) ) { BloodSpurt( ent, traceEnt, &tr ); } else { tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS ); tent->s.eventParm = DirToByte( tr.plane.normal ); tent->s.weapon = ent->s.weapon; tent->s.generic1 = ent->s.generic1; //weaponMode } if( traceEnt->takedamage ) { G_Damage( traceEnt, ent, ent, forward, tr.endpos, MDRIVER_DMG, 0, MOD_MDRIVER ); } }
/* ================ ProximityMine_ExplodeOnPlayer ================ */ static void ProximityMine_ExplodeOnPlayer( gentity_t *mine ) { gentity_t *player; player = mine->enemy; player->client->ps.eFlags &= ~EF_TICKING; if ( player->client->invulnerabilityTime > level.time ) { G_Damage( player, mine->parent, mine->parent, vec3_origin, mine->s.origin, 1000, DAMAGE_NO_KNOCKBACK, MOD_JUICED ); player->client->invulnerabilityTime = 0; G_TempEntity( player->client->ps.origin, EV_JUICED ); } else { G_SetOrigin( mine, player->s.pos.trBase ); // make sure the explosion gets to the client mine->r.svFlags &= ~SVF_NOCLIENT; mine->splashMethodOfDeath = MOD_PROXIMITY_MINE; G_ExplodeMissile( mine ); } }
// Play an effect at a position on an entity. // Mostly for G_MissileBounceEffect so we can play an effect on the bouncee. //----------------------------- void G_PlayEffect( int fxID, int clientNum, vec3_t origin, vec3_t fwd ) { gentity_t *tent; vec3_t temp; tent = G_TempEntity( origin, EV_PLAY_EFFECT ); tent->s.eventParm = fxID; if ( clientNum != -1 ) { tent->s.saberActive = 1; tent->s.otherEntityNum = clientNum; } VectorSet( tent->maxs, FX_ENT_RADIUS, FX_ENT_RADIUS, FX_ENT_RADIUS ); VectorScale( tent->maxs, -1, tent->mins ); VectorCopy( fwd, tent->s.angles ); // Assume angles, we'll do a cross product on the other end to finish up MakeNormalVectors( fwd, tent->s.angles2, temp ); }
bool Gametype_inf::onItemTouch(gitem_t *item, gclient_s *other){ if (other->sess.team == TEAM_BLUE){ trap_SetConfigstring(CS_GAMETYPE_MESSAGE, va("%i,%s", level.time + 5000, va("@%s ^7has taken the briefcase!", other->pers.netname.c_str()))); // Taken. trap_SendServerCommand(-1, va("print\"^3[INF] %s ^7has taken the briefcase.\n\"", other->pers.netname.c_str())); // Boe!Man 11/29/12: Global sound. if (!level.intermissionQueued && !level.intermissiontime){ gentity_t* tent; tent = G_TempEntity(vec3_origin, EV_GLOBAL_SOUND); tent->s.eventParm = caseTakenSound; tent->r.svFlags = SVF_BROADCAST; } // Boe!Man 11/29/12: Radio message. G_Voice(&g_entities[other->ps.clientNum], NULL, SAY_TEAM, "got_it", qfalse); return true; } else return false; }
void gas_think( gentity_t *ent ) { gentity_t *tent; ent->count++; if ( ent->health < ent->count ) { ent->think = G_FreeEntity; if ( ent->s.density == 5 ) { ent->nextthink = level.time + FRAMETIME; } else { ent->nextthink = level.time + 3000; } return; } ent->r.maxs[0] = ent->r.maxs[1] = ent->r.maxs[2]++; ent->r.mins[0] = ent->r.mins[1] = ent->r.mins[2]--; ent->nextthink = level.time + FRAMETIME; tent = G_TempEntity( ent->r.currentOrigin, EV_SMOKE ); VectorCopy( ent->r.currentOrigin, tent->s.origin ); if ( ent->s.density == 5 ) { tent->s.time = 500; tent->s.time2 = 100; tent->s.density = 5; tent->s.angles2[0] = 8; tent->s.angles2[1] = 32; } else { tent->s.time = 5000; tent->s.time2 = 3000; tent->s.density = 5; tent->s.angles2[0] = 24; tent->s.angles2[1] = 96; } trap_LinkEntity( ent ); }
/* ============== fire_mortar dir is a non-normalized direction/power vector ============== */ gentity_t *fire_mortar( gentity_t *self, vec3_t start, vec3_t dir ) { gentity_t *bolt; // VectorNormalize (dir); if ( self->spawnflags ) { gentity_t *tent; tent = G_TempEntity( self->s.pos.trBase, EV_MORTAREFX ); tent->s.density = self->spawnflags; // send smoke and muzzle flash flags VectorCopy( self->s.pos.trBase, tent->s.origin ); VectorCopy( self->s.apos.trBase, tent->s.angles ); } bolt = G_Spawn(); bolt->classname = const_cast<char*>("mortar"); bolt->nextthink = level.time + 20000; // push it out a little bolt->think = G_ExplodeMissile; bolt->s.eType = ET_MISSILE; bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN | SVF_BROADCAST; // broadcast sound. not multiplayer friendly, but for mortars it should be okay // bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; bolt->s.weapon = WP_MORTAR; bolt->r.ownerNum = self->s.number; bolt->parent = self; bolt->damage = G_GetWeaponDamage( WP_MORTAR ); // JPW NERVE bolt->splashDamage = G_GetWeaponDamage( WP_MORTAR ); // JPW NERVE bolt->splashRadius = 120; bolt->methodOfDeath = MOD_MORTAR; bolt->splashMethodOfDeath = MOD_MORTAR_SPLASH; bolt->clipmask = MASK_MISSILESHOT; bolt->s.pos.trType = TR_GRAVITY; bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame VectorCopy( start, bolt->s.pos.trBase ); // VectorScale( dir, 900, bolt->s.pos.trDelta ); VectorCopy( dir, bolt->s.pos.trDelta ); SnapVector( bolt->s.pos.trDelta ); // save net bandwidth VectorCopy( start, bolt->r.currentOrigin ); return bolt; }
void weapon_supershotgun_fire (gentity_t *ent) { gentity_t *tent; // send shotgun blast tent = G_TempEntity( muzzle, EV_SHOTGUN ); VectorScale( forward, 4096, tent->s.origin2 ); SnapVector( tent->s.origin2 ); tent->s.eventParm = rand() & 255; // seed for spread pattern //unlagged - attack prediction #2 if ( g_unlagged.integer ) { // this has to be something the client can predict now tent->s.eventParm = ent->client->attackTime % 256; // seed for spread pattern } else { tent->s.eventParm = rand() & 255; // seed for spread pattern } //unlagged - attack prediction #2 tent->s.otherEntityNum = ent->s.number; ShotgunPattern( tent->s.pos.trBase, tent->s.origin2, tent->s.eventParm, ent ); }
/* =============== BloodSpurt Generates a blood spurt event for traces with accurate end points =============== */ static void BloodSpurt( gentity_t *attacker, gentity_t *victim, trace_t *tr ) { gentity_t *tent; if ( !attacker->client ) { return; } if ( victim->health <= 0 ) { return; } tent = G_TempEntity( tr->endpos, EV_MISSILE_HIT ); tent->s.otherEntityNum = victim->s.number; tent->s.eventParm = DirToByte( tr->plane.normal ); tent->s.weapon = attacker->s.weapon; tent->s.generic1 = attacker->s.generic1; // weaponMode }
void smoke_think(gentity_t *ent) { gentity_t *tent; ent->nextthink = level.time + ent->delay; if(!(ent->spawnflags & 4)) { return; } if(ent->health) { ent->health--; if(!ent->health) { ent->think = G_FreeEntity; ent->nextthink = level.time + FRAMETIME; } } tent = G_TempEntity(ent->r.currentOrigin, EV_SMOKE); VectorCopy(ent->r.currentOrigin, tent->s.origin); tent->s.time = ent->speed; tent->s.time2 = ent->duration; tent->s.density = ent->s.density; // this is used to set the size of the smoke particle tent->s.angles2[0] = ent->start_size; tent->s.angles2[1] = ent->end_size; tent->s.angles2[2] = ent->wait; VectorCopy(ent->pos3, tent->s.origin2); if(ent->s.frame) // denotes reverse gravity effect { tent->s.frame = 1; } }
/* * CheckObeliskAttack */ qbool CheckObeliskAttack(Gentity *obelisk, Gentity *attacker) { Gentity *te; /* if this really is an obelisk */ if(obelisk->die != ObeliskDie) return qfalse; /* if the attacker is a client */ if(!attacker->client) return qfalse; /* if the obelisk is on the same team as the attacker then don't hurt it */ if(obelisk->spawnflags == attacker->client->sess.team) return qtrue; /* obelisk may be hurt */ /* if not played any sounds recently */ if((obelisk->spawnflags == TEAM_RED && teamgame.redObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME) || (obelisk->spawnflags == TEAM_BLUE && teamgame.blueObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME)){ /* tell which obelisk is under attack */ te = G_TempEntity(obelisk->s.pos.base, EV_GLOBAL_TEAM_SOUND); if(obelisk->spawnflags == TEAM_RED){ te->s.eventParm = GTS_REDOBELISK_ATTACKED; teamgame.redObeliskAttackedTime = level.time; }else{ te->s.eventParm = GTS_BLUEOBELISK_ATTACKED; teamgame.blueObeliskAttackedTime = level.time; } te->r.svFlags |= SVF_BROADCAST; } return qfalse; }
void NS_SetPrimary( gentity_t *ent, int primary ) { gentity_t *temp; temp = G_TempEntity( ent->client->ps.origin, EV_STOLENWEAPON ); temp->s.weapon = primary; temp->s.otherEntityNum = ent->client->ps.clientNum; // copy old primary modifications to the new one [only for some weapon - some can't handle weaponmods] if ( BG_WeaponMods( primary ) & ( 1 << WM_SILENCER ) ) { ent->client->pers.nsInven.weapon_mods[primary].silencer = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].silencer; } if ( BG_WeaponMods( primary ) & ( 1 << WM_LASER ) ) { ent->client->pers.nsInven.weapon_mods[primary].lasersight = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].lasersight; } if ( BG_WeaponMods( primary ) & ( 1 << WM_SCOPE ) ) { ent->client->pers.nsInven.weapon_mods[primary].scope = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].scope; } if ( BG_WeaponMods( primary ) & ( 1 << WM_BAYONET ) ) { ent->client->pers.nsInven.weapon_mods[primary].bayonet = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].bayonet; } if ( BG_WeaponMods( primary ) & ( 1 << WM_GRENADELAUNCHER ) ) { ent->client->pers.nsInven.weapon_mods[primary].gl = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].gl; } if ( BG_WeaponMods( primary ) & ( 1 << WM_DUCKBILL ) ) { ent->client->pers.nsInven.weapon_mods[primary].duckbill = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].duckbill; } if ( BG_WeaponMods( primary ) & ( 1 << WM_FLASHLIGHT ) ) { ent->client->pers.nsInven.weapon_mods[primary].flashlight = ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].flashlight; } // delete old mods ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].silencer = 0; ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].lasersight = 0; ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].scope = 0; ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].bayonet = 0; ent->client->pers.nsInven.weapon_mods[ent->client->pers.nsInven.primaryweapon].gl = 0; // now set the new primary weapon ent->client->pers.nsInven.primaryweapon = primary; }
//------------------------------------------------------------------------- void G_MissileBounceEffect( gentity_t *ent, vec3_t org, vec3_t dir ) { //FIXME: have an EV_BOUNCE_MISSILE event that checks the s.weapon and does the appropriate effect switch( ent->s.weapon ) { case WP_BOWCASTER: G_PlayEffect( "bowcaster/deflect", ent->currentOrigin, dir ); break; case WP_BLASTER: case WP_BRYAR_PISTOL: G_PlayEffect( "blaster/deflect", ent->currentOrigin, dir ); break; default: { gentity_t *tent = G_TempEntity( org, EV_GRENADE_BOUNCE ); VectorCopy( dir, tent->pos1 ); tent->s.weapon = ent->s.weapon; } break; } }
void Blocked_Tramcar( gentity_t *ent, gentity_t *other ) { // remove anything other than a client if ( !other->client ) { // except CTF flags!!!! if ( other->s.eType == ET_ITEM && other->item->giType == IT_TEAM ) { Team_DroppedFlagThink( other ); return; } G_TempEntity( other->s.origin, EV_ITEM_POP ); G_FreeEntity( other ); return; } if ( other->flags & FL_GODMODE ) { other->flags &= ~FL_GODMODE; other->client->ps.stats[STAT_HEALTH] = other->health = 0; } G_Damage( other, ent, ent, NULL, NULL, 99999, 0, MOD_CRUSH ); }
/* =============== meleeAttack =============== */ void meleeAttack( gentity_t *ent, float range, float width, int damage, meansOfDeath_t mod ) { trace_t tr; vec3_t end; gentity_t *tent; gentity_t *traceEnt; vec3_t mins, maxs; VectorSet( mins, -width, -width, -width ); VectorSet( maxs, width, width, width ); // set aiming directions AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); VectorMA( muzzle, range, forward, end ); G_UnlaggedOn( ent, muzzle, range ); trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); G_UnlaggedOff( ); if( tr.surfaceFlags & SURF_NOIMPACT ) return; traceEnt = &g_entities[ tr.entityNum ]; // send blood impact if( traceEnt->takedamage && traceEnt->client ) { tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); tent->s.otherEntityNum = traceEnt->s.number; tent->s.eventParm = DirToByte( tr.plane.normal ); tent->s.weapon = ent->s.weapon; tent->s.generic1 = ent->s.generic1; //weaponMode } if( traceEnt->takedamage ) G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod ); }
/* * AddTeamScore * * used for gametype > GT_TEAM * for gametype GT_TEAM the level.teamScores is updated in AddScore in g_combat.c */ void AddTeamScore(Vec3 origin, int team, int score) { Gentity *te; te = G_TempEntity(origin, EV_GLOBAL_TEAM_SOUND); te->r.svFlags |= SVF_BROADCAST; if(team == TEAM_RED){ if(level.teamScores[ TEAM_RED ] + score == level.teamScores[ TEAM_BLUE ]) /* teams are tied sound */ te->s.eventParm = GTS_TEAMS_ARE_TIED; else if(level.teamScores[ TEAM_RED ] <= level.teamScores[ TEAM_BLUE ] && level.teamScores[ TEAM_RED ] + score > level.teamScores[ TEAM_BLUE ]) /* red took the lead sound */ te->s.eventParm = GTS_REDTEAM_TOOK_LEAD; else /* red scored sound */ te->s.eventParm = GTS_REDTEAM_SCORED; }else{ if(level.teamScores[ TEAM_BLUE ] + score == level.teamScores[ TEAM_RED ]) /* teams are tied sound */ te->s.eventParm = GTS_TEAMS_ARE_TIED; else if(level.teamScores[ TEAM_BLUE ] <= level.teamScores[ TEAM_RED ] && level.teamScores[ TEAM_BLUE ] + score > level.teamScores[ TEAM_RED ]) /* blue took the lead sound */ te->s.eventParm = GTS_BLUETEAM_TOOK_LEAD; else /* blue scored sound */ te->s.eventParm = GTS_BLUETEAM_SCORED; } level.teamScores[ team ] += score; }
/* ======================================================================================================================================= Team_TakeFlagSound ======================================================================================================================================= */ void Team_TakeFlagSound(gentity_t *ent, int team) { gentity_t *te; if (ent == NULL) { G_Printf("Warning: NULL passed to Team_TakeFlagSound\n"); return; } // only play sound when the flag was at the base or not picked up the last 10 seconds switch (team) { case TEAM_RED: if (teamgame.blueStatus != FLAG_ATBASE) { if (teamgame.blueTakenTime > level.time - 10000) { return; } } teamgame.blueTakenTime = level.time; break; case TEAM_BLUE: // CTF if (teamgame.redStatus != FLAG_ATBASE) { if (teamgame.redTakenTime > level.time - 10000) { return; } } teamgame.redTakenTime = level.time; break; } te = G_TempEntity(ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND); if (team == TEAM_BLUE) { te->s.eventParm = GTS_RED_TAKEN; } else { te->s.eventParm = GTS_BLUE_TAKEN; } te->r.svFlags |= SVF_BROADCAST; }
void script_mover_blocked(gentity_t *ent, gentity_t *other) { // remove it, we must not stop for anything or it will screw up script timing if (!other->client && other->s.eType != ET_CORPSE) { // /me slaps nerve // except CTF flags!!!! if (other->s.eType == ET_ITEM && other->item->giType == IT_TEAM) { Team_DroppedFlagThink(other); return; } G_TempEntity(other->s.origin, EV_ITEM_POP); G_FreeEntity(other); return; } // FIXME: we could have certain entities stop us, thereby "pausing" movement // until they move out the way. then we can just call the GotoMarker() again, // telling it that we are just now calling it for the first time, so it should // start us on our way again (theoretically speaking). // kill them G_Damage(other, ent, ent, NULL, NULL, 9999, 0, MOD_CRUSH); }
void G_MissileBounceEffect( gentity_t *ent, vector3 *org, vector3 *dir ) { //FIXME: have an EV_BOUNCE_MISSILE event that checks the s.weapon and does the appropriate effect switch ( ent->s.weapon ) { case WP_BOWCASTER: G_PlayEffectID( G_EffectIndex( "bowcaster/deflect" ), &ent->r.currentOrigin, dir ); break; case WP_BLASTER: case WP_BRYAR_PISTOL: G_PlayEffectID( G_EffectIndex( "blaster/deflect" ), &ent->r.currentOrigin, dir ); break; default: { gentity_t *te = G_TempEntity( org, EV_SABER_BLOCK ); VectorCopy( org, &te->s.origin ); VectorCopy( dir, &te->s.angles ); te->s.eventParm = 0; te->s.weapon = 0;//saberNum te->s.legsAnim = 0;//bladeNum } break; } }
/* ================ G_InvulnerabilityEffect ================ */ int G_InvulnerabilityEffect(gentity_t * targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir) { gentity_t *impact; vec3_t intersections[2], vec; int n; if(!targ->client) { return qfalse; } VectorCopy(dir, vec); VectorInverse(vec); // sphere model radius = 42 units n = RaySphereIntersections(targ->client->ps.origin, 42, point, vec, intersections); if(n > 0) { impact = G_TempEntity(targ->client->ps.origin, EV_INVUL_IMPACT); VectorSubtract(intersections[0], targ->client->ps.origin, vec); VectorToAngles(vec, impact->s.angles); impact->s.angles[0] += 90; if(impact->s.angles[0] > 360) impact->s.angles[0] -= 360; if(impactpoint) { VectorCopy(intersections[0], impactpoint); } if(bouncedir) { VectorCopy(vec, bouncedir); VectorNormalize(bouncedir); } return qtrue; } else { return qfalse; } }
/* ================ Blocked_Door ================ */ void Blocked_Door( gentity_t *ent, gentity_t *other ) { // remove anything other than a client if ( !other->client ) { // except CTF flags!!!! if( other->s.eType == ET_ITEM && other->item->giType == IT_TEAM ) { Team_DroppedFlagThink( other ); return; } G_TempEntity( other->s.origin, EV_ITEM_POP ); G_FreeEntity( other ); return; } if ( ent->damage ) { G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH ); } if ( ent->spawnflags & 4 ) { return; // crushers don't reverse } // reverse direction Use_BinaryMover( ent, ent, other ); }
/* ============== M_think ============== */ void M_think( gentity_t *ent ) { gentity_t *tent; ent->count++; // if (ent->count == 1) // Concussive_fx (ent); //----(SA) moved to G_ExplodeMissile() if ( ent->count == ent->health ) { ent->think = G_FreeEntity; } tent = G_TempEntity( ent->s.origin, EV_SMOKE ); VectorCopy( ent->s.origin, tent->s.origin ); if ( ent->s.density == 1 ) { tent->s.origin[2] += 16; } else { // tent->s.origin[2]+=32; // Note to self Maxx said to lower the spawn loc for the smoke 16 units tent->s.origin[2] += 16; } tent->s.time = 3000; tent->s.time2 = 100; tent->s.density = 0; if ( ent->s.density == 1 ) { tent->s.angles2[0] = 16; } else { // Note to self Maxx changed this to 24 tent->s.angles2[0] = 24; } tent->s.angles2[1] = 96; tent->s.angles2[2] = 50; ent->nextthink = level.time + FRAMETIME; }
void G_MissileBounceEffect( gentity_t *ent, vec3_t org, vec3_t dir ) #endif // _IMMERSION { //FIXME: have an EV_BOUNCE_MISSILE event that checks the s.weapon and does the appropriate effect switch( ent->s.weapon ) { case WP_BOWCASTER: #ifdef _IMMERSION G_PlayEffect( "bowcaster/deflect", hitEntNum, ent->currentOrigin, dir ); #else G_PlayEffect( "bowcaster/deflect", ent->currentOrigin, dir ); #endif // _IMMERSION break; case WP_BLASTER: case WP_BRYAR_PISTOL: #ifdef _IMMERSION G_PlayEffect( "blaster/deflect", hitEntNum, ent->currentOrigin, dir ); #else G_PlayEffect( "blaster/deflect", ent->currentOrigin, dir ); #endif // _IMMERSION break; default: { gentity_t *tent = G_TempEntity( org, EV_GRENADE_BOUNCE ); VectorCopy( dir, tent->pos1 ); tent->s.weapon = ent->s.weapon; #ifdef _IMMERSION if ( hitEntNum != -1 ) { tent->s.saberActive = 1; tent->s.otherEntityNum = hitEntNum; } #endif // _IMMERSION } break; } }
/* ======================================================================================================================================= CheckObeliskAttack ======================================================================================================================================= */ qboolean CheckObeliskAttack(gentity_t *obelisk, gentity_t *attacker) { gentity_t *te; // if this really is an obelisk if (obelisk->die != ObeliskDie) { return qfalse; } // if the attacker is a client if (!attacker->client) { return qfalse; } // if the obelisk is on the same team as the attacker then don't hurt it if (!g_friendlyFire.integer && obelisk->spawnflags == attacker->client->sess.sessionTeam) { return qtrue; } // obelisk may be hurt // if not played any sounds recently if (obelisk->spawnflags != attacker->client->sess.sessionTeam) { if ((obelisk->spawnflags == TEAM_RED && teamgame.redObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME) || (obelisk->spawnflags == TEAM_BLUE && teamgame.blueObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME)) { // tell which obelisk is under attack te = G_TempEntity(obelisk->s.pos.trBase, EV_GLOBAL_TEAM_SOUND); if (obelisk->spawnflags == TEAM_RED) { te->s.eventParm = GTS_REDOBELISK_ATTACKED; teamgame.redObeliskAttackedTime = level.time; } else { te->s.eventParm = GTS_BLUEOBELISK_ATTACKED; teamgame.blueObeliskAttackedTime = level.time; } te->r.svFlags |= SVF_BROADCAST; } } return qfalse; }