694 lines · 15.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include "../dat.h"#include "../fns.h"  void InitTrigger (edict_t *self){	if (!VectorCompare (self->s.angles, vec3_origin))		G_SetMovedir (self->s.angles, self->movedir); 	self->solid = SOLID_TRIGGER;	self->movetype = MOVETYPE_NONE;	gi.setmodel (self, self->model);	self->svflags = SVF_NOCLIENT;}  // the wait time has passed, so set back up for another activationvoid multi_wait (edict_t *ent){	ent->nextthink = 0;}  // the trigger was just activated// ent->activator should be set to the activator so it can be held through a delay// so wait for the delay time before firingvoid multi_trigger (edict_t *ent){	if (ent->nextthink)		return;		// already been triggered 	G_UseTargets (ent, ent->activator); 	if (ent->wait > 0)		{		ent->think = multi_wait;		ent->nextthink = level.time + ent->wait;	}	else	{	// we can't just remove (self) here, because this is a touch function		// called while looping through area links...		ent->touch = NULL;		ent->nextthink = level.time + FRAMETIME;		ent->think = G_FreeEdict;	}} void Use_Multi (edict_t *ent, edict_t *, edict_t *activator){	ent->activator = activator;	multi_trigger (ent);} void Touch_Multi (edict_t *self, edict_t *other, cplane_t *, csurface_t *){	if(other->client)	{		if (self->spawnflags & 2)			return;	}	else if (other->svflags & SVF_MONSTER)	{		if (!(self->spawnflags & 1))			return;	}	else		return; 	if (!VectorCompare(self->movedir, vec3_origin))	{		vec3_t	forward; 		AngleVectors(other->s.angles, forward, NULL, NULL);		if (_DotProduct(forward, self->movedir) < 0)			return;	} 	self->activator = other;	multi_trigger (self);} /*QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGEREDVariable sized repeatable trigger.  Must be targeted at one or more entities.If "delay" is set, the trigger waits some time after activating before firing."wait" : Seconds between triggerings. (.2 default)sounds1)	secret2)	beep beep3)	large switch4)set "message" to text string*/void trigger_enable (edict_t *self, edict_t *, edict_t *){	self->solid = SOLID_TRIGGER;	self->use = Use_Multi;	gi.linkentity (self);} void SP_trigger_multiple (edict_t *ent){	if (ent->sounds == 1)		ent->noise_index = gi.soundindex ("misc/secret.wav");	else if (ent->sounds == 2)		ent->noise_index = gi.soundindex ("misc/talk.wav");	else if (ent->sounds == 3)		ent->noise_index = gi.soundindex ("misc/trigger1.wav");		if (!ent->wait)		ent->wait = 0.2;	ent->touch = Touch_Multi;	ent->movetype = MOVETYPE_NONE;	ent->svflags |= SVF_NOCLIENT;  	if (ent->spawnflags & 4)	{		ent->solid = SOLID_NOT;		ent->use = trigger_enable;	}	else	{		ent->solid = SOLID_TRIGGER;		ent->use = Use_Multi;	} 	if (!VectorCompare(ent->s.angles, vec3_origin))		G_SetMovedir (ent->s.angles, ent->movedir); 	gi.setmodel (ent, ent->model);	gi.linkentity (ent);}  /*QUAKED trigger_once (.5 .5 .5) ? x x TRIGGEREDTriggers once, then removes itself.You must set the key "target" to the name of another object in the level that has a matching "targetname". If TRIGGERED, this trigger must be triggered before it is live. sounds 1)	secret 2)	beep beep 3)	large switch 4) "message"	string to be displayed when triggered*/ void SP_trigger_once(edict_t *ent){	// make old maps work because I messed up on flag assignments here	// triggered was on bit 1 when it should have been on bit 4	if (ent->spawnflags & 1)	{		vec3_t	v; 		VectorMA (ent->mins, 0.5, ent->size, v);		ent->spawnflags &= ~1;		ent->spawnflags |= 4;		gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v));	} 	ent->wait = -1;	SP_trigger_multiple (ent);} /*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)This fixed size trigger cannot be touched, it can only be fired by other events.*/void trigger_relay_use (edict_t *self, edict_t *, edict_t *activator){	G_UseTargets (self, activator);} void SP_trigger_relay (edict_t *self){	self->use = trigger_relay_use;}  /*============================================================================== trigger_key ==============================================================================*/ /*QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8)A relay trigger that only fires it's targets if player has the proper key.Use "item" to specify the required key, for example "key_data_cd"*/void trigger_key_use (edict_t *self, edict_t *, edict_t *activator){	int			index; 	if (!self->item)		return;	if (!activator->client)		return; 	index = ITEM_INDEX(self->item);	if (!activator->client->pers.inventory[index])	{		if (level.time < self->touch_debounce_time)			return;		self->touch_debounce_time = level.time + 5.0;		gi.centerprintf (activator, "You need the %s", self->item->pickup_name);		gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keytry.wav"), 1, ATTN_NORM, 0);		return;	} 	gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keyuse.wav"), 1, ATTN_NORM, 0);	if (coop->value)	{		int		player;		edict_t	*ent; 		if (strcmp(self->item->classname, "key_power_cube") == 0)		{			int	cube; 			for (cube = 0; cube < 8; cube++)				if (activator->client->pers.power_cubes & (1 << cube))					break;			for (player = 1; player <= game.maxclients; player++)			{				ent = &g_edicts[player];				if (!ent->inuse)					continue;				if (!ent->client)					continue;				if (ent->client->pers.power_cubes & (1 << cube))				{					ent->client->pers.inventory[index]--;					ent->client->pers.power_cubes &= ~(1 << cube);				}			}		}		else		{			for (player = 1; player <= game.maxclients; player++)			{				ent = &g_edicts[player];				if (!ent->inuse)					continue;				if (!ent->client)					continue;				ent->client->pers.inventory[index] = 0;			}		}	}	else	{		activator->client->pers.inventory[index]--;	} 	G_UseTargets (self, activator); 	self->use = NULL;} void SP_trigger_key (edict_t *self){	if (!st.item)	{		gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));		return;	}	self->item = FindItemByClassname (st.item); 	if (!self->item)	{		gi.dprintf("item %s not found for trigger_key at %s\n", st.item, vtos(self->s.origin));		return;	} 	if (!self->target)	{		gi.dprintf("%s at %s has no target\n", self->classname, vtos(self->s.origin));		return;	} 	gi.soundindex ("misc/keytry.wav");	gi.soundindex ("misc/keyuse.wav"); 	self->use = trigger_key_use;}  /*============================================================================== trigger_counter ==============================================================================*/ /*QUAKED trigger_counter (.5 .5 .5) ? nomessageActs as an intermediary for an action that takes multiple inputs. If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished. After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.*/ void trigger_counter_use(edict_t *self, edict_t *, edict_t *activator){	if (self->count == 0)		return;		self->count--; 	if (self->count)	{		if (! (self->spawnflags & 1))		{			gi.centerprintf(activator, "%i more to go...", self->count);			gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);		}		return;	}		if (! (self->spawnflags & 1))	{		gi.centerprintf(activator, "Sequence completed!");		gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);	}	self->activator = activator;	multi_trigger (self);} void SP_trigger_counter (edict_t *self){	self->wait = -1;	if (!self->count)		self->count = 2; 	self->use = trigger_counter_use;}  /*============================================================================== trigger_always ==============================================================================*/ /*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)This trigger will always fire.  It is activated by the world.*/void SP_trigger_always (edict_t *ent){	// we must have some delay to make sure our use targets are present	if (ent->delay < 0.2)		ent->delay = 0.2;	G_UseTargets(ent, ent);}  /*============================================================================== trigger_push ==============================================================================*//*#define PUSH_ONCE		1 static int windsound; void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *){	if (strcmp(other->classname, "grenade") == 0)	{		VectorScale (self->movedir, self->speed * 10, other->velocity);	}	else if (other->health > 0)	{		VectorScale (self->movedir, self->speed * 10, other->velocity); 		if (other->client)		{			// don't take falling damage immediately from this			VectorCopy (other->velocity, other->client->oldvelocity);			if (other->fly_sound_debounce_time < level.time)			{				other->fly_sound_debounce_time = level.time + 1.5;				gi.sound (other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);			}		}	}	if (self->spawnflags & PUSH_ONCE)		G_FreeEdict (self);} void SP_trigger_push (edict_t *self){	InitTrigger (self);	windsound = gi.soundindex ("misc/windfly.wav");	self->touch = trigger_push_touch;	if (!self->speed)		self->speed = 1000;	gi.linkentity (self);}*/ // RAFAEL#define PUSH_ONCE  1 static int windsound; void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *){	if (strcmp(other->classname, "grenade") == 0)	{		VectorScale (self->movedir, self->speed * 10, other->velocity);	}	else if (other->health > 0)	{			VectorScale (self->movedir, self->speed * 10, other->velocity); 		if (other->client)		{			// don't take falling damage immediately from this			VectorCopy (other->velocity, other->client->oldvelocity);			if (other->fly_sound_debounce_time < level.time)			{				other->fly_sound_debounce_time = level.time + 1.5;				gi.sound (other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);			}		}	}	if (self->spawnflags & PUSH_ONCE)	G_FreeEdict (self);}  /*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE PUSH_PLUS PUSH_RAMPPushes the player"speed"  defaults to 1000"wait"  defaults to 10 must use PUSH_PLUS  used for on*/ void trigger_push_active (edict_t *self); void trigger_effect (edict_t *self){	vec3_t	origin;	vec3_t	size;	int		i;		VectorScale (self->size, 0.5, size);	VectorAdd (self->absmin, size, origin);		for (i=0; i<10; i++)	{		origin[2] += (self->speed * 0.01) * (i + qrandom());		gi.WriteByte (svc_temp_entity);		gi.WriteByte (TE_TUNNEL_SPARKS);		gi.WriteByte (1);		gi.WritePosition (origin);		gi.WriteDir (vec3_origin);		gi.WriteByte (0x74 + (rand()&7));		gi.multicast (self->s.origin, MULTICAST_PVS);	} } void trigger_push_inactive (edict_t *self){	if (self->delay > level.time)	{		self->nextthink = level.time + 0.1;	}	else	{		self->touch = trigger_push_touch;		self->think = trigger_push_active;		self->nextthink = level.time + 0.1;		self->delay = self->nextthink + self->wait;  	}} void trigger_push_active (edict_t *self){	if (self->delay > level.time)	{		self->nextthink = level.time + 0.1;		trigger_effect (self);	}	else	{

Lines 1–500 of 694.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t