796 lines · 19.5 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include "../dat.h"#include "../fns.h" /*QUAKED target_temp_entity (1 0 0) (-8 -8 -8) (8 8 8)Fire an origin based temp entity event to the clients."style"		type byte*/void Use_Target_Tent (edict_t *ent, edict_t */*other*/, edict_t */*activator*/){	gi.WriteByte (svc_temp_entity);	gi.WriteByte (ent->style);	gi.WritePosition (ent->s.origin);	gi.multicast (ent->s.origin, MULTICAST_PVS);} void SP_target_temp_entity (edict_t *ent){	ent->use = Use_Target_Tent;}  //========================================================== //========================================================== /*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off reliable"noise"		wav file to play"attenuation"-1 = none, send to whole level1 = normal fighting sounds2 = idle sound level3 = ambient sound level"volume"	0.0 to 1.0 Normal sounds play each time the target is used.  The reliable flag can be set for crucial voiceovers. Looped sounds are always atten 3 / vol 1, and the use function toggles it on/off.Multiple identical looping sounds will just increase volume without any speed cost.*/void Use_Target_Speaker (edict_t *ent, edict_t */*other*/, edict_t */*activator*/){	int		chan; 	if (ent->spawnflags & 3)	{	// looping sound toggles		if (ent->s.sound)			ent->s.sound = 0;	// turn it off		else			ent->s.sound = ent->noise_index;	// start it	}	else	{	// normal sound		if (ent->spawnflags & 4)			chan = CHAN_VOICE|CHAN_RELIABLE;		else			chan = CHAN_VOICE;		// use a positioned_sound, because this entity won't normally be		// sent to any clients because it is invisible		gi.positioned_sound (ent->s.origin, ent, chan, ent->noise_index, ent->volume, ent->attenuation, 0);	}} void SP_target_speaker (edict_t *ent){	char	buffer[MAX_QPATH]; 	if(!st.noise)	{		gi.dprintf("target_speaker with no noise set at %s\n", vtos(ent->s.origin));		return;	}	if (!strstr (st.noise, ".wav"))		Com_sprintf (buffer, sizeof(buffer), "%s.wav", st.noise);	else		strncpy (buffer, st.noise, sizeof(buffer));	ent->noise_index = gi.soundindex (buffer); 	if (!ent->volume)		ent->volume = 1.0; 	if (!ent->attenuation)		ent->attenuation = 1.0;	else if (ent->attenuation == -1)	// use -1 so 0 defaults to 1		ent->attenuation = 0; 	// check for prestarted looping sound	if (ent->spawnflags & 1)		ent->s.sound = ent->noise_index; 	ent->use = Use_Target_Speaker; 	// must link the entity so we get areas and clusters so	// the server can determine who to send updates to	gi.linkentity (ent);}  //========================================================== void Use_Target_Help (edict_t *ent, edict_t */*other*/, edict_t */*activator*/){	if (ent->spawnflags & 1)		strncpy (game.helpmessage1, ent->message, sizeof(game.helpmessage2)-1);	else		strncpy (game.helpmessage2, ent->message, sizeof(game.helpmessage1)-1); 	game.helpchanged++;} /*QUAKED target_help (1 0 1) (-16 -16 -24) (16 16 24) help1When fired, the "message" key becomes the current personal computer string, and the message light will be set on all clients status bars.*/void SP_target_help(edict_t *ent){	if (deathmatch->value)	{	// auto-remove for deathmatch		G_FreeEdict (ent);		return;	} 	if (!ent->message)	{		gi.dprintf ("%s with no message at %s\n", ent->classname, vtos(ent->s.origin));		G_FreeEdict (ent);		return;	}	ent->use = Use_Target_Help;} //========================================================== /*QUAKED target_secret (1 0 1) (-8 -8 -8) (8 8 8)Counts a secret found.These are single use targets.*/void use_target_secret (edict_t *ent, edict_t */*other*/, edict_t *activator){	gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); 	level.found_secrets++; 	G_UseTargets (ent, activator);	G_FreeEdict (ent);} void SP_target_secret (edict_t *ent){	if (deathmatch->value)	{	// auto-remove for deathmatch		G_FreeEdict (ent);		return;	} 	ent->use = use_target_secret;	if (!st.noise)		st.noise = "misc/secret.wav";	ent->noise_index = gi.soundindex (st.noise);	ent->svflags = SVF_NOCLIENT;	level.total_secrets++;	// map bug hack	if (!cistrcmp(level.mapname, "mine3") && ent->s.origin[0] == 280 && ent->s.origin[1] == -2048 && ent->s.origin[2] == -624)		ent->message = "You have found a secret area.";} //========================================================== /*QUAKED target_goal (1 0 1) (-8 -8 -8) (8 8 8)Counts a goal completed.These are single use targets.*/void use_target_goal (edict_t *ent, edict_t */*other*/, edict_t *activator){	gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); 	level.found_goals++; 	if (level.found_goals == level.total_goals)		gi.configstring (CS_CDTRACK, "0"); 	G_UseTargets (ent, activator);	G_FreeEdict (ent);} void SP_target_goal (edict_t *ent){	if (deathmatch->value)	{	// auto-remove for deathmatch		G_FreeEdict (ent);		return;	} 	ent->use = use_target_goal;	if (!st.noise)		st.noise = "misc/secret.wav";	ent->noise_index = gi.soundindex (st.noise);	ent->svflags = SVF_NOCLIENT;	level.total_goals++;} //==========================================================  /*QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8)Spawns an explosion temporary entity when used. "delay"		wait this long before going off"dmg"		how much radius damage should be done, defaults to 0*/void target_explosion_explode (edict_t *self){	float		save; 	gi.WriteByte (svc_temp_entity);	gi.WriteByte (TE_EXPLOSION1);	gi.WritePosition (self->s.origin);	gi.multicast (self->s.origin, MULTICAST_PHS); 	T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE); 	save = self->delay;	self->delay = 0;	G_UseTargets (self, self->activator);	self->delay = save;} void use_target_explosion (edict_t *self, edict_t */*other*/, edict_t *activator){	self->activator = activator; 	if (!self->delay)	{		target_explosion_explode (self);		return;	} 	self->think = target_explosion_explode;	self->nextthink = level.time + self->delay;} void SP_target_explosion (edict_t *ent){	ent->use = use_target_explosion;	ent->svflags = SVF_NOCLIENT;}  //========================================================== /*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8)Changes level to "map" when fired*/void use_target_changelevel (edict_t *self, edict_t *other, edict_t *activator){	if (level.intermissiontime)		return;		// already activated 	if (!deathmatch->value && !coop->value)	{		if (g_edicts[1].health <= 0)			return;	} 	// if noexit, do a ton of damage to other	if (deathmatch->value && !( (int)dmflags->value & DF_ALLOW_EXIT) && other != WORLD)	{		T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0, MOD_EXIT);		return;	} 	// if multiplayer, let everyone know who hit the exit	if (deathmatch->value)	{		if (activator && activator->client)			gi.bprintf (PRINT_HIGH, "%s exited the level.\n", activator->client->pers.netname);	} 	// if going to a new unit, clear cross triggers	if (strstr(self->map, "*"))			game.serverflags &= ~(SFL_CROSS_TRIGGER_MASK); 	BeginIntermission (self);} void SP_target_changelevel (edict_t *ent){	if (!ent->map)	{		gi.dprintf("target_changelevel with no map at %s\n", vtos(ent->s.origin));		G_FreeEdict (ent);		return;	} 	// ugly hack because *SOMEBODY* screwed up their map   if((cistrcmp(level.mapname, "fact1") == 0) && (cistrcmp(ent->map, "fact3") == 0))	   ent->map = "fact3$secret1"; 	ent->use = use_target_changelevel;	ent->svflags = SVF_NOCLIENT;}  //========================================================== /*QUAKED target_splash (1 0 0) (-8 -8 -8) (8 8 8)Creates a particle splash effect when used. Set "sounds" to one of the following:  1) sparks  2) blue water  3) brown water  4) slime  5) lava  6) blood "count"	how many pixels in the splash"dmg"	if set, does a radius damage at this location when it splashes		useful for lava/sparks*/ void use_target_splash (edict_t *self, edict_t */*other*/, edict_t *activator){	gi.WriteByte (svc_temp_entity);	gi.WriteByte (TE_SPLASH);	gi.WriteByte (self->count);	gi.WritePosition (self->s.origin);	gi.WriteDir (self->movedir);	gi.WriteByte (self->sounds);	gi.multicast (self->s.origin, MULTICAST_PVS); 	if (self->dmg)		T_RadiusDamage (self, activator, self->dmg, NULL, self->dmg+40, MOD_SPLASH);} void SP_target_splash (edict_t *self){	self->use = use_target_splash;	G_SetMovedir (self->s.angles, self->movedir); 	if (!self->count)		self->count = 32; 	self->svflags = SVF_NOCLIENT;}  //========================================================== /*QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8)Set target to the type of entity you want spawned.Useful for spawning monsters and gibs in the factory levels. For monsters:	Set direction to the facing you want it to have. For gibs:	Set direction if you want it moving and	speed how fast it should be moving otherwise it	will just be dropped*/void ED_CallSpawn (edict_t *ent); void use_target_spawner (edict_t *self, edict_t */*other*/, edict_t */*activator*/){	edict_t	*ent; 	ent = G_Spawn();	ent->classname = self->target;	VectorCopy (self->s.origin, ent->s.origin);	VectorCopy (self->s.angles, ent->s.angles);	ED_CallSpawn (ent);	gi.unlinkentity (ent);	KillBox (ent);	gi.linkentity (ent);	if (self->speed)		VectorCopy (self->movedir, ent->velocity);} void SP_target_spawner (edict_t *self){	self->use = use_target_spawner;	self->svflags = SVF_NOCLIENT;	if (self->speed)	{		G_SetMovedir (self->s.angles, self->movedir);		VectorScale (self->movedir, self->speed, self->movedir);	}} //========================================================== /*QUAKED target_blaster (1 0 0) (-8 -8 -8) (8 8 8) NOTRAIL NOEFFECTSFires a blaster bolt in the set direction when triggered. dmg		default is 15speed	default is 1000*/ void use_target_blaster (edict_t *self, edict_t */*other*/, edict_t */*activator*/){	/*	int effect; 	if (self->spawnflags & 2)		effect = 0;	else if (self->spawnflags & 1)		effect = EF_HYPERBLASTER;	else		effect = EF_BLASTER;	*/ 	fire_blaster (self, self->s.origin, self->movedir, self->dmg, self->speed, EF_BLASTER, MOD_TARGET_BLASTER);	gi.sound (self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0);} void SP_target_blaster (edict_t *self){	self->use = use_target_blaster;	G_SetMovedir (self->s.angles, self->movedir);	self->noise_index = gi.soundindex ("weapons/laser2.wav"); 	if (!self->dmg)		self->dmg = 15;	if (!self->speed)		self->speed = 1000; 	self->svflags = SVF_NOCLIENT;}  //========================================================== /*QUAKED target_crosslevel_trigger (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8Once this trigger is touched/used, any trigger_crosslevel_target with the same trigger number is automatically used when a level is started within the same unit.  It is OK to check multiple triggers.  Message, delay, target, and killtarget also work.*/void trigger_crosslevel_trigger_use (edict_t *self, edict_t */*other*/, edict_t */*activator*/){	game.serverflags |= self->spawnflags;	G_FreeEdict (self);} void SP_target_crosslevel_trigger (edict_t *self){	self->svflags = SVF_NOCLIENT;	self->use = trigger_crosslevel_trigger_use;} /*QUAKED target_crosslevel_target (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8Triggered by a trigger_crosslevel elsewhere within a unit.  If multiple triggers are checked, all must be true.  Delay, target andkilltarget also work. "delay"		delay before using targets if the trigger has been activated (default 1)*/void target_crosslevel_target_think (edict_t *self){	if (self->spawnflags == (game.serverflags & SFL_CROSS_TRIGGER_MASK & self->spawnflags))	{		G_UseTargets (self, self);		G_FreeEdict (self);	}} void SP_target_crosslevel_target (edict_t *self){	if (! self->delay)		self->delay = 1;	self->svflags = SVF_NOCLIENT; 	self->think = target_crosslevel_target_think;	self->nextthink = level.time + self->delay;} //========================================================== /*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FATWhen triggered, fires a laser.  You can either set a targetor a direction.*/ void target_laser_think (edict_t *self){	edict_t	*ignore;	vec3_t	start;	vec3_t	end;	trace_t	tr;	vec3_t	point;	vec3_t	last_movedir;	int		count; 	if (self->spawnflags & 0x80000000)		count = 8;	else		count = 4; 	if (self->enemy)	{		VectorCopy (self->movedir, last_movedir);		VectorMA (self->enemy->absmin, 0.5, self->enemy->size, point);

Lines 1–500 of 796.

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