256 lines
5.5 KiB
C
256 lines
5.5 KiB
C
#include "g_local.h"
|
|
|
|
|
|
/*QUAKED sound_echo (1 0 0) (-16 -16 -16) (16 16 16)
|
|
Echo any sounds that are played within "dmg_radius" radius.
|
|
"delay" "x" where x is the delay between echo's.
|
|
"wait" "x" where x is the sound volume decay percent per echo (eg. 0.1 = %10)
|
|
"dmg_radius" "x" where x is the max distance that affects sounds
|
|
*/
|
|
|
|
void SP_sound_echo (edict_t *self)
|
|
{
|
|
G_FreeEdict(self);
|
|
}
|
|
|
|
/*QUAKED load_mirrorlevel (1 0 0) (-16 -16 -16) (16 16 16)
|
|
"target" the mapname of the mirror map to this one.
|
|
*/
|
|
|
|
void SP_load_mirrorlevel (edict_t *self)
|
|
{
|
|
G_FreeEdict(self);
|
|
}
|
|
|
|
#ifdef CACHE_SOUND
|
|
int (*actual_soundindex) (char *name);
|
|
|
|
list_t *soundList;
|
|
unsigned int soundNumRejected;
|
|
|
|
typedef struct
|
|
{
|
|
char *name;
|
|
|
|
} modelsound;
|
|
|
|
void initSoundList()
|
|
{
|
|
soundList = gi.TagMalloc (sizeof(list_t), TAG_LEVEL);
|
|
initializeList(soundList);
|
|
soundNumRejected = 0;
|
|
}
|
|
|
|
int internalSoundIndex(char *name)
|
|
{
|
|
int idx = 0;
|
|
int numSounds = listLength(soundList);
|
|
modelsound *sound;
|
|
int i = 0;
|
|
|
|
// convert name to lowercase
|
|
for (i = 0; i < strlen(name); i++)
|
|
name[i] = tolower(name[i]);
|
|
|
|
// do we already have this sound?
|
|
for (i = 0; i < numSounds; i++)
|
|
{
|
|
sound = (modelsound *)getItem(soundList, i);
|
|
if(strcmp(sound->name, name) == 0)
|
|
{
|
|
return (*actual_soundindex)(name);
|
|
}
|
|
}
|
|
|
|
// ok, do we have too many sounds?
|
|
if (numSounds >= MAX_SOUNDS-1)
|
|
{
|
|
soundNumRejected++;
|
|
// ok, we cannot precache anymore
|
|
if (printSoundRejects->value)
|
|
gi.dprintf("%s precache rejected\n", name);
|
|
return 0;
|
|
}
|
|
|
|
idx = (*actual_soundindex)(name);
|
|
if (idx == 0)
|
|
return 0;
|
|
|
|
sound = gi.TagMalloc (sizeof(modelsound), TAG_LEVEL);
|
|
sound->name = gi.TagMalloc (strlen(name) + 1, TAG_LEVEL);
|
|
strcpy(sound->name, name);
|
|
|
|
addTail(soundList, sound);
|
|
//gi.dprintf("numSounds = %i\n", listLength(&soundList));
|
|
|
|
return idx;
|
|
}
|
|
|
|
void printSoundNum()
|
|
{
|
|
int numSounds = listLength(soundList);
|
|
gi.dprintf("%i precached sounds\n", numSounds);
|
|
if (printSoundRejects->value)
|
|
gi.dprintf("%i sounds rejected\n", soundNumRejected);
|
|
}
|
|
#endif
|
|
|
|
|
|
/********************************************
|
|
trigger_laser
|
|
*/
|
|
|
|
/*QUAKED trigger_laser (1 0 0) (-16 -16 -16) (16 16 16) TRIGGER_MULTIPLE
|
|
Laser-type trigger
|
|
"wait" "x" where x is the delay before reactivation
|
|
"target" target to trigger
|
|
"message" message to center print
|
|
"delay" delay before trigger
|
|
*/
|
|
|
|
#define TRIGGER_MULTIPLE 1
|
|
void trigger_laser_on (edict_t *self);
|
|
void trigger_laser_think (edict_t *self)
|
|
{
|
|
vec3_t start;
|
|
vec3_t end;
|
|
trace_t tr;
|
|
int count = 8;
|
|
|
|
self->nextthink = level.time + FRAMETIME;
|
|
|
|
VectorCopy (self->s.origin, start);
|
|
VectorMA (start, 2048, self->movedir, end);
|
|
tr = gi.trace (start, NULL, NULL, end, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER);
|
|
|
|
if (!tr.ent)
|
|
return;
|
|
|
|
// if we hit something that's not a monster or player
|
|
if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
|
|
{
|
|
if (self->spawnflags & 0x80000000)
|
|
{
|
|
self->spawnflags &= ~0x80000000;
|
|
gi.WriteByte (svc_temp_entity);
|
|
gi.WriteByte (TE_LASER_SPARKS);
|
|
gi.WriteByte (count);
|
|
gi.WritePosition (tr.endpos);
|
|
gi.WriteDir (tr.plane.normal);
|
|
gi.WriteByte (self->s.skinnum);
|
|
gi.multicast (tr.endpos, MULTICAST_PVS);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// trigger
|
|
G_UseTargets (self, tr.ent);
|
|
|
|
if (self->spawnflags & TRIGGER_MULTIPLE)
|
|
{
|
|
// hide for a time
|
|
self->svflags |= SVF_NOCLIENT;
|
|
self->nextthink = level.time + self->wait;
|
|
self->think = trigger_laser_on;
|
|
}
|
|
else
|
|
{
|
|
// remove self
|
|
G_FreeEdict(self);
|
|
}
|
|
}
|
|
|
|
VectorCopy (tr.endpos, self->s.old_origin);
|
|
}
|
|
|
|
void trigger_laser_on (edict_t *self)
|
|
{
|
|
self->svflags &= ~SVF_NOCLIENT;
|
|
self->think = trigger_laser_think;
|
|
trigger_laser_think(self);
|
|
}
|
|
|
|
void SP_trigger_laser(edict_t *self)
|
|
{
|
|
// if no target
|
|
if (!self->target)
|
|
{
|
|
gi.dprintf("trigger_laser without target\n");
|
|
G_FreeEdict(self);
|
|
return;
|
|
}
|
|
|
|
// if no wait, set default
|
|
if (!self->wait)
|
|
{
|
|
self->wait = 4;
|
|
}
|
|
|
|
G_SetMovedir (self->s.angles, self->movedir);
|
|
self->s.skinnum = 0xf2f2f0f0; // colour
|
|
self->s.frame = 2; // diameter
|
|
self->movetype = MOVETYPE_NONE;
|
|
self->solid = SOLID_NOT;
|
|
self->s.renderfx |= RF_BEAM|RF_TRANSLUCENT;
|
|
self->s.modelindex = 1;
|
|
self->spawnflags |= 0x80000000;
|
|
self->think = trigger_laser_on;
|
|
self->nextthink = level.time + 0.1;
|
|
self->svflags |= SVF_NOCLIENT;
|
|
gi.linkentity (self);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*QUAKED misc_commdish (0 .5 .8) (-16 -16 0) (16 16 40)
|
|
*/
|
|
|
|
void Anim_CommDish(edict_t *self)
|
|
{
|
|
self->s.frame++;
|
|
|
|
if(self->s.frame >= 98)
|
|
{
|
|
self->s.frame = 98;
|
|
}
|
|
else
|
|
{
|
|
self->nextthink = level.time + FRAMETIME;
|
|
}
|
|
}
|
|
|
|
void Use_CommDish (edict_t *ent, edict_t *other, edict_t *activator)
|
|
{
|
|
ent->nextthink = level.time + FRAMETIME;
|
|
ent->think = Anim_CommDish;
|
|
ent->use = NULL;
|
|
gi.sound (ent, CHAN_AUTO, gi.soundindex ("misc/commdish.wav"), 1, ATTN_NORM, 0);
|
|
}
|
|
|
|
void SP_misc_commdish (edict_t *self)
|
|
{
|
|
if (deathmatch->value)
|
|
{ // auto-remove for deathmatch
|
|
G_FreeEdict (self);
|
|
return;
|
|
}
|
|
|
|
self->solid = SOLID_BBOX;
|
|
self->movetype = MOVETYPE_STEP;
|
|
|
|
self->model = "models/objects/satdish/tris.md2";
|
|
self->s.modelindex = gi.modelindex (self->model);
|
|
VectorSet (self->mins, -100, -100, 0);
|
|
VectorSet (self->maxs, 100, 100, 275);
|
|
|
|
self->monsterinfo.aiflags = AI_NOSTEP;
|
|
|
|
self->think = M_droptofloor;
|
|
self->nextthink = level.time + 2 * FRAMETIME;
|
|
self->use = Use_CommDish;
|
|
|
|
gi.linkentity (self);
|
|
}
|