1857 lines · 43.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include "../dat.h"#include "../fns.h"  /*QUAKED func_group (0 0 0) ?Used to group brushes together just for editor convenience.*/ //===================================================== void Use_Areaportal (edict_t *ent, edict_t */*other*/, edict_t */*activator*/){	ent->count ^= 1;		// toggle state//	gi.dprintf ("portalstate: %i = %i\n", ent->style, ent->count);	gi.SetAreaPortalState (ent->style, ent->count);} /*QUAKED func_areaportal (0 0 0) ? This is a non-visible object that divides the world intoareas that are seperated when this portal is not activated.Usually enclosed in the middle of a door.*/void SP_func_areaportal (edict_t *ent){	ent->use = Use_Areaportal;	ent->count = 0;		// always start closed;} //=====================================================  /*=================Misc functions=================*/void VelocityForDamage (int damage, vec3_t v){	v[0] = 100.0 * crandom();	v[1] = 100.0 * crandom();	v[2] = 200.0 + 100.0 * qrandom(); 	if (damage < 50)		VectorScale (v, 0.7, v);	else 		VectorScale (v, 1.2, v);} void ClipGibVelocity (edict_t *ent){	if (ent->velocity[0] < -300)		ent->velocity[0] = -300;	else if (ent->velocity[0] > 300)		ent->velocity[0] = 300;	if (ent->velocity[1] < -300)		ent->velocity[1] = -300;	else if (ent->velocity[1] > 300)		ent->velocity[1] = 300;	if (ent->velocity[2] < 200)		ent->velocity[2] = 200;	// always some upwards	else if (ent->velocity[2] > 500)		ent->velocity[2] = 500;}  /*=================gibs=================*/void gib_think (edict_t *self){	self->s.frame++;	self->nextthink = level.time + FRAMETIME; 	if (self->s.frame == 10)	{		self->think = G_FreeEdict;		self->nextthink = level.time + 8 + qrandom()*10;	}} void gib_touch (edict_t *self, edict_t */*other*/, cplane_t *plane, csurface_t */*surf*/){	vec3_t	normal_angles, right; 	if (!self->groundentity)		return; 	self->touch = NULL; 	if (plane)	{		gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/fhit3.wav"), 1, ATTN_NORM, 0); 		vectoangles (plane->normal, normal_angles);		AngleVectors (normal_angles, NULL, right, NULL);		vectoangles (right, self->s.angles); 		if (self->s.modelindex == sm_meat_index)		{			self->s.frame++;			self->think = gib_think;			self->nextthink = level.time + FRAMETIME;		}	}} void gib_die (edict_t *self, edict_t */*inflictor*/, edict_t */*attacker*/, int /*damage*/, vec3_t /*point*/){	G_FreeEdict (self);} void ThrowGib (edict_t *self, char *gibname, int damage, int type){	edict_t *gib;	vec3_t	vd;	vec3_t	origin;	vec3_t	size;	float	vscale; 	gib = G_Spawn(); 	VectorScale (self->size, 0.5, size);	VectorAdd (self->absmin, size, origin);	gib->s.origin[0] = origin[0] + crandom() * size[0];	gib->s.origin[1] = origin[1] + crandom() * size[1];	gib->s.origin[2] = origin[2] + crandom() * size[2]; 	gi.setmodel (gib, gibname);	gib->solid = SOLID_NOT;	gib->s.effects |= EF_GIB;	gib->flags |= FL_NO_KNOCKBACK;	gib->takedamage = DAMAGE_YES;	gib->die = gib_die; 	if (type == GIB_ORGANIC)	{		gib->movetype = MOVETYPE_TOSS;		gib->touch = gib_touch;		vscale = 0.5;	}	else	{		gib->movetype = MOVETYPE_BOUNCE;		vscale = 1.0;	} 	VelocityForDamage (damage, vd);	VectorMA (self->velocity, vscale, vd, gib->velocity);	ClipGibVelocity (gib);	gib->avelocity[0] = qrandom()*600;	gib->avelocity[1] = qrandom()*600;	gib->avelocity[2] = qrandom()*600; 	gib->think = G_FreeEdict;	gib->nextthink = level.time + 10 + qrandom()*10; 	gi.linkentity (gib);} void ThrowHead (edict_t *self, char *gibname, int damage, int type){	vec3_t	vd;	float	vscale; 	self->s.skinnum = 0;	self->s.frame = 0;	VectorClear (self->mins);	VectorClear (self->maxs); 	self->s.modelindex2 = 0;	gi.setmodel (self, gibname);	self->solid = SOLID_NOT;	self->s.effects |= EF_GIB;	self->s.effects &= ~EF_FLIES;	self->s.sound = 0;	self->flags |= FL_NO_KNOCKBACK;	self->svflags &= ~SVF_MONSTER;	self->takedamage = DAMAGE_YES;	self->die = gib_die; 	if (type == GIB_ORGANIC)	{		self->movetype = MOVETYPE_TOSS;		self->touch = gib_touch;		vscale = 0.5;	}	else	{		self->movetype = MOVETYPE_BOUNCE;		vscale = 1.0;	} 	VelocityForDamage (damage, vd);	VectorMA (self->velocity, vscale, vd, self->velocity);	ClipGibVelocity (self); 	self->avelocity[YAW] = crandom()*600; 	self->think = G_FreeEdict;	self->nextthink = level.time + 10 + qrandom()*10; 	gi.linkentity (self);}  void ThrowClientHead (edict_t *self, int damage){	vec3_t	vd;	char	*gibname; 	if (rand()&1)	{		gibname = "models/objects/gibs/head2/tris.md2";		self->s.skinnum = 1;		// second skin is player	}	else	{		gibname = "models/objects/gibs/skull/tris.md2";		self->s.skinnum = 0;	} 	self->s.origin[2] += 32;	self->s.frame = 0;	gi.setmodel (self, gibname);	VectorSet (self->mins, -16, -16, 0);	VectorSet (self->maxs, 16, 16, 16); 	self->takedamage = DAMAGE_NO;	self->solid = SOLID_NOT;	self->s.effects = EF_GIB;	self->s.sound = 0;	self->flags |= FL_NO_KNOCKBACK; 	self->movetype = MOVETYPE_BOUNCE;	VelocityForDamage (damage, vd);	VectorAdd (self->velocity, vd, self->velocity); 	if (self->client)	// bodies in the queue don't have a client anymore	{		self->client->anim_priority = ANIM_DEATH;		self->client->anim_end = self->s.frame;	}	else	{		self->think = NULL;		self->nextthink = 0;	} 	gi.linkentity (self);}  /*=================debris=================*/void debris_die (edict_t *self, edict_t */*inflictor*/, edict_t */*attacker*/, int /*damage*/, vec3_t /*point*/){	G_FreeEdict (self);} void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin){	edict_t	*chunk;	vec3_t	v; 	chunk = G_Spawn();	VectorCopy (origin, chunk->s.origin);	gi.setmodel (chunk, modelname);	v[0] = 100 * crandom();	v[1] = 100 * crandom();	v[2] = 100 + 100 * crandom();	VectorMA (self->velocity, speed, v, chunk->velocity);	chunk->movetype = MOVETYPE_BOUNCE;	chunk->solid = SOLID_NOT;	chunk->avelocity[0] = qrandom()*600;	chunk->avelocity[1] = qrandom()*600;	chunk->avelocity[2] = qrandom()*600;	chunk->think = G_FreeEdict;	chunk->nextthink = level.time + 5 + qrandom()*5;	chunk->s.frame = 0;	chunk->flags = 0;	chunk->classname = "debris";	chunk->takedamage = DAMAGE_YES;	chunk->die = debris_die;	gi.linkentity (chunk);}  void BecomeExplosion1 (edict_t *self){	gi.WriteByte (svc_temp_entity);	gi.WriteByte (TE_EXPLOSION1);	gi.WritePosition (self->s.origin);	gi.multicast (self->s.origin, MULTICAST_PVS); 	G_FreeEdict (self);}  void BecomeExplosion2 (edict_t *self){	gi.WriteByte (svc_temp_entity);	gi.WriteByte (TE_EXPLOSION2);	gi.WritePosition (self->s.origin);	gi.multicast (self->s.origin, MULTICAST_PVS); 	G_FreeEdict (self);}  /*QUAKED path_corner (.5 .3 0) (-8 -8 -8) (8 8 8) TELEPORTTarget: next path cornerPathtarget: gets used when an entity that has	this path_corner targeted touches it*/ void path_corner_touch (edict_t *self, edict_t *other, cplane_t */*plane*/, csurface_t */*surf*/){	vec3_t		v;	edict_t		*next; 	if (other->movetarget != self)		return;		if (other->enemy)		return; 	if (self->pathtarget)	{		char *savetarget; 		savetarget = self->target;		self->target = self->pathtarget;		G_UseTargets (self, other);		self->target = savetarget;	} 	if (self->target)		next = G_PickTarget(self->target);	else		next = NULL; 	if ((next) && (next->spawnflags & 1))	{		VectorCopy (next->s.origin, v);		v[2] += next->mins[2];		v[2] -= other->mins[2];		VectorCopy (v, other->s.origin);		next = G_PickTarget(next->target);		other->s.event = EV_OTHER_TELEPORT;	} 	other->goalentity = other->movetarget = next; 	if (self->wait)	{		other->monsterinfo.pausetime = level.time + self->wait;		other->monsterinfo.stand (other);		return;	} 	if (!other->movetarget)	{		other->monsterinfo.pausetime = level.time + 100000000;		other->monsterinfo.stand (other);	}	else	{		VectorSubtract (other->goalentity->s.origin, other->s.origin, v);		other->ideal_yaw = vectoyaw (v);	}} void SP_path_corner (edict_t *self){	if (!self->targetname)	{		gi.dprintf ("path_corner with no targetname at %s\n", vtos(self->s.origin));		G_FreeEdict (self);		return;	} 	self->solid = SOLID_TRIGGER;	self->touch = path_corner_touch;	VectorSet (self->mins, -8, -8, -8);	VectorSet (self->maxs, 8, 8, 8);	self->svflags |= SVF_NOCLIENT;	gi.linkentity (self);}  /*QUAKED point_combat (0.5 0.3 0) (-8 -8 -8) (8 8 8) HoldMakes this the target of a monster and it will head herewhen first activated before going after the activator.  Ifhold is selected, it will stay here.*/void point_combat_touch (edict_t *self, edict_t *other, cplane_t */*plane*/, csurface_t */*surf*/){	edict_t	*activator; 	if (other->movetarget != self)		return; 	if (self->target)	{		other->target = self->target;		other->goalentity = other->movetarget = G_PickTarget(other->target);		if (!other->goalentity)		{			gi.dprintf("%s at %s target %s does not exist\n", self->classname, vtos(self->s.origin), self->target);			other->movetarget = self;		}		self->target = NULL;	}	else if ((self->spawnflags & 1) && !(other->flags & (FL_SWIM|FL_FLY)))	{		other->monsterinfo.pausetime = level.time + 100000000;		other->monsterinfo.aiflags |= AI_STAND_GROUND;		other->monsterinfo.stand (other);	} 	if (other->movetarget == self)	{		other->target = NULL;		other->movetarget = NULL;		other->goalentity = other->enemy;		other->monsterinfo.aiflags &= ~AI_COMBAT_POINT;	} 	if (self->pathtarget)	{		char *savetarget; 		savetarget = self->target;		self->target = self->pathtarget;		if (other->enemy && other->enemy->client)			activator = other->enemy;		else if (other->oldenemy && other->oldenemy->client)			activator = other->oldenemy;		else if (other->activator && other->activator->client)			activator = other->activator;		else			activator = other;		G_UseTargets (self, activator);		self->target = savetarget;	}} void SP_point_combat (edict_t *self){	if (deathmatch->value)	{		G_FreeEdict (self);		return;	}	self->solid = SOLID_TRIGGER;	self->touch = point_combat_touch;	VectorSet (self->mins, -8, -8, -16);	VectorSet (self->maxs, 8, 8, 16);	self->svflags = SVF_NOCLIENT;	gi.linkentity (self);};  /*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)Just for the debugging level.  Don't use*/void TH_viewthing(edict_t *ent){	ent->s.frame = (ent->s.frame + 1) % 7;	ent->nextthink = level.time + FRAMETIME;} void SP_viewthing(edict_t *ent){	gi.dprintf ("viewthing spawned\n"); 	ent->movetype = MOVETYPE_NONE;	ent->solid = SOLID_BBOX;	ent->s.renderfx = RF_FRAMELERP;	VectorSet (ent->mins, -16, -16, -24);	VectorSet (ent->maxs, 16, 16, 32);	ent->s.modelindex = gi.modelindex ("models/objects/banner/tris.md2");	gi.linkentity (ent);	ent->nextthink = level.time + 0.5;	ent->think = TH_viewthing;	return;}  /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)Used as a positional target for spotlights, etc.

Lines 1–500 of 1857.

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