void misc_beam_start(gentity_t *self) { gentity_t *ent; self->s.eType = ET_BEAM_2; if (self->target) { ent = G_FindByTargetname(NULL, self->target); if (!ent) { G_Printf("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); G_FreeEntity(self); return; } self->target_ent = ent; } else { G_Printf("%s at %s: with no target\n", self->classname, vtos(self->s.origin)); G_FreeEntity(self); return; } if (self->message) { ent = G_FindByTargetname(NULL, self->message); if (!ent) { G_Printf("%s at %s: %s is a bad target2\n", self->classname, vtos(self->s.origin), self->message); G_FreeEntity(self); return; // No targets by this name. } self->enemy = ent; } else { // the misc_beam is it's own ending point self->enemy = self; } self->accuracy = 0; self->think = misc_beam_think; self->nextthink = level.time + FRAMETIME; }
gentity_t *G_PickTarget( char *targetname ) { gentity_t *ent = NULL; int num_choices = 0; gentity_t *choice[MAXCHOICES]; if ( !targetname ) { //G_Printf("G_PickTarget called with NULL targetname\n"); return NULL; } while ( 1 ) { ent = G_FindByTargetname( ent, targetname ); if ( !ent ) { break; } choice[num_choices++] = ent; if ( num_choices == MAXCHOICES ) { break; } } if ( !num_choices ) { G_Printf( "G_PickTarget: target %s not found\n", targetname ); return NULL; } return choice[rand() % num_choices]; }
void script_mover_spawn(gentity_t *ent) { if (ent->spawnflags & 128) { gentity_t *tent = G_FindByTargetname(NULL, ent->tagBuffer); if (!tent) { ent->nextTrain = ent; } else { ent->nextTrain = tent; } ent->s.effect3Time = ent->nextTrain - g_entities; } if (ent->spawnflags & 2) { ent->clipmask = CONTENTS_SOLID; ent->r.contents = CONTENTS_SOLID; } else { ent->s.eFlags |= EF_NONSOLID_BMODEL; ent->clipmask = 0; ent->r.contents = 0; } script_linkentity(ent); // now start thinking process which controls AAS interaction ent->think = script_mover_aas_blocking; ent->nextthink = level.time + 200; }
void G_KillEnts(const char *target, gentity_t *ignore, gentity_t *killer) { gentity_t *targ = NULL; while ((targ = G_FindByTargetname(targ, target)) != NULL) { // make sure it isn't going to respawn or show any events targ->nextthink = 0; if (targ == ignore) { continue; } // RF, script_movers should die! if (targ->s.eType == ET_MOVER && !Q_stricmp(targ->classname, "script_mover") && targ->die) { G_Damage(targ, killer, killer, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); continue; } if (targ->s.eType == ET_CONSTRUCTIBLE) { targ->die(targ, killer, killer, targ->health, 0); continue; } trap_UnlinkEntity(targ); targ->nextthink = level.time + FRAMETIME; targ->use = NULL; targ->touch = NULL; targ->think = G_FreeEntity; } }
/*QUAKED target_give (1 0 0) (-8 -8 -8) (8 8 8) Gives the activator all the items pointed to. */ void Use_Target_Give(gentity_t *ent, gentity_t *other, gentity_t *activator) { gentity_t *t; trace_t trace; // Nico, silent GCC (void)other; if (!activator->client) { return; } if (!ent->target) { return; } memset(&trace, 0, sizeof (trace)); t = NULL; while ((t = G_FindByTargetname(t, ent->target)) != NULL) { if (!t->item) { continue; } Touch_Item(t, activator, &trace); // make sure it isn't going to respawn or show any events t->nextthink = 0; trap_UnlinkEntity(t); } }
void target_laser_start(gentity_t *self) { gentity_t *ent; self->s.eType = ET_BEAM; if (self->target) { ent = G_FindByTargetname(NULL, self->target); if (!ent) { G_Printf("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); } self->enemy = ent; } else { G_SetMovedir(self->s.angles, self->movedir); } self->use = target_laser_use; self->think = target_laser_think; if (!self->damage) { self->damage = 1; } if (self->spawnflags & 1) { target_laser_on(self); } else { target_laser_off(self); } }
gentity_t *G_PickTarget(char *targetname) { gentity_t *ent = NULL; int num_choices = 0; gentity_t *choice[MAXCHOICES]; if (!targetname) { //G_Printf("G_PickTarget called with NULL targetname\n"); return NULL; } while (1) { ent = G_FindByTargetname(ent, targetname); if (!ent) { break; } choice[num_choices++] = ent; if (num_choices == MAXCHOICES) { break; } } if (!num_choices) { G_Printf(S_COLOR_YELLOW "WARNING G_PickTarget: target %s not found or isn't in use - this might be a bug (returning NULL)\n", targetname); return NULL; } return choice[rand() % num_choices]; }
/*QUAKED trigger_multiple (.5 .5 .5) ? AXIS_ONLY ALLIED_ONLY NOBOT BOTONLY SOLDIERONLY LTONLY MEDICONLY ENGINEERONLY COVERTOPSONLY "wait" : Seconds between triggerings, 0.5 default, -1 = one time only. "random" wait variance, default is 0 Variable sized repeatable trigger. Must be targeted at one or more entities. so, the basic time between firing is a random time between (wait - random) and (wait + random) */ void SP_trigger_multiple(gentity_t *ent) { gentity_t *target = NULL; G_SpawnFloat("wait", "0.5", &ent->wait); ent->touch = Touch_Multi; ent->use = Use_Multi; ent->s.eType = ET_TRIGGER_MULTIPLE; InitTrigger(ent); // Nico, override wait -1 or wait 9999 on trigger_multiple where target is start timer // Note, this test is in case the start/stop timer or checkpoint entity was defined before the trigger multiple if (g_forceTimerReset.integer) { target = G_FindByTargetname(NULL, ent->target); if (target && ent->wait != 0.5 && (!Q_stricmp(target->classname, "target_startTimer") || !Q_stricmp(target->classname, "target_stopTimer") || !Q_stricmp(target->classname, "target_checkpoint"))) { G_DPrintf("%s: SP_trigger_multiple linked to %s, wait found = %f, overrided to 0.5\n", GAME_VERSION, target->classname, ent->wait); ent->wait = 0.5; } } #ifdef VISIBLE_TRIGGERS ent->r.svFlags &= ~SVF_NOCLIENT; #endif trap_LinkEntity(ent); }
/* ============== alarmbox_updateparts ============== */ void alarmbox_updateparts(gentity_t *ent, qboolean matestoo) { gentity_t *t, *mate; qboolean alarming = (ent->s.frame == 1); // update teammates if (matestoo) { for (mate = ent->teammaster; mate; mate = mate->teamchain) { if (mate == ent) { continue; } if (!(mate->active)) { // don't update dead alarm boxes, they stay dead continue; } if (!(ent->active)) { // destroyed, so just turn teammates off mate->s.frame = 0; } else { mate->s.frame = ent->s.frame; } alarmbox_updateparts(mate, qfalse); } } // update lights if (!ent->target) { return; } t = NULL; while ((t = G_FindByTargetname(t, ent->target)) != NULL) { if (t == ent) { G_DPrintf("WARNING: Entity used itself.\n"); } else { // give the dlight the sound if (!Q_stricmp(t->classname, "dlight")) { t->soundLoop = ent->soundLoop; if (alarming) { if (!(t->r.linked)) { G_UseEntity(t, ent, 0); } } else { if (t->r.linked) { G_UseEntity(t, ent, 0); } } } // alarmbox can tell script_trigger about activation // (but don't trigger if dying, only activation) else if (!Q_stricmp(t->classname, "target_script_trigger") && ent->active) { // not dead G_UseEntity(t, ent, 0); } } } }
void bot_landminespot_setup( gentity_t* self ) { gentity_t* target = G_FindByTargetname( NULL, self->target ); if(!target) { G_FreeEntity( self ); return; } VectorCopy( target->s.origin, self->s.origin2 ); }
void trigger_ammo_setup(gentity_t* self) { self->target_ent = G_FindByTargetname( NULL, self->target ); if(!self->target_ent) { G_Error( "trigger_ammo failed to find target: %s\n", self->target ); } if(TRIGGER_AMMO_CANTHINK(self)) { self->think = trigger_ammo_think; self->nextthink = level.time + FRAMETIME; } }
void target_speaker_multiple(gentity_t *ent) { gentity_t *vis_dummy = NULL; if (!(ent->target)) { G_Error("target_speaker missing target at pos %s", vtos(ent->s.origin)); } vis_dummy = G_FindByTargetname(NULL, ent->target); if (vis_dummy) { ent->s.otherEntityNum = vis_dummy->s.number; } else { G_Error("target_speaker cant find vis_dummy_multiple %s", vtos(ent->s.origin)); } }
void trigger_aidoor_stayopen(gentity_t * ent, gentity_t * other, trace_t * trace) { gentity_t *door; // only use this in single player. It was taken out of multiplayer, and I'm guessing there was a good reason. if(g_gametype.integer != GT_SINGLE_PLAYER && g_gametype.integer != GT_COOP) { return; } // FIXME: port this code over to moving doors (use MOVER_POSx instead of MOVER_POSxROTATE) if(other->client && other->health > 0) { if(!ent->target || !(strlen(ent->target))) { // ent->target of "" will crash game in Q_stricmp() // FIXME: commented out so it can be fixed // G_Printf( "trigger_aidoor at loc %s does not have a target door\n", vtos (ent->s.origin) ); return; } door = G_FindByTargetname(NULL, ent->target); if(!door) { // FIXME: commented out so it can be fixed // G_Printf( "trigger_aidoor at loc %s does not have a target door\n", vtos (ent->s.origin) ); return; } if((door->moverState == MOVER_POS2ROTATE) || (door->moverState == MOVER_POS2)) { // door is in open state waiting to close keep it open door->nextthink = level.time + door->wait + 3000; } // what about other move states? // for now, don't worry about getting the bots out of the way. this is just for single player, and the bots should have // orders to follow anyway } }
/** * @brief Kills the activator. (default) * @details QUAKED target_kill (.5 .5 .5) (-8 -8 -8) (8 8 8) kill_user_too * If targets, they will be killed when this is fired * "kill_user_too" will still kill the activator when this ent has targets (default is only kill targets, not activator) * * @param[in] target * @param[in] ignore * @param[in] killer * @param[in] mod */ void G_KillEnts(const char *target, gentity_t *ignore, gentity_t *killer, meansOfDeath_t mod) { gentity_t *targ = NULL; while ((targ = G_FindByTargetname(targ, target))) { // make sure it isn't going to respawn or show any events targ->nextthink = 0; if (targ == ignore) { continue; } // script_movers should die! if (targ->s.eType == ET_MOVER && !Q_stricmp(targ->classname, "script_mover") && targ->die) { G_Damage(targ, killer, killer, NULL, NULL, targ->client ? GIB_DAMAGE(targ->health) : GIB_ENT, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); continue; } if (targ->s.eType == ET_CONSTRUCTIBLE) { if (killer) { G_AddKillSkillPointsForDestruction(killer, mod, &targ->constructibleStats); } targ->die(targ, killer, killer, targ->health, MOD_UNKNOWN); continue; } trap_UnlinkEntity(targ); targ->nextthink = level.time + FRAMETIME; targ->use = NULL; targ->touch = NULL; targ->think = G_FreeEntity; } }
/** * @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; } } } } }
// Arnout: links the trigger to it's objective, determining if it's a func_explosive // of func_constructible and spawning the right indicator void Think_SetupObjectiveInfo( gentity_t *ent ) { ent->target_ent = G_FindByTargetname( NULL, ent->target ); if( !ent->target_ent ) { G_Error ("'trigger_objective_info' has a missing target '%s'\n", ent->target ); } if( ent->target_ent->s.eType == ET_EXPLOSIVE ) { // Arnout: this is for compass usage if ( ( ent->spawnflags & AXIS_OBJECTIVE ) || ( ent->spawnflags & ALLIED_OBJECTIVE ) ) { gentity_t *e; e = G_Spawn(); e->r.svFlags = SVF_BROADCAST; e->classname = "explosive_indicator"; if( ent->spawnflags & 8 ) { e->s.eType = ET_TANK_INDICATOR; } else { e->s.eType = ET_EXPLOSIVE_INDICATOR; } e->parent = ent; e->s.pos.trType = TR_STATIONARY; if ( ent->spawnflags & AXIS_OBJECTIVE ) e->s.teamNum = 1; else if ( ent->spawnflags & ALLIED_OBJECTIVE ) e->s.teamNum = 2; G_SetOrigin(e, ent->r.currentOrigin); e->s.modelindex2 = ent->s.teamNum; e->r.ownerNum = ent->s.number; e->think = explosive_indicator_think; e->nextthink = level.time + FRAMETIME; e->s.effect1Time = ent->target_ent->constructibleStats.weaponclass; if( ent->tagParent ) { e->tagParent = ent->tagParent; Q_strncpyz( e->tagName, ent->tagName, MAX_QPATH ); } else { VectorCopy( ent->r.absmin, e->s.pos.trBase ); VectorAdd( ent->r.absmax, e->s.pos.trBase, e->s.pos.trBase ); VectorScale( e->s.pos.trBase, 0.5, e->s.pos.trBase ); } SnapVector( e->s.pos.trBase ); trap_LinkEntity( e ); ent->target_ent->parent = ent; } } else if ( ent->target_ent->s.eType == ET_CONSTRUCTIBLE ) { gentity_t *constructibles[2]; int team[2]; ent->target_ent->parent = ent; constructibles[0] = ent->target_ent; constructibles[1] = G_FindByTargetname( constructibles[0], ent->target ); // see if we are targetting a 2nd one for two team constructibles team[0] = constructibles[0]->spawnflags & AXIS_CONSTRUCTIBLE ? TEAM_AXIS : TEAM_ALLIES; constructibles[0]->s.otherEntityNum2 = ent->s.teamNum; if( constructibles[1] ) { team[1] = constructibles[1]->spawnflags & AXIS_CONSTRUCTIBLE ? TEAM_AXIS : TEAM_ALLIES; if( constructibles[1]->s.eType != ET_CONSTRUCTIBLE ) { G_Error( "'trigger_objective_info' targets multiple entities with targetname '%s', the second one isn't a 'func_constructible'\n", ent->target ); } if( team[0] == team[1] ) { G_Error( "'trigger_objective_info' targets two 'func_constructible' entities with targetname '%s' that are constructible by the same team\n", ent->target ); } constructibles[1]->s.otherEntityNum2 = ent->s.teamNum; ent->chain = constructibles[1]; ent->chain->parent = ent; constructibles[0]->chain = constructibles[1]; constructibles[1]->chain = constructibles[0]; } else { constructibles[0]->chain = NULL; } // if already constructed (in case of START_BUILT) if( constructibles[0]->s.angles2[1] != 0 ) { // trap_UnlinkEntity( ent ); // return; } else { // Arnout: spawn a constructible icon - this is for compass usage gentity_t *e; e = G_Spawn(); e->r.svFlags = SVF_BROADCAST; e->classname = "constructible_indicator"; if( ent->spawnflags & 8 ) { e->s.eType = ET_TANK_INDICATOR_DEAD; } else { e->s.eType = ET_CONSTRUCTIBLE_INDICATOR; } e->s.pos.trType = TR_STATIONARY; if( constructibles[1] ) { // see if one of the two is still partially built (happens when a multistage destructible construction blows up for the first time) if( constructibles[0]->count2 && constructibles[0]->grenadeFired > 1 ) { e->s.teamNum = team[0]; } else if( constructibles[1]->count2 && constructibles[1]->grenadeFired > 1 ) { e->s.teamNum = team[1]; } else { e->s.teamNum = 3; // both teams } } else { e->s.teamNum = team[0]; } e->s.modelindex2 = ent->s.teamNum; e->r.ownerNum = ent->s.number; ent->count2 = (e - g_entities); e->think = constructible_indicator_think; e->nextthink = level.time + FRAMETIME; e->parent = ent; if( ent->tagParent ) { e->tagParent = ent->tagParent; Q_strncpyz( e->tagName, ent->tagName, MAX_QPATH ); } else { VectorCopy( ent->r.absmin, e->s.pos.trBase ); VectorAdd( ent->r.absmax, e->s.pos.trBase, e->s.pos.trBase ); VectorScale( e->s.pos.trBase, 0.5, e->s.pos.trBase ); } SnapVector( e->s.pos.trBase ); trap_LinkEntity( e ); // moved down } ent->touch = Touch_ObjectiveInfo; } else if( ent->target_ent->s.eType == ET_COMMANDMAP_MARKER ) { ent->target_ent->parent = ent; } trap_LinkEntity (ent); }
/* ================ Bot_ScriptInitBot ================ */ qboolean Bot_ScriptInitBot(int entnum) { gentity_t *ent, *trav; bot_state_t *bs; char userinfo[MAX_INFO_STRING]; bot_script_global_data_t *bsgd; char *token, *p, *pBackup; int i, val = 0; int weapons[2]; gitem_t *item = NULL; char *name; // bs = &botstates[entnum]; if(!bs->inuse) { return qfalse; } if(bs->script.data) { return qtrue; } // set starting defaults bs->script.status.eventIndex = -1; bs->script.data = NULL; // ent = BotGetEntity(bs->entitynum); trap_GetUserinfo(bs->entitynum, userinfo, sizeof(userinfo)); name = Info_ValueForKey(userinfo, "scriptName"); if(!name || !name[0]) { return qfalse; } // find the script data for this bot bsgd = botCharacterScriptData; for(i = 0; i < numScriptCharacters; i++, bsgd++) { if(Q_stricmp(name, bsgd->name) != 0) { continue; } // check params p = bsgd->params; // // eliminate them with each condition not met while(qtrue) { token = COM_ParseExt(&p, qfalse); if(!token || !token[0]) { // we're done, we found a match break; } // if(token[0] != '/') { G_Error("BotScript, line %i: condition identifier expected, '%s' found\n", bsgd->lineNum, token); } // if(!Q_stricmp(token, "/team")) { token = COM_ParseExt(&p, qfalse); if(!token || !token[0] || token[0] == '/') { G_Error("BotScript, line %i: unexpected end of /team parameter", bsgd->lineNum); } // if(!Q_stricmp(token, "axis")) { val = TEAM_AXIS; } else if(!Q_stricmp(token, "allies")) { val = TEAM_ALLIES; } else { G_Error("BotScript, line %i: unknown team \"%s\"", bsgd->lineNum, token); } // eliminate player if(bs->mpTeam != val) { break; } } else // if(!Q_stricmp(token, "/class")) { token = COM_ParseExt(&p, qfalse); if(!token || !token[0] || token[0] == '/') { G_Error("BotScript, line %i: unexpected end of /class parameter", bsgd->lineNum); } // val = Team_ClassForString(token); if(val < 0) { G_Error("BotScript, line %i: unknown class \"%s\"", bsgd->lineNum, token); } if(bs->mpClass != val) { break; } } else // if(!Q_stricmp(token, "/weapon")) { memset(weapons, 0, sizeof(weapons)); // for each weapon while(qtrue) { // read the weapon token = COM_ParseExt(&p, qfalse); if(!token || !token[0] || token[0] == '/') { G_Error("BotScript, line %i: unexpected end of /weapon parameter", bsgd->lineNum); } // if((item = BG_FindItem(token))) { if(!item->giTag) { G_Error("BotScript, line %i: unknown weapon \"%s\"", bsgd->lineNum, token); } COM_BitSet(weapons, item->giTag); } else { G_Error("BotScript, line %i: unknown weapon \"%s\"", bsgd->lineNum, token); } // pBackup = p; token = COM_ParseExt(&p, qfalse); if(Q_stricmp(token, "or") != 0) { // not OR, so drop out of here p = pBackup; break; } } if(!(ent->client->ps.weapons[0] & weapons[0]) && !(ent->client->ps.weapons[1] & weapons[1])) { break; } } else // if(!Q_stricmp(token, "/within_range")) { // targetname token = COM_ParseExt(&p, qfalse); if(!token || !token[0] || token[0] == '/') { G_Error("BotScript, line %i: unexpected end of /within_range parameter", bsgd->lineNum); } trav = G_FindByTargetname(NULL, token); if(!trav) { G_Error("BotScript, line %i: unknown spawn point \"%s\"", bsgd->lineNum, token); } // range token = COM_ParseExt(&p, qfalse); if(!token || !token[0] || token[0] == '/') { G_Error("BotScript, line %i: range expected, not found", bsgd->lineNum); } // // eliminate players if(VectorDistanceSquared(ent->r.currentOrigin, trav->s.origin) > SQR(atof(token))) { break; } } } // // if there is a NOT a valid token waiting, then we passed all checks if(!token[0]) { break; } } // if(i < numScriptCharacters) { // we found a script for this character bs->script.data = bsgd->data; return qtrue; } // return qfalse; }
// JPW NERVE -- if spawn flag is set, use this touch fn instead to turn on/off targeted spawnpoints void checkpoint_spawntouch(gentity_t *self, gentity_t *other, trace_t *trace) { gentity_t *ent = NULL; qboolean playsound = qtrue; qboolean firsttime = qfalse; // Nico, silent GCC (void)trace; if (self->count == (int)other->client->sess.sessionTeam) { return; } 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; } 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; } else if (self->s.frame == WCP_ANIM_AMERICAN_RAISED) { self->s.frame = WCP_ANIM_AMERICAN_FALLING; } 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; } 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; } else if (self->s.frame == WCP_ANIM_AXIS_RAISED) { self->s.frame = WCP_ANIM_AXIS_FALLING; } 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; // Gordon: reset player disguise on touching flag // Run script trigger if (self->count == TEAM_AXIS) { G_Script_ScriptEvent(self, "trigger", "axis_capture"); } else { G_Script_ScriptEvent(self, "trigger", "allied_capture"); } // Don't allow touch again until animation is finished self->touch = NULL; self->think = checkpoint_think; self->nextthink = level.time + 1000; // activate all targets // Arnout - updated this to allow toggling of initial spawnpoints as well, plus now it only // toggles spawnflags 2 for spawnpoint entities if (self->target) { for (;; ) { 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; } } } } }