void Touch_flagonly (gentity_t *ent, gentity_t *other, trace_t *trace) { gentity_t* tmp; if (!other->client) return; if ( ent->spawnflags & RED_FLAG && other->client->ps.powerups[ PW_REDFLAG ] ) { if( ent->spawnflags & 4 ) { other->client->ps.powerups[ PW_REDFLAG ] = 0; other->client->speedScale = 0; } AddScore(other, ent->accuracy); // JPW NERVE set from map, defaults to 20 //G_AddExperience( other, 2.f ); tmp = ent->parent; ent->parent = other; G_Script_ScriptEvent( ent, "death", "" ); G_Script_ScriptEvent( &g_entities[other->client->flagParent], "trigger", "captured" ); Bot_Util_SendTrigger(ent, NULL, va("Allies captured %s", ent->scriptName), ""); ent->parent = tmp; // Removes itself ent->touch = NULL; ent->nextthink = level.time + FRAMETIME; ent->think = G_FreeEntity; } else if ( ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[ PW_BLUEFLAG ] ) { if( ent->spawnflags & 4 ) { other->client->ps.powerups[ PW_BLUEFLAG ] = 0; other->client->speedScale = 0; } AddScore(other, ent->accuracy); // JPW NERVE set from map, defaults to 20 //G_AddExperience( other, 2.f ); tmp = ent->parent; ent->parent = other; G_Script_ScriptEvent( ent, "death", "" ); G_Script_ScriptEvent( &g_entities[other->client->flagParent], "trigger", "captured" ); Bot_Util_SendTrigger(ent, NULL, va("Axis captured %s", ent->scriptName), ""); ent->parent = tmp; // Removes itself ent->touch = NULL; ent->nextthink = level.time + FRAMETIME; ent->think = G_FreeEntity; } }
void Touch_flagonly_multiple(gentity_t * ent, gentity_t * other, trace_t * trace) { gentity_t *tmp; if(!other->client) { return; } if(ent->spawnflags & RED_FLAG && other->client->ps.powerups[PW_REDFLAG]) { other->client->ps.powerups[PW_REDFLAG] = 0; other->client->speedScale = 0; AddScore(other, ent->accuracy); // JPW NERVE set from map, defaults to 20 //G_AddExperience( other, 2.f ); tmp = ent->parent; ent->parent = other; G_Script_ScriptEvent(ent, "death", ""); G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured"); #ifdef OMNIBOT Bot_Util_SendTrigger(ent, NULL, va("Allies captured %s", ent->scriptName), ""); #endif ent->parent = tmp; } else if(ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[PW_BLUEFLAG]) { other->client->ps.powerups[PW_BLUEFLAG] = 0; other->client->speedScale = 0; AddScore(other, ent->accuracy); // JPW NERVE set from map, defaults to 20 //G_AddExperience( other, 2.f ); tmp = ent->parent; ent->parent = other; G_Script_ScriptEvent(ent, "death", ""); G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured"); #ifdef OMNIBOT Bot_Util_SendTrigger(ent, NULL, va("Axis captured %s", ent->scriptName), ""); #endif ent->parent = tmp; } }
/** * @brief Team_ResetFlag * @param[in] ent */ void Team_ResetFlag(gentity_t *ent) { if (!ent) { G_Printf("Warning: NULL passed to Team_ResetFlag\n"); return; } if (ent->flags & FL_DROPPED_ITEM) { Team_ResetFlag(&g_entities[ent->s.otherEntityNum]); G_FreeEntity(ent); } else { ent->s.density++; // do we need to respawn? if (ent->s.density == 1) { RespawnItem(ent); #ifdef FEATURE_OMNIBOT Bot_Util_SendTrigger(ent, NULL, va("Flag returned %s!", _GetEntityName(ent)), "returned"); #endif } } }
/** * @brief Team_TouchOurFlag * @param[in] ent * @param[in] other * @param[in] team * @return */ int Team_TouchOurFlag(gentity_t *ent, gentity_t *other, int team) { gclient_t *cl = other->client; if (ent->flags & FL_DROPPED_ITEM) { // hey, its not home. return it by teleporting it back AddScore(other, WOLF_SECURE_OBJ_BONUS); if (cl->sess.sessionTeam == TEAM_AXIS) { if (level.gameManager) { G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_returned"); } G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned"); #ifdef FEATURE_OMNIBOT { const char *pName = ent->message ? ent->message : _GetEntityName(ent); Bot_Util_SendTrigger(ent, NULL, va("Axis have returned %s!", pName ? pName : ""), "returned"); } #endif } else { if (level.gameManager) { G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_returned"); } G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned"); #ifdef FEATURE_OMNIBOT { const char *pName = ent->message ? ent->message : _GetEntityName(ent); Bot_Util_SendTrigger(ent, NULL, va("Allies have returned %s!", pName ? pName : ""), "returned"); } #endif } //ResetFlag will remove this entity! We must return zero Team_ReturnFlagSound(ent, team); Team_ResetFlag(ent); return 0; } // GT_WOLF doesn't support capturing the flag return 0; }
void G_Script_ScriptEvent( gentity_t *ent, char *eventStr, char *params ) { int i = G_Script_GetEventIndex(ent, eventStr, params); if (i>=0) G_Script_ScriptChange( ent, i ); // omnibot ////////////////////////////////////////////////////////////////////////// // skip these if(!Q_stricmp(eventStr, "trigger") || !Q_stricmp(eventStr, "activate") || !Q_stricmp(eventStr, "spawn") || !Q_stricmp(eventStr, "death") || !Q_stricmp(eventStr, "pain") || !Q_stricmp(eventStr, "playerstart")) return; if(!Q_stricmp(eventStr, "defused")) { Bot_Util_SendTrigger(ent, NULL, va("Defused at %s.", ent->parent ? ent->parent->track : ent->track), eventStr); } else if(!Q_stricmp(eventStr, "dynamited")) { Bot_Util_SendTrigger(ent, NULL, va("Planted at %s.", ent->parent ? ent->parent->track : ent->track), eventStr); } else if(!Q_stricmp(eventStr, "destroyed")) { Bot_Util_SendTrigger(ent, NULL, va("%s Destroyed.", ent->parent ? ent->parent->track : ent->track), eventStr); } else if(!Q_stricmp(eventStr, "exploded")) { Bot_Util_SendTrigger(ent, NULL, va("Explode_%s Exploded.", _GetEntityName(ent) ),eventStr); } // end omnibot }
/*QUAKED target_script_trigger (1 .7 .2) (-8 -8 -8) (8 8 8) must have an aiName must have a target when used it will fire its targets */ void target_script_trigger_use (gentity_t *ent, gentity_t *other, gentity_t *activator ) { // gentity_t *player; if (ent->aiName) { // player = AICast_FindEntityForName("player"); // if (player) // AICast_ScriptEvent( AICast_GetCastState(player->s.number), "trigger", ent->target ); } // DHM - Nerve :: In multiplayer, we use the brush scripting only if ( g_gametype.integer >= GT_WOLF && ent->scriptName ) { #ifdef OMNIBOT Bot_Util_SendTrigger(ent, NULL, ent->scriptName, ent->target ); #endif G_Script_ScriptEvent( ent, "trigger", ent->target ); } G_UseTargets ( ent, other); }
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) { int contents = 0, i, killer = ENTITYNUM_WORLD; const char* killerName = "<world>"; qboolean nogib = qtrue; gitem_t *item = NULL; gentity_t *ent; qboolean killedintank = qfalse; //float timeLived; weapon_t weap; // Jaybird - override/set weapon if( meansOfDeath == MOD_FEAR ) { weap = BG_WeaponForMOD( self->client->lasthurt_mod ); } else if (meansOfDeath == MOD_FALLING && self->client->pmext.wasShoved) { weap = WP_NONE; attacker = &g_entities[self->client->pmext.shover]; meansOfDeath = MOD_SHOVED; } else { // default weap = BG_WeaponForMOD( meansOfDeath ); } if(attacker == self) { if(self->client) { self->client->pers.playerStats.suicides++; trap_PbStat ( self - g_entities , "suicide" , va ( "%d %d %d" , self->client->sess.sessionTeam , self->client->sess.playerType , weap ) ) ; } } else if(OnSameTeam( self, attacker )) { G_LogTeamKill( attacker, weap ); } else { G_LogDeath( self, weap ); G_LogKill( attacker, weap ); if( cvars::gameState.ivalue == GS_PLAYING ) { if( attacker->client ) { attacker->client->combatState = (combatstate_t)( attacker->client->combatState | (1<<COMBATSTATE_KILLEDPLAYER) ); } } } if( !OnSameTeam( self, attacker ) ) { self->isProp = qfalse; // were we teamkilled or not? } else { self->isProp = qtrue; } // if we got killed by a landmine, update our map if( self->client && meansOfDeath == MOD_LANDMINE ) { // if it's an enemy mine, update both teamlists /*int teamNum; mapEntityData_t *mEnt; mapEntityData_Team_t *teamList; teamNum = inflictor->s.teamNum % 4; teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[0] : &mapEntityData[1]; if((mEnt = G_FindMapEntityData(teamList, inflictor-g_entities)) != NULL) { G_FreeMapEntityData( teamList, mEnt ); } if( teamNum != self->client->sess.sessionTeam ) { teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[1] : &mapEntityData[0]; if((mEnt = G_FindMapEntityData(teamList, inflictor-g_entities)) != NULL) { G_FreeMapEntityData( teamList, mEnt ); } }*/ mapEntityData_t *mEnt; if((mEnt = G_FindMapEntityData(&mapEntityData[0], inflictor-g_entities)) != NULL) { G_FreeMapEntityData( &mapEntityData[0], mEnt ); } if((mEnt = G_FindMapEntityData(&mapEntityData[1], inflictor-g_entities)) != NULL) { G_FreeMapEntityData( &mapEntityData[1], mEnt ); } } { mapEntityData_t *mEnt; mapEntityData_Team_t *teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[1] : &mapEntityData[0]; // swapped, cause enemy team mEnt = G_FindMapEntityDataSingleClient( teamList, NULL, self->s.number, -1 ); while( mEnt ) { if( mEnt->type == ME_PLAYER_DISGUISED ) { mapEntityData_t* mEntFree = mEnt; mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, self->s.number, -1 ); G_FreeMapEntityData( teamList, mEntFree ); } else { mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, self->s.number, -1 ); } } } if( self->tankLink ) { G_LeaveTank( self, qfalse ); killedintank = qtrue; } if( self->client->ps.pm_type == PM_DEAD || cvars::gameState.ivalue == GS_INTERMISSION ) { return; } // Player isn't playing dead now, he really is dead! self->client->ps.eFlags &= ~EF_PLAYDEAD; // Jaybird - clear poison effects self->client->ps.eFlags &= ~EF_POISON; G_ResetPoisonEvents(self); // OSP - death stats handled out-of-band of G_Damage for external calls if( meansOfDeath == MOD_FEAR ) { G_addStats( self, attacker, damage, self->client->lasthurt_mod ); // tjw: this would normally be handled in G_Damage() G_AddKillSkillPoints( attacker, (meansOfDeath_t)self->client->lasthurt_mod, HR_HEAD, qfalse ); } else { G_addStats(self, attacker, damage, meansOfDeath); } // OSP self->client->ps.pm_type = PM_DEAD; G_AddEvent( self, EV_STOPSTREAMINGSOUND, 0); if(attacker) { killer = attacker->s.number; killerName = (attacker->client) ? attacker->client->pers.netname : "<non-client>"; } if(attacker == 0 || killer < 0 || killer >= MAX_CLIENTS) { killer = ENTITYNUM_WORLD; killerName = "<world>"; } if(cvars::gameState.ivalue == GS_PLAYING) { char *obit; if(meansOfDeath < 0 || meansOfDeath >= int( sizeof(modNames) / sizeof(modNames[0]) )) { obit = "<bad obituary>"; } else { obit = modNames[meansOfDeath]; } ////////////////////////////////////////////////////////////////////////// // send the events Bot_Event_Death(self-g_entities, &g_entities[attacker-g_entities], obit); Bot_Event_KilledSomeone(attacker-g_entities, &g_entities[self-g_entities], obit); G_LogPrintf("Kill: %i %i %i: %s killed %s by %s\n", killer, self->s.number, meansOfDeath, killerName, self->client->pers.netname, obit ); } ////////////////////////////////////////////////////////////////////////// // broadcast the death event to everyone ent = G_TempEntity( vec3_origin, EV_OBITUARY ); ent->s.eventParm = meansOfDeath; ent->s.otherEntityNum = self->s.number; ent->s.otherEntityNum2 = killer; ent->r.svFlags = SVF_BROADCAST; // send to everyone // Jaybird - They're dead. Adjust their spree info. // G_endKillSpree(self, attacker, meansOfDeath); G_AddLoseSpree( self ); self->enemy = attacker; // Jaybird - shrubbot shortcuts Q_strncpyz(self->client->pers.lastkilled, killerName, sizeof(self->client->pers.lastkilled)); if (attacker && attacker->client) { Q_strncpyz(attacker->client->pers.lastkill, self->client->pers.netname, sizeof(attacker->client->pers.lastkill)); self->client->lastkilledby_client = attacker->s.number; } //self->client->ps.persistant[PERS_KILLED]++; // CHRUKER: b010 - Make sure covert ops lose their disguises if ( self->client->ps.powerups[PW_OPS_DISGUISED] ) self->client->ps.powerups[PW_OPS_DISGUISED] = 0; // JPW NERVE -- if player is holding ticking grenade, drop it if (self->client->ps.grenadeTimeLeft) { switch (self->s.weapon) { case WP_DYNAMITE: case WP_LANDMINE: case WP_LANDMINE_BBETTY: case WP_LANDMINE_PGAS: case WP_MOLOTOV: case WP_SATCHEL: case WP_TRIPMINE: break; default: { vec3_t launchvel, launchspot; gentity_t* m; launchvel[0] = crandom(); launchvel[1] = crandom(); launchvel[2] = random(); VectorScale( launchvel, 160, launchvel ); VectorCopy(self->r.currentOrigin, launchspot); launchspot[2] += 40; // Gordon: fixes premature grenade explosion, ta bani ;) m = fire_grenade(self, launchspot, launchvel, self->s.weapon); m->damage = 0; break; } } } if (attacker && attacker->client) { if ( attacker == self || OnSameTeam (self, attacker ) ) { // DHM - Nerve :: Complaint lodging // Jaybird - shrubbot immunity if( attacker != self && !level.warmupEndTime && cvars::gameState.ivalue == GS_PLAYING && !cmd::entityHasPermission( attacker, priv::base::voteImmunity )) { if( attacker->client->pers.localClient ) { if(attacker->r.svFlags & SVF_BOT) trap_SendServerCommand( self-g_entities, "complaint -5" ); else trap_SendServerCommand( self-g_entities, "complaint -4" ); } else { if( meansOfDeath != MOD_CRUSH_CONSTRUCTION && meansOfDeath != MOD_CRUSH_CONSTRUCTIONDEATH && meansOfDeath != MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER ) { if( g_complaintlimit.integer ) { if( !(meansOfDeath == MOD_LANDMINE && g_disableComplaints.integer & TKFL_MINES ) && !((meansOfDeath == MOD_ARTY || meansOfDeath == MOD_AIRSTRIKE) && g_disableComplaints.integer & TKFL_AIRSTRIKE ) && !(meansOfDeath == MOD_MORTAR && g_disableComplaints.integer & TKFL_MORTAR ) ) { trap_SendServerCommand( self-g_entities, va( "complaint %i", attacker->s.number ) ); self->client->pers.complaintClient = attacker->s.clientNum; self->client->pers.complaintEndTime = level.time + 20500; } } } } } // high penalty to offset medic heal /* AddScore( attacker, WOLF_FRIENDLY_PENALTY ); */ if( g_gametype.integer == GT_WOLF_LMS ) { AddKillScore( attacker, WOLF_FRIENDLY_PENALTY ); } } else { //G_AddExperience( attacker, 1 ); // JPW NERVE -- mostly added as conveneience so we can tweak from the #defines all in one place AddScore(attacker, WOLF_FRAG_BONUS); // Jaybird - Only run these if the player: // a) exists // b) isn't the one who died G_EndLoseSpree(attacker); G_AddKillSpree(attacker); G_FirstBlood(attacker); G_UpdateLastKill(attacker); G_AddMultiKill(attacker); if( g_gametype.integer == GT_WOLF_LMS ) { if( level.firstbloodTeam == -1 ) level.firstbloodTeam = attacker->client->sess.sessionTeam; AddKillScore( attacker, WOLF_FRAG_BONUS ); } attacker->client->lastKillTime = level.time; } } else { AddScore( self, -1 ); if( g_gametype.integer == GT_WOLF_LMS ) AddKillScore( self, -1 ); } // Add team bonuses Team_FragBonuses(self, inflictor, attacker); // drop flag regardless if (self->client->ps.powerups[PW_REDFLAG]) { item = BG_FindItem("Red Flag"); if (!item) item = BG_FindItem("Objective"); self->client->ps.powerups[PW_REDFLAG] = 0; } if (self->client->ps.powerups[PW_BLUEFLAG]) { item = BG_FindItem("Blue Flag"); if (!item) item = BG_FindItem("Objective"); self->client->ps.powerups[PW_BLUEFLAG] = 0; } if (item) { vec3_t launchvel = { 0, 0, 0 }; gentity_t *flag = LaunchItem(item, self->r.currentOrigin, launchvel, self->s.number); flag->s.modelindex2 = self->s.otherEntityNum2;// JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here flag->message = self->message; // DHM - Nerve :: also restore item name Bot_Util_SendTrigger(flag, NULL, va("%s dropped.", flag->message), "dropped"); // Clear out player's temp copies self->s.otherEntityNum2 = 0; self->message = NULL; } // send a fancy "MEDIC!" scream. Sissies, ain' they? if (self->client != NULL) { if( self->health > GIB_HEALTH && meansOfDeath != MOD_SUICIDE && meansOfDeath != MOD_SWITCHTEAM ) { G_AddEvent( self, EV_MEDIC_CALL, 0 ); // ATM: only register the goal if the target isn't in water. if(self->waterlevel <= 1) { Bot_AddFallenTeammateGoals(self, self->client->sess.sessionTeam); } } } Cmd_Score_f( self ); // show scores // send updated scores to any clients that are following this one, // or they would get stale scoreboards for(i=0; i<level.numConnectedClients; i++) { gclient_t *client = &level.clients[level.sortedClients[i]]; if(client->pers.connected != CON_CONNECTED) continue; if(client->sess.sessionTeam != TEAM_SPECTATOR) continue; if(client->sess.spectatorClient == self->s.number) { Cmd_Score_f(g_entities + level.sortedClients[i]); } } self->takedamage = qtrue; // can still be gibbed self->r.contents = CONTENTS_CORPSE; //self->s.angles[2] = 0; self->s.powerups = 0; self->s.loopSound = 0; self->client->limboDropWeapon = self->s.weapon; // store this so it can be dropped in limbo LookAtKiller( self, inflictor, attacker ); self->client->ps.viewangles[0] = 0; self->client->ps.viewangles[2] = 0; //VectorCopy( self->s.angles, self->client->ps.viewangles ); // trap_UnlinkEntity( self ); // ydnar: so bodoes don't clip into world // Jaybird: ClientHiboxMaxZ will take care of effective hitbox self->r.maxs[2] = self->client->ps.crouchMaxZ; self->client->ps.maxs[2] = self->client->ps.crouchMaxZ; trap_LinkEntity( self ); // don't allow respawn until the death anim is done // g_forcerespawn may force spawning at some later time self->client->respawnTime = level.timeCurrent + 800; // remove powerups memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) ); // never gib in a nodrop // FIXME: contents is always 0 here if ( self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) ) { GibEntity( self, killer ); nogib = qfalse; } if(nogib){ // normal death // for the no-blood option, we need to prevent the health // from going to gib level if ( self->health <= GIB_HEALTH ) { self->health = GIB_HEALTH + 1; } // Arnout: re-enable this for flailing /* if( self->client->ps.groundEntityNum == ENTITYNUM_NONE ) { self->client->ps.pm_flags |= PMF_FLAILING; self->client->ps.pm_time = 750; BG_AnimScriptAnimation( &self->client->ps, ANIM_MT_FLAILING, qtrue ); // Face explosion directory { vec3_t angles; vectoangles( self->client->ps.velocity, angles ); self->client->ps.viewangles[YAW] = angles[YAW]; SetClientViewAngle( self, self->client->ps.viewangles ); } } else*/ // DHM - Play death animation, and set pm_time to delay 'fallen' animation //if( G_IsSinglePlayerGame() && self->client->sess.sessionTeam == TEAM_ALLIES ) { // // play "falldown" animation since allies bots won't ever die completely // self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, self->client->pers.character->animModelInfo, ANIM_ET_FALLDOWN, qfalse, qtrue ); // G_StartPlayerAppropriateSound(self, "death"); //} else { self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, self->client->pers.character->animModelInfo, ANIM_ET_DEATH, qfalse, qtrue ); // death animation script already contains sound //} // record the death animation to be used later on by the corpse self->client->torsoDeathAnim = self->client->ps.torsoAnim; self->client->legsDeathAnim = self->client->ps.legsAnim; G_AddEvent( self, EV_DEATH1 + 1, killer ); // the body can still be gibbed self->die = body_die; } if( meansOfDeath == MOD_MACHINEGUN ) { switch( self->client->sess.sessionTeam ) { case TEAM_AXIS: level.axisMG42Counter = level.time; break; case TEAM_ALLIES: level.alliesMG42Counter = level.time; break; default: break; } } G_FadeItems( self, MOD_SATCHEL ); CalculateRanks(); if( killedintank /*Gordon: automatically go to limbo from tank*/ ) { limbo( self, qfalse ); // but no corpse } else if (( meansOfDeath == MOD_SUICIDE || meansOfDeath == MOD_FEAR ) && cvars::gameState.ivalue == GS_PLAYING ) { limbo( self, qtrue ); } else if( g_gametype.integer == GT_WOLF_LMS ) { if( !G_CountTeamMedics( self->client->sess.sessionTeam, qtrue ) ) { limbo( self, qtrue ); } } }
/** * @brief Team_TouchEnemyFlag * @param[in,out] ent * @param[out] other * @param[in] team * @return */ int Team_TouchEnemyFlag(gentity_t *ent, gentity_t *other, int team) { gclient_t *cl = other->client; gentity_t *tmp; ent->s.density--; // hey, its not our flag, pick it up AddScore(other, WOLF_STEAL_OBJ_BONUS); tmp = ent->parent; ent->parent = other; if (cl->sess.sessionTeam == TEAM_AXIS) { gentity_t *pm = G_PopupMessage(PM_OBJECTIVE); pm->s.effect3Time = G_StringIndex(ent->message); pm->s.effect2Time = TEAM_AXIS; pm->s.density = 0; // 0 = stolen if (level.gameManager) { G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_stolen"); } G_Script_ScriptEvent(ent, "trigger", "stolen"); #ifdef FEATURE_OMNIBOT Bot_Util_SendTrigger(ent, NULL, va("Axis have stolen %s!", ent->message), "stolen"); #endif } else { gentity_t *pm = G_PopupMessage(PM_OBJECTIVE); pm->s.effect3Time = G_StringIndex(ent->message); pm->s.effect2Time = TEAM_ALLIES; pm->s.density = 0; // 0 = stolen if (level.gameManager) { G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_stolen"); } G_Script_ScriptEvent(ent, "trigger", "stolen"); #ifdef FEATURE_OMNIBOT Bot_Util_SendTrigger(ent, NULL, va("Allies have stolen %s!", ent->message), "stolen"); #endif } ent->parent = tmp; // reset player disguise on stealing docs other->client->ps.powerups[PW_OPS_DISGUISED] = 0; other->client->disguiseClientNum = -1; if (team == TEAM_AXIS) { cl->ps.powerups[PW_REDFLAG] = INT_MAX; } else { cl->ps.powerups[PW_BLUEFLAG] = INT_MAX; } // flags never expire // store the entitynum of our original flag spawner if (ent->flags & FL_DROPPED_ITEM) { cl->flagParent = ent->s.otherEntityNum; } else { cl->flagParent = ent->s.number; } other->client->speedScale = ent->splashDamage; // Alter player speed if (ent->s.density > 0) { return 1; // We have more flags to give out, spawn back quickly } else { return -1; // Do not respawn this automatically, but do delete it if it was FL_DROPPED } }
/** * @brief If spawn flag is set, use this touch fn instead to turn on/off targeted spawnpoints * @param[in,out] self * @param[in,out] other * @param trace - unused */ void checkpoint_spawntouch(gentity_t *self, gentity_t *other, trace_t *trace) { gentity_t *ent = NULL; qboolean playsound = qtrue; qboolean firsttime = qfalse; #ifdef FEATURE_OMNIBOT char *flagAction = "touch"; #endif if (self->count == other->client->sess.sessionTeam) { return; } if (self->s.frame == WCP_ANIM_NOFLAG) { AddScore(other, WOLF_SP_CAPTURE); } else { AddScore(other, WOLF_SP_RECOVER); } if (self->count < 0) { firsttime = qtrue; } // Set controlling team self->count = other->client->sess.sessionTeam; // Set animation if (self->count == TEAM_AXIS) { if (self->s.frame == WCP_ANIM_NOFLAG && !(self->spawnflags & ALLIED_ONLY)) { self->s.frame = WCP_ANIM_RAISE_AXIS; #ifdef FEATURE_OMNIBOT flagAction = "capture"; #endif } else if (self->s.frame == WCP_ANIM_NOFLAG) { self->s.frame = WCP_ANIM_NOFLAG; playsound = qfalse; } else if (self->s.frame == WCP_ANIM_AMERICAN_RAISED && !(self->spawnflags & ALLIED_ONLY)) { self->s.frame = WCP_ANIM_AMERICAN_TO_AXIS; #ifdef FEATURE_OMNIBOT flagAction = "reclaims"; #endif } else if (self->s.frame == WCP_ANIM_AMERICAN_RAISED) { self->s.frame = WCP_ANIM_AMERICAN_FALLING; #ifdef FEATURE_OMNIBOT flagAction = "neutralized"; #endif } else { self->s.frame = WCP_ANIM_AXIS_RAISED; } } else { if (self->s.frame == WCP_ANIM_NOFLAG && !(self->spawnflags & AXIS_ONLY)) { self->s.frame = WCP_ANIM_RAISE_AMERICAN; #ifdef FEATURE_OMNIBOT flagAction = "capture"; #endif } else if (self->s.frame == WCP_ANIM_NOFLAG) { self->s.frame = WCP_ANIM_NOFLAG; playsound = qfalse; } else if (self->s.frame == WCP_ANIM_AXIS_RAISED && !(self->spawnflags & AXIS_ONLY)) { self->s.frame = WCP_ANIM_AXIS_TO_AMERICAN; #ifdef FEATURE_OMNIBOT flagAction = "reclaims"; #endif } else if (self->s.frame == WCP_ANIM_AXIS_RAISED) { self->s.frame = WCP_ANIM_AXIS_FALLING; #ifdef FEATURE_OMNIBOT flagAction = "neutralized"; #endif } else { self->s.frame = WCP_ANIM_AMERICAN_RAISED; } } // If this is the first time it's being touched, and it was the opposing team // touching a single-team reinforcement flag... don't do anything. if (firsttime && !playsound) { return; } // Play a sound if (playsound) { G_AddEvent(self, EV_GENERAL_SOUND, self->soundPos1); } self->parent = other; // reset player disguise on touching flag other->client->ps.powerups[PW_OPS_DISGUISED] = 0; other->client->disguiseClientNum = -1; // Run script trigger if (self->count == TEAM_AXIS) { G_Script_ScriptEvent(self, "trigger", "axis_capture"); #ifdef FEATURE_OMNIBOT Bot_Util_SendTrigger(self, NULL, va("axis_%s_%s", flagAction, _GetEntityName(self)), flagAction); #endif } else { G_Script_ScriptEvent(self, "trigger", "allied_capture"); #ifdef FEATURE_OMNIBOT Bot_Util_SendTrigger(self, NULL, va("allies_%s_%s", flagAction, _GetEntityName(self)), flagAction); #endif } // Don't allow touch again until animation is finished self->touch = NULL; self->think = checkpoint_think; self->nextthink = level.time + 1000; // activate all targets // updated this to allow toggling of initial spawnpoints as well, plus now it only // toggles spawnflags 2 for spawnpoint entities if (self->target) { while (1) { ent = G_FindByTargetname(ent, self->target); if (!ent) { break; } if (other->client->sess.sessionTeam == TEAM_AXIS) { if (!strcmp(ent->classname, "team_CTF_redspawn")) { ent->spawnflags |= 2; } else if (!strcmp(ent->classname, "team_CTF_bluespawn")) { ent->spawnflags &= ~2; } } else { if (!strcmp(ent->classname, "team_CTF_bluespawn")) { ent->spawnflags |= 2; } else if (!strcmp(ent->classname, "team_CTF_redspawn")) { ent->spawnflags &= ~2; } } } } }