Beispiel #1
0
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];
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
	}
}
Beispiel #5
0
/*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);
	}
}
Beispiel #6
0
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);
	}
}
Beispiel #7
0
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];
}
Beispiel #8
0
/*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);
}
Beispiel #9
0
/*
==============
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);
			}
		}
	}
}
Beispiel #10
0
Datei: g_bot.c Projekt: GenaSG/ET
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 );
}
Beispiel #11
0
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;
	}	
}
Beispiel #12
0
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));
	}
}
Beispiel #13
0
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

	}

}
Beispiel #14
0
/**
 * @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;
	}
}
Beispiel #15
0
/**
 * @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;
				}
			}
		}
	}
}
Beispiel #16
0
// 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);
}
Beispiel #17
0
/*
================
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;
}
Beispiel #18
0
// 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;
				}
			}
		}
	}
}