mirror of
https://github.com/yquake2/ctf.git
synced 2024-11-29 15:12:04 +00:00
Reformat g_trigger.c
This commit is contained in:
parent
373e2d1efc
commit
725c5a94b7
1 changed files with 425 additions and 267 deletions
664
src/g_trigger.c
664
src/g_trigger.c
|
@ -1,53 +1,64 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 1997-2001 Id Software, Inc.
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* Trigger.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
void
|
||||||
void InitTrigger (edict_t *self)
|
InitTrigger(edict_t *self)
|
||||||
{
|
{
|
||||||
if (!VectorCompare (self->s.angles, vec3_origin))
|
if (!VectorCompare(self->s.angles, vec3_origin))
|
||||||
G_SetMovedir (self->s.angles, self->movedir);
|
{
|
||||||
|
G_SetMovedir(self->s.angles, self->movedir);
|
||||||
|
}
|
||||||
|
|
||||||
self->solid = SOLID_TRIGGER;
|
self->solid = SOLID_TRIGGER;
|
||||||
self->movetype = MOVETYPE_NONE;
|
self->movetype = MOVETYPE_NONE;
|
||||||
gi.setmodel (self, self->model);
|
gi.setmodel(self, self->model);
|
||||||
self->svflags = SVF_NOCLIENT;
|
self->svflags = SVF_NOCLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// the wait time has passed, so set back up for another activation
|
* The wait time has passed, so set
|
||||||
void multi_wait (edict_t *ent)
|
* back up for another activation
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
multi_wait(edict_t *ent)
|
||||||
{
|
{
|
||||||
ent->nextthink = 0;
|
ent->nextthink = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
// the trigger was just activated
|
multi_trigger(edict_t *ent)
|
||||||
// ent->activator should be set to the activator so it can be held through a delay
|
|
||||||
// so wait for the delay time before firing
|
|
||||||
void multi_trigger (edict_t *ent)
|
|
||||||
{
|
{
|
||||||
if (ent->nextthink)
|
if (ent->nextthink)
|
||||||
return; // already been triggered
|
{
|
||||||
|
return; /* already been triggered */
|
||||||
|
}
|
||||||
|
|
||||||
G_UseTargets (ent, ent->activator);
|
G_UseTargets(ent, ent->activator);
|
||||||
|
|
||||||
if (ent->wait > 0)
|
if (ent->wait > 0)
|
||||||
{
|
{
|
||||||
|
@ -55,82 +66,107 @@ void multi_trigger (edict_t *ent)
|
||||||
ent->nextthink = level.time + ent->wait;
|
ent->nextthink = level.time + ent->wait;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // we can't just remove (self) here, because this is a touch function
|
{
|
||||||
// called while looping through area links...
|
/* we can't just remove (self) here, because this is
|
||||||
|
a touch function called while looping through area links... */
|
||||||
ent->touch = NULL;
|
ent->touch = NULL;
|
||||||
ent->nextthink = level.time + FRAMETIME;
|
ent->nextthink = level.time + FRAMETIME;
|
||||||
ent->think = G_FreeEdict;
|
ent->think = G_FreeEdict;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Use_Multi (edict_t *ent, edict_t *other, edict_t *activator)
|
void
|
||||||
|
Use_Multi(edict_t *ent, edict_t *other, edict_t *activator)
|
||||||
{
|
{
|
||||||
ent->activator = activator;
|
ent->activator = activator;
|
||||||
multi_trigger (ent);
|
multi_trigger(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Touch_Multi (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
void
|
||||||
|
Touch_Multi(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||||
{
|
{
|
||||||
if(other->client)
|
if (other->client)
|
||||||
{
|
{
|
||||||
if (self->spawnflags & 2)
|
if (self->spawnflags & 2)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (other->svflags & SVF_MONSTER)
|
else if (other->svflags & SVF_MONSTER)
|
||||||
{
|
{
|
||||||
if (!(self->spawnflags & 1))
|
if (!(self->spawnflags & 1))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!VectorCompare(self->movedir, vec3_origin))
|
if (!VectorCompare(self->movedir, vec3_origin))
|
||||||
{
|
{
|
||||||
vec3_t forward;
|
vec3_t forward;
|
||||||
|
|
||||||
AngleVectors(other->s.angles, forward, NULL, NULL);
|
AngleVectors(other->s.angles, forward, NULL, NULL);
|
||||||
|
|
||||||
if (_DotProduct(forward, self->movedir) < 0)
|
if (_DotProduct(forward, self->movedir) < 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self->activator = other;
|
self->activator = other;
|
||||||
multi_trigger (self);
|
multi_trigger(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGERED
|
/*
|
||||||
Variable sized repeatable trigger. Must be targeted at one or more entities.
|
* QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGERED
|
||||||
If "delay" is set, the trigger waits some time after activating before firing.
|
* Variable sized repeatable trigger. Must be targeted at one or more entities.
|
||||||
"wait" : Seconds between triggerings. (.2 default)
|
* If "delay" is set, the trigger waits some time after activating before firing.
|
||||||
sounds
|
* "wait" : Seconds between triggerings. (.2 default)
|
||||||
1) secret
|
*
|
||||||
2) beep beep
|
* sounds
|
||||||
3) large switch
|
* 1) secret
|
||||||
4)
|
* 2) beep beep
|
||||||
set "message" to text string
|
* 3) large switch
|
||||||
*/
|
* 4)
|
||||||
void trigger_enable (edict_t *self, edict_t *other, edict_t *activator)
|
*
|
||||||
|
* set "message" to text string
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
trigger_enable(edict_t *self, edict_t *other, edict_t *activator)
|
||||||
{
|
{
|
||||||
self->solid = SOLID_TRIGGER;
|
self->solid = SOLID_TRIGGER;
|
||||||
self->use = Use_Multi;
|
self->use = Use_Multi;
|
||||||
gi.linkentity (self);
|
gi.linkentity(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_multiple (edict_t *ent)
|
void
|
||||||
|
SP_trigger_multiple(edict_t *ent)
|
||||||
{
|
{
|
||||||
if (ent->sounds == 1)
|
if (ent->sounds == 1)
|
||||||
ent->noise_index = gi.soundindex ("misc/secret.wav");
|
{
|
||||||
|
ent->noise_index = gi.soundindex("misc/secret.wav");
|
||||||
|
}
|
||||||
else if (ent->sounds == 2)
|
else if (ent->sounds == 2)
|
||||||
ent->noise_index = gi.soundindex ("misc/talk.wav");
|
{
|
||||||
|
ent->noise_index = gi.soundindex("misc/talk.wav");
|
||||||
|
}
|
||||||
else if (ent->sounds == 3)
|
else if (ent->sounds == 3)
|
||||||
ent->noise_index = gi.soundindex ("misc/trigger1.wav");
|
{
|
||||||
|
ent->noise_index = gi.soundindex("misc/trigger1.wav");
|
||||||
|
}
|
||||||
|
|
||||||
if (!ent->wait)
|
if (!ent->wait)
|
||||||
|
{
|
||||||
ent->wait = 0.2;
|
ent->wait = 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
ent->touch = Touch_Multi;
|
ent->touch = Touch_Multi;
|
||||||
ent->movetype = MOVETYPE_NONE;
|
ent->movetype = MOVETYPE_NONE;
|
||||||
ent->svflags |= SVF_NOCLIENT;
|
ent->svflags |= SVF_NOCLIENT;
|
||||||
|
|
||||||
|
|
||||||
if (ent->spawnflags & 4)
|
if (ent->spawnflags & 4)
|
||||||
{
|
{
|
||||||
ent->solid = SOLID_NOT;
|
ent->solid = SOLID_NOT;
|
||||||
|
@ -143,93 +179,111 @@ void SP_trigger_multiple (edict_t *ent)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!VectorCompare(ent->s.angles, vec3_origin))
|
if (!VectorCompare(ent->s.angles, vec3_origin))
|
||||||
G_SetMovedir (ent->s.angles, ent->movedir);
|
{
|
||||||
|
G_SetMovedir(ent->s.angles, ent->movedir);
|
||||||
|
}
|
||||||
|
|
||||||
gi.setmodel (ent, ent->model);
|
gi.setmodel(ent, ent->model);
|
||||||
gi.linkentity (ent);
|
gi.linkentity(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QUAKED trigger_once (.5 .5 .5) ? x x TRIGGERED
|
||||||
|
* Triggers 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
|
||||||
|
*/
|
||||||
|
|
||||||
/*QUAKED trigger_once (.5 .5 .5) ? x x TRIGGERED
|
void
|
||||||
Triggers once, then removes itself.
|
SP_trigger_once(edict_t *ent)
|
||||||
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
|
/* 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
|
triggered was on bit 1 when it should have been on bit 4 */
|
||||||
if (ent->spawnflags & 1)
|
if (ent->spawnflags & 1)
|
||||||
{
|
{
|
||||||
vec3_t v;
|
vec3_t v;
|
||||||
|
|
||||||
VectorMA (ent->mins, 0.5, ent->size, v);
|
VectorMA(ent->mins, 0.5, ent->size, v);
|
||||||
ent->spawnflags &= ~1;
|
ent->spawnflags &= ~1;
|
||||||
ent->spawnflags |= 4;
|
ent->spawnflags |= 4;
|
||||||
gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v));
|
gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
ent->wait = -1;
|
ent->wait = -1;
|
||||||
SP_trigger_multiple (ent);
|
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.
|
* 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 *other, edict_t *activator)
|
*/
|
||||||
|
void
|
||||||
|
trigger_relay_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||||
{
|
{
|
||||||
G_UseTargets (self, activator);
|
G_UseTargets(self, activator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_relay (edict_t *self)
|
void
|
||||||
|
SP_trigger_relay(edict_t *self)
|
||||||
{
|
{
|
||||||
self->use = trigger_relay_use;
|
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.
|
||||||
trigger_key
|
* Use "item" to specify the required key, for example "key_data_cd"
|
||||||
|
*/
|
||||||
==============================================================================
|
void
|
||||||
*/
|
trigger_key_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||||
|
|
||||||
/*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 *other, edict_t *activator)
|
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
if (!self->item)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keyuse.wav"), 1, ATTN_NORM, 0);
|
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)
|
if (coop->value)
|
||||||
{
|
{
|
||||||
int player;
|
int player;
|
||||||
|
@ -240,15 +294,27 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||||
int cube;
|
int cube;
|
||||||
|
|
||||||
for (cube = 0; cube < 8; cube++)
|
for (cube = 0; cube < 8; cube++)
|
||||||
|
{
|
||||||
if (activator->client->pers.power_cubes & (1 << cube))
|
if (activator->client->pers.power_cubes & (1 << cube))
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (player = 1; player <= game.maxclients; player++)
|
for (player = 1; player <= game.maxclients; player++)
|
||||||
{
|
{
|
||||||
ent = &g_edicts[player];
|
ent = &g_edicts[player];
|
||||||
|
|
||||||
if (!ent->inuse)
|
if (!ent->inuse)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ent->client)
|
if (!ent->client)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ent->client->pers.power_cubes & (1 << cube))
|
if (ent->client->pers.power_cubes & (1 << cube))
|
||||||
{
|
{
|
||||||
ent->client->pers.inventory[index]--;
|
ent->client->pers.inventory[index]--;
|
||||||
|
@ -261,10 +327,17 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||||
for (player = 1; player <= game.maxclients; player++)
|
for (player = 1; player <= game.maxclients; player++)
|
||||||
{
|
{
|
||||||
ent = &g_edicts[player];
|
ent = &g_edicts[player];
|
||||||
|
|
||||||
if (!ent->inuse)
|
if (!ent->inuse)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ent->client)
|
if (!ent->client)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ent->client->pers.inventory[index] = 0;
|
ent->client->pers.inventory[index] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,324 +347,409 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator)
|
||||||
activator->client->pers.inventory[index]--;
|
activator->client->pers.inventory[index]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_UseTargets (self, activator);
|
G_UseTargets(self, activator);
|
||||||
|
|
||||||
self->use = NULL;
|
self->use = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_key (edict_t *self)
|
void
|
||||||
|
SP_trigger_key(edict_t *self)
|
||||||
{
|
{
|
||||||
if (!st.item)
|
if (!st.item)
|
||||||
{
|
{
|
||||||
gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));
|
gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->item = FindItemByClassname (st.item);
|
|
||||||
|
self->item = FindItemByClassname(st.item);
|
||||||
|
|
||||||
if (!self->item)
|
if (!self->item)
|
||||||
{
|
{
|
||||||
gi.dprintf("item %s not found for trigger_key at %s\n", st.item, vtos(self->s.origin));
|
gi.dprintf("item %s not found for trigger_key at %s\n", st.item,
|
||||||
|
vtos(self->s.origin));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->target)
|
if (!self->target)
|
||||||
{
|
{
|
||||||
gi.dprintf("%s at %s has no target\n", self->classname, vtos(self->s.origin));
|
gi.dprintf("%s at %s has no target\n", self->classname,
|
||||||
|
vtos(self->s.origin));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gi.soundindex ("misc/keytry.wav");
|
gi.soundindex("misc/keytry.wav");
|
||||||
gi.soundindex ("misc/keyuse.wav");
|
gi.soundindex("misc/keyuse.wav");
|
||||||
|
|
||||||
self->use = trigger_key_use;
|
self->use = trigger_key_use;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================================
|
||||||
|
*
|
||||||
|
* trigger_counter
|
||||||
|
*
|
||||||
|
* ==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
* QUAKED trigger_counter (.5 .5 .5) ? nomessage
|
||||||
|
* Acts as an intermediary for an action that takes multiple inputs.
|
||||||
trigger_counter
|
*
|
||||||
|
* 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
|
||||||
/*QUAKED trigger_counter (.5 .5 .5) ? nomessage
|
* will fire all of it's targets and remove itself.
|
||||||
Acts as an intermediary for an action that takes multiple inputs.
|
*/
|
||||||
|
void
|
||||||
If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
|
trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||||
|
|
||||||
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 *other, edict_t *activator)
|
|
||||||
{
|
{
|
||||||
if (self->count == 0)
|
if (self->count == 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self->count--;
|
self->count--;
|
||||||
|
|
||||||
if (self->count)
|
if (self->count)
|
||||||
{
|
{
|
||||||
if (! (self->spawnflags & 1))
|
if (!(self->spawnflags & 1))
|
||||||
{
|
{
|
||||||
gi.centerprintf(activator, "%i more to go...", self->count);
|
gi.centerprintf(activator, "%i more to go...", self->count);
|
||||||
gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (self->spawnflags & 1))
|
if (!(self->spawnflags & 1))
|
||||||
{
|
{
|
||||||
gi.centerprintf(activator, "Sequence completed!");
|
gi.centerprintf(activator, "Sequence completed!");
|
||||||
gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->activator = activator;
|
self->activator = activator;
|
||||||
multi_trigger (self);
|
multi_trigger(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_counter (edict_t *self)
|
void
|
||||||
|
SP_trigger_counter(edict_t *self)
|
||||||
{
|
{
|
||||||
self->wait = -1;
|
self->wait = -1;
|
||||||
|
|
||||||
if (!self->count)
|
if (!self->count)
|
||||||
|
{
|
||||||
self->count = 2;
|
self->count = 2;
|
||||||
|
}
|
||||||
|
|
||||||
self->use = trigger_counter_use;
|
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.
|
||||||
trigger_always
|
*/
|
||||||
|
void
|
||||||
==============================================================================
|
SP_trigger_always(edict_t *ent)
|
||||||
*/
|
|
||||||
|
|
||||||
/*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
|
/* we must have some delay to make sure our use targets are present */
|
||||||
if (ent->delay < 0.2)
|
if (ent->delay < 0.2)
|
||||||
|
{
|
||||||
ent->delay = 0.2;
|
ent->delay = 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
G_UseTargets(ent, ent);
|
G_UseTargets(ent, ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
* ==============================================================================
|
||||||
|
*
|
||||||
trigger_push
|
* trigger_push
|
||||||
|
*
|
||||||
==============================================================================
|
* ==============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PUSH_ONCE 1
|
#define PUSH_ONCE 1
|
||||||
|
|
||||||
static int windsound;
|
static int windsound;
|
||||||
|
|
||||||
void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
void
|
||||||
|
trigger_push_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||||
|
csurface_t *surf)
|
||||||
{
|
{
|
||||||
if (strcmp(other->classname, "grenade") == 0)
|
if (strcmp(other->classname, "grenade") == 0)
|
||||||
{
|
{
|
||||||
VectorScale (self->movedir, self->speed * 10, other->velocity);
|
VectorScale(self->movedir, self->speed * 10, other->velocity);
|
||||||
}
|
}
|
||||||
else if (other->health > 0)
|
else if (other->health > 0)
|
||||||
{
|
{
|
||||||
VectorScale (self->movedir, self->speed * 10, other->velocity);
|
VectorScale(self->movedir, self->speed * 10, other->velocity);
|
||||||
|
|
||||||
if (other->client)
|
if (other->client)
|
||||||
{
|
{
|
||||||
// don't take falling damage immediately from this
|
/* don't take falling damage immediately from this */
|
||||||
VectorCopy (other->velocity, other->client->oldvelocity);
|
VectorCopy(other->velocity, other->client->oldvelocity);
|
||||||
|
|
||||||
if (other->fly_sound_debounce_time < level.time)
|
if (other->fly_sound_debounce_time < level.time)
|
||||||
{
|
{
|
||||||
other->fly_sound_debounce_time = level.time + 1.5;
|
other->fly_sound_debounce_time = level.time + 1.5;
|
||||||
gi.sound (other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);
|
gi.sound(other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->spawnflags & PUSH_ONCE)
|
if (self->spawnflags & PUSH_ONCE)
|
||||||
G_FreeEdict (self);
|
{
|
||||||
|
G_FreeEdict(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
|
|
||||||
Pushes the player
|
|
||||||
"speed" defaults to 1000
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
* QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
|
||||||
|
* Pushes the player
|
||||||
trigger_hurt
|
* "speed" defaults to 1000
|
||||||
|
*/
|
||||||
==============================================================================
|
void
|
||||||
*/
|
SP_trigger_push(edict_t *self)
|
||||||
|
|
||||||
/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW
|
|
||||||
Any entity that touches this will be hurt.
|
|
||||||
|
|
||||||
It does dmg points of damage each server frame
|
|
||||||
|
|
||||||
SILENT supresses playing the sound
|
|
||||||
SLOW changes the damage rate to once per second
|
|
||||||
NO_PROTECTION *nothing* stops the damage
|
|
||||||
|
|
||||||
"dmg" default 5 (whole numbers only)
|
|
||||||
|
|
||||||
*/
|
|
||||||
void hurt_use (edict_t *self, edict_t *other, edict_t *activator)
|
|
||||||
{
|
{
|
||||||
if (self->solid == SOLID_NOT)
|
InitTrigger(self);
|
||||||
self->solid = SOLID_TRIGGER;
|
windsound = gi.soundindex("misc/windfly.wav");
|
||||||
else
|
self->touch = trigger_push_touch;
|
||||||
self->solid = SOLID_NOT;
|
|
||||||
gi.linkentity (self);
|
|
||||||
|
|
||||||
if (!(self->spawnflags & 2))
|
if (!self->speed)
|
||||||
self->use = NULL;
|
{
|
||||||
|
self->speed = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
gi.linkentity(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================================
|
||||||
|
*
|
||||||
|
* trigger_hurt
|
||||||
|
*
|
||||||
|
* ==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
/*
|
||||||
|
* QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW
|
||||||
|
* Any entity that touches this will be hurt.
|
||||||
|
*
|
||||||
|
* It does dmg points of damage each server frame
|
||||||
|
*
|
||||||
|
* SILENT supresses playing the sound
|
||||||
|
* SLOW changes the damage rate to once per second
|
||||||
|
* NO_PROTECTION *nothing* stops the damage
|
||||||
|
*
|
||||||
|
* "dmg" default 5 (whole numbers only)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
hurt_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||||
|
{
|
||||||
|
if (self->solid == SOLID_NOT)
|
||||||
|
{
|
||||||
|
self->solid = SOLID_TRIGGER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->solid = SOLID_NOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
gi.linkentity(self);
|
||||||
|
|
||||||
|
if (!(self->spawnflags & 2))
|
||||||
|
{
|
||||||
|
self->use = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hurt_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||||
{
|
{
|
||||||
int dflags;
|
int dflags;
|
||||||
|
|
||||||
if (!other->takedamage)
|
if (!other->takedamage)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->timestamp > level.time)
|
if (self->timestamp > level.time)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->spawnflags & 16)
|
if (self->spawnflags & 16)
|
||||||
|
{
|
||||||
self->timestamp = level.time + 1;
|
self->timestamp = level.time + 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
self->timestamp = level.time + FRAMETIME;
|
self->timestamp = level.time + FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(self->spawnflags & 4))
|
if (!(self->spawnflags & 4))
|
||||||
{
|
{
|
||||||
if ((level.framenum % 10) == 0)
|
if ((level.framenum % 10) == 0)
|
||||||
gi.sound (other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0);
|
{
|
||||||
|
gi.sound(other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->spawnflags & 8)
|
if (self->spawnflags & 8)
|
||||||
|
{
|
||||||
dflags = DAMAGE_NO_PROTECTION;
|
dflags = DAMAGE_NO_PROTECTION;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dflags = 0;
|
dflags = 0;
|
||||||
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT);
|
}
|
||||||
|
|
||||||
|
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin,
|
||||||
|
self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_hurt (edict_t *self)
|
void
|
||||||
|
SP_trigger_hurt(edict_t *self)
|
||||||
{
|
{
|
||||||
InitTrigger (self);
|
InitTrigger(self);
|
||||||
|
|
||||||
self->noise_index = gi.soundindex ("world/electro.wav");
|
self->noise_index = gi.soundindex("world/electro.wav");
|
||||||
self->touch = hurt_touch;
|
self->touch = hurt_touch;
|
||||||
|
|
||||||
if (!self->dmg)
|
if (!self->dmg)
|
||||||
|
{
|
||||||
self->dmg = 5;
|
self->dmg = 5;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->spawnflags & 1)
|
if (self->spawnflags & 1)
|
||||||
|
{
|
||||||
self->solid = SOLID_NOT;
|
self->solid = SOLID_NOT;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
self->solid = SOLID_TRIGGER;
|
self->solid = SOLID_TRIGGER;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->spawnflags & 2)
|
if (self->spawnflags & 2)
|
||||||
|
{
|
||||||
self->use = hurt_use;
|
self->use = hurt_use;
|
||||||
|
}
|
||||||
|
|
||||||
gi.linkentity (self);
|
gi.linkentity(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================================
|
||||||
|
*
|
||||||
|
* trigger_gravity
|
||||||
|
*
|
||||||
|
* ==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
* QUAKED trigger_gravity (.5 .5 .5) ?
|
||||||
|
* Changes the touching entites gravity to
|
||||||
|
* the value of "gravity". 1.0 is standard
|
||||||
|
* gravity for the level.
|
||||||
|
*/
|
||||||
|
|
||||||
trigger_gravity
|
void
|
||||||
|
trigger_gravity_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||||
==============================================================================
|
csurface_t *surf)
|
||||||
*/
|
|
||||||
|
|
||||||
/*QUAKED trigger_gravity (.5 .5 .5) ?
|
|
||||||
Changes the touching entites gravity to
|
|
||||||
the value of "gravity". 1.0 is standard
|
|
||||||
gravity for the level.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void trigger_gravity_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|
||||||
{
|
{
|
||||||
other->gravity = self->gravity;
|
other->gravity = self->gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_gravity (edict_t *self)
|
void
|
||||||
|
SP_trigger_gravity(edict_t *self)
|
||||||
{
|
{
|
||||||
if (st.gravity == 0)
|
if (st.gravity == 0)
|
||||||
{
|
{
|
||||||
gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin));
|
gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin));
|
||||||
G_FreeEdict (self);
|
G_FreeEdict(self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitTrigger (self);
|
InitTrigger(self);
|
||||||
self->gravity = atoi(st.gravity);
|
self->gravity = atoi(st.gravity);
|
||||||
self->touch = trigger_gravity_touch;
|
self->touch = trigger_gravity_touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================================
|
||||||
|
*
|
||||||
|
* trigger_monsterjump
|
||||||
|
*
|
||||||
|
* ==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
* QUAKED trigger_monsterjump (.5 .5 .5) ?
|
||||||
|
* Walking monsters that touch this will jump in the direction of the trigger's angle
|
||||||
trigger_monsterjump
|
* "speed" default to 200, the speed thrown forward
|
||||||
|
* "height" default to 200, the speed thrown upwards
|
||||||
==============================================================================
|
*/
|
||||||
*/
|
void
|
||||||
|
trigger_monsterjump_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||||
/*QUAKED trigger_monsterjump (.5 .5 .5) ?
|
csurface_t *surf)
|
||||||
Walking monsters that touch this will jump in the direction of the trigger's angle
|
|
||||||
"speed" default to 200, the speed thrown forward
|
|
||||||
"height" default to 200, the speed thrown upwards
|
|
||||||
*/
|
|
||||||
|
|
||||||
void trigger_monsterjump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|
||||||
{
|
{
|
||||||
if (other->flags & (FL_FLY | FL_SWIM) )
|
if (other->flags & (FL_FLY | FL_SWIM))
|
||||||
return;
|
{
|
||||||
if (other->svflags & SVF_DEADMONSTER)
|
|
||||||
return;
|
|
||||||
if ( !(other->svflags & SVF_MONSTER))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// set XY even if not on ground, so the jump will clear lips
|
if (other->svflags & SVF_DEADMONSTER)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(other->svflags & SVF_MONSTER))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set XY even if not on ground, so the jump will clear lips */
|
||||||
other->velocity[0] = self->movedir[0] * self->speed;
|
other->velocity[0] = self->movedir[0] * self->speed;
|
||||||
other->velocity[1] = self->movedir[1] * self->speed;
|
other->velocity[1] = self->movedir[1] * self->speed;
|
||||||
|
|
||||||
if (!other->groundentity)
|
if (!other->groundentity)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
other->groundentity = NULL;
|
other->groundentity = NULL;
|
||||||
other->velocity[2] = self->movedir[2];
|
other->velocity[2] = self->movedir[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SP_trigger_monsterjump (edict_t *self)
|
void
|
||||||
|
SP_trigger_monsterjump(edict_t *self)
|
||||||
{
|
{
|
||||||
if (!self->speed)
|
if (!self->speed)
|
||||||
|
{
|
||||||
self->speed = 200;
|
self->speed = 200;
|
||||||
|
}
|
||||||
|
|
||||||
if (!st.height)
|
if (!st.height)
|
||||||
|
{
|
||||||
st.height = 200;
|
st.height = 200;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->s.angles[YAW] == 0)
|
if (self->s.angles[YAW] == 0)
|
||||||
|
{
|
||||||
self->s.angles[YAW] = 360;
|
self->s.angles[YAW] = 360;
|
||||||
InitTrigger (self);
|
}
|
||||||
|
|
||||||
|
InitTrigger(self);
|
||||||
self->touch = trigger_monsterjump_touch;
|
self->touch = trigger_monsterjump_touch;
|
||||||
self->movedir[2] = st.height;
|
self->movedir[2] = st.height;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue