activator = self.enemy;
SUB_UseTargets ();
remove(self);
-};
+}
/*
==============================
*/
void SUB_UseTargets()
{
- local entity t, stemp, otemp, act;
+ entity t, stemp, otemp, act;
string s;
float i;
//
// print the message
//
- if (activator.classname == "player" && self.message != "")
+ if (IS_PLAYER(activator) && self.message != "")
{
- if(clienttype(activator) == CLIENTTYPE_REAL)
+ if(IS_REAL_CLIENT(activator))
{
centerprint (activator, self.message);
- if (!self.noise)
+ if (self.noise == "")
play2(activator, "misc/talk.wav");
}
}
activator = act;
self = stemp;
other = otemp;
-};
+}
//=============================================================================
-float SPAWNFLAG_NOMESSAGE = 1;
-float SPAWNFLAG_NOTOUCH = 1;
+const float SPAWNFLAG_NOMESSAGE = 1;
+const float SPAWNFLAG_NOTOUCH = 1;
// the wait time has passed, so set back up for another activation
void multi_wait()
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
}
-};
+}
// the trigger was just touched/killed/used
if (self.classname == "trigger_secret")
{
- if (self.enemy.classname != "player")
+ if (!IS_PLAYER(self.enemy))
return;
found_secrets = found_secrets + 1;
WriteByte (MSG_ALL, SVC_FOUNDSECRET);
}
if (self.noise)
- sound (self.enemy, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM);
+ sound (self.enemy, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
// don't trigger again until reset
self.takedamage = DAMAGE_NO;
else
{ // we can't just remove (self) here, because this is a touch function
// called wheil C code is looping through area links...
- self.touch = SUB_Null;
+ self.touch = func_null;
}
-};
+}
void multi_use()
{
self.goalentity = other;
self.enemy = activator;
multi_trigger();
-};
+}
void multi_touch()
{
- if not(self.spawnflags & 2)
- if not(other.iscreature)
+ if (!(self.spawnflags & 2))
+ if (!other.iscreature)
return;
if(self.team)
- if((self.spawnflags & 4 == 0) == (self.team != other.team))
+ if(((self.spawnflags & 4) == 0) == (self.team != other.team))
return;
// if the trigger has an angles field, check player's facing direction
self.enemy = other;
self.goalentity = other;
multi_trigger ();
-};
+}
void multi_eventdamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
}
- self.think = SUB_Null;
+ self.think = func_null;
+ self.nextthink = 0;
self.team = self.team_saved;
}
setorigin (self, self.origin); // make sure it links into the world
}
}
-};
+}
/*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
{
self.wait = -1;
spawnfunc_trigger_multiple();
-};
+}
//=============================================================================
{
self.use = SUB_UseTargets;
self.reset = spawnfunc_trigger_relay; // this spawnfunc resets fully
-};
+}
void delay_use()
{
void delay_reset()
{
- self.think = SUB_Null;
+ self.think = func_null;
+ self.nextthink = 0;
}
void spawnfunc_trigger_delay()
if (self.count != 0)
{
- if (activator.classname == "player"
+ if (IS_PLAYER(activator)
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
{
if (self.count >= 4)
return;
}
- if (activator.classname == "player"
+ if (IS_PLAYER(activator)
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
centerprint(activator, "Sequence completed!");
self.enemy = activator;
multi_trigger ();
-};
+}
void counter_reset()
{
self.use = counter_use;
self.reset = counter_reset;
-};
+}
void trigger_hurt_use()
{
- if(activator.classname == "player")
+ if(IS_PLAYER(activator))
self.enemy = activator;
else
self.enemy = world; // let's just destroy it, if taking over is too much work
.float triggerhurttime;
void trigger_hurt_touch()
{
- if (self.active != ACTIVE_ACTIVE)
+ if (self.active != ACTIVE_ACTIVE)
return;
if(self.team)
- if((self.spawnflags & 4 == 0) == (self.team != other.team))
+ if(((self.spawnflags & 4) == 0) == (self.team != other.team))
return;
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
entity own;
own = self.enemy;
- if(own.classname != "player")
+ if (!IS_PLAYER(own))
{
own = self;
self.enemy = world; // I still hate you all
Damage (other, self, own, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
}
}
- else
+ else if(other.damagedbytriggers)
{
- if (!other.owner)
+ if(other.takedamage)
{
- if (other.items & IT_KEY1 || other.items & IT_KEY2) // reset flag
- {
- EXACTTRIGGER_TOUCH;
- other.pain_finished = min(other.pain_finished, time + 2);
- }
- else if (other.classname == "rune") // reset runes
- {
- EXACTTRIGGER_TOUCH;
- other.nextthink = min(other.nextthink, time + 1);
- }
+ EXACTTRIGGER_TOUCH;
+ Damage(other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
}
}
return;
-};
+}
/*QUAKED spawnfunc_trigger_hurt (.5 .5 .5) ?
Any object touching this will be hurt
self.enemy = world; // I hate you all
if (!self.dmg)
self.dmg = 1000;
- if (!self.message)
+ if (self.message == "")
self.message = "was in the wrong place";
- if (!self.message2)
+ if (self.message2 == "")
self.message2 = "was thrown into a world of hurt by";
// self.message = "someone like %s always gets wrongplaced";
if(trigger_hurt_last)
trigger_hurt_last.trigger_hurt_next = self;
trigger_hurt_last = self;
-};
+}
float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end)
{
.float triggerhealtime;
void trigger_heal_touch()
{
- if (self.active != ACTIVE_ACTIVE)
+ if (self.active != ACTIVE_ACTIVE)
return;
-
+
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
if (other.iscreature)
{
if (other.takedamage)
+ if (!other.deadflag)
if (other.triggerhealtime < time)
{
EXACTTRIGGER_TOUCH;
other.triggerhealtime = time + 1;
-
+
if (other.health < self.max_health)
{
other.health = min(other.health + self.health, self.max_health);
other.pauserothealth_finished = max(other.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
- sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM);
+ sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
}
}
}
-};
+}
void spawnfunc_trigger_heal()
{
self.active = ACTIVE_ACTIVE;
-
+
EXACTTRIGGER_INIT;
self.touch = trigger_heal_touch;
if (!self.health)
if(self.noise == "")
self.noise = "misc/mediumhealth.wav";
precache_sound(self.noise);
-};
+}
//////////////////////////////////////////////////////////////
self.count -= 1;
self.nextthink = time;
}
-};
+}
void trigger_gravity_use()
{
self.state = !self.state;
-};
+}
void trigger_gravity_touch()
{
g = self.gravity;
- if not(self.spawnflags & 1)
+ if (!(self.spawnflags & 1))
{
if(other.trigger_gravity_check)
{
{
other.gravity = g;
if(self.noise != "")
- sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM);
+ sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
UpdateCSQCProjectile(self.owner);
}
-};
+}
void spawnfunc_trigger_gravity()
{
if(self.spawnflags & 2)
self.state = FALSE;
}
-};
+}
//=============================================================================
void target_speaker_use_off();
void target_speaker_use_activator()
{
- if(clienttype(activator) != CLIENTTYPE_REAL)
+ if (!IS_REAL_CLIENT(activator))
return;
string snd;
if(substring(self.noise, 0, 1) == "*")
else
snd = self.noise;
msg_entity = activator;
- soundto(MSG_ONE, self, CHAN_TRIGGER, snd, VOL_BASE * self.volume, self.atten);
+ soundto(MSG_ONE, self, CH_TRIGGER, snd, VOL_BASE * self.volume, self.atten);
}
void target_speaker_use_on()
{
}
else
snd = self.noise;
- sound(self, CHAN_TRIGGER, snd, VOL_BASE * self.volume, self.atten);
+ sound(self, CH_TRIGGER_SINGLE, snd, VOL_BASE * self.volume, self.atten);
if(self.spawnflags & 3)
self.use = target_speaker_use_off;
}
void target_speaker_use_off()
{
- sound(self, CHAN_TRIGGER, "misc/null.wav", VOL_BASE * self.volume, self.atten);
+ sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASE * self.volume, self.atten);
self.use = target_speaker_use_on;
}
void target_speaker_reset()
if(!self.atten && !(self.spawnflags & 4))
{
IFTARGETED
- self.atten = ATTN_NORM;
+ self.atten = ATTEN_NORM;
else
- self.atten = ATTN_STATIC;
+ self.atten = ATTEN_STATIC;
}
else if(self.atten < 0)
self.atten = 0;
ambientsound (self.origin, self.noise, VOL_BASE * self.volume, self.atten);
remove(self);
}
-};
+}
void spawnfunc_func_stardust() {
setmodel(self, self.model);
if(self.noise != "")
precache_sound (self.noise);
-
+
if(!self.bgmscriptsustain)
self.bgmscriptsustain = 1;
else if(self.bgmscriptsustain < 0)
self.bgmscriptsustain = 0;
if(!self.atten)
- self.atten = ATTN_NORM;
+ self.atten = ATTEN_NORM;
else if(self.atten < 0)
self.atten = 0;
if(!self.volume)
WriteShort(MSG_ENTITY, self.count);
WriteByte(MSG_ENTITY, self.cnt);
return 1;
-};
+}
/*QUAKED spawnfunc_func_rain (0 .5 .8) ?
This is an invisible area like a trigger, which rain falls inside of.
self.Version = 1;
Net_LinkEntity(self, FALSE, 0, rainsnow_SendEntity);
-};
+}
/*QUAKED spawnfunc_func_snow (0 .5 .8) ?
self.Version = 1;
Net_LinkEntity(self, FALSE, 0, rainsnow_SendEntity);
-};
+}
void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, float deathtype);
if(self.enemy)
{
o = self.enemy.origin;
- if not(self.spawnflags & 2)
+ if (!(self.spawnflags & 2))
o = self.origin + normalize(o - self.origin) * 32768;
}
else
if(self.dmg)
{
if(self.team)
- if((self.spawnflags & 8 == 0) == (self.team != hitent.team))
+ if(((self.spawnflags & 8) == 0) == (self.team != hitent.team))
return;
if(hitent.takedamage)
Damage(hitent, self, self, ((self.dmg < 0) ? 100000 : (self.dmg * frametime)), DEATH_HURTTRIGGER, hitloc, '0 0 0');
if(self.colormod == '0 0 0')
if(!self.alpha)
self.colormod = '1 0 0';
- if(!self.message)
+ if(self.message == "")
self.message = "saw the light";
- if (!self.message2)
+ if (self.message2 == "")
self.message2 = "was pushed into a laser by";
if(!self.scale)
self.scale = 1;
float pushdeltatime;
float str;
- if (self.active != ACTIVE_ACTIVE)
+ if (self.active != ACTIVE_ACTIVE)
return;
- // FIXME: Better checking for what to push and not.
- if not(other.iscreature)
- if (other.classname != "corpse")
- if (other.classname != "body")
- if (other.classname != "gib")
- if (other.classname != "missile")
- if (other.classname != "rocket")
- if (other.classname != "casing")
- if (other.classname != "grenade")
- if (other.classname != "plasma")
- if (other.classname != "plasma_prim")
- if (other.classname != "plasma_chain")
- if (other.classname != "droppedweapon")
- if (other.classname != "nexball_basketball")
- if (other.classname != "nexball_football")
- return;
-
- if (other.deadflag && other.iscreature)
+ if (!isPushable(other))
return;
EXACTTRIGGER_TOUCH;
return;
}
+ str = min(self.radius, vlen(self.origin - other.origin));
+
if(self.falloff == 1)
str = (str / self.radius) * self.strength;
else if(self.falloff == 2)
if(!pushdeltatime) return;
other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
- other.flags &~= FL_ONGROUND;
+ other.flags &= ~FL_ONGROUND;
UpdateCSQCProjectile(other);
}
{
float pushdeltatime;
- if (self.active != ACTIVE_ACTIVE)
+ if (self.active != ACTIVE_ACTIVE)
return;
- // FIXME: Better checking for what to push and not.
- if not(other.iscreature)
- if (other.classname != "corpse")
- if (other.classname != "body")
- if (other.classname != "gib")
- if (other.classname != "missile")
- if (other.classname != "rocket")
- if (other.classname != "casing")
- if (other.classname != "grenade")
- if (other.classname != "plasma")
- if (other.classname != "plasma_prim")
- if (other.classname != "plasma_chain")
- if (other.classname != "droppedweapon")
- if (other.classname != "nexball_basketball")
- if (other.classname != "nexball_football")
- return;
-
- if (other.deadflag && other.iscreature)
+ if (!isPushable(other))
return;
EXACTTRIGGER_TOUCH;
float pushdeltatime;
float str;
- if (self.active != ACTIVE_ACTIVE)
+ if (self.active != ACTIVE_ACTIVE)
return;
- // FIXME: Better checking for what to push and not.
- if not(other.iscreature)
- if (other.classname != "corpse")
- if (other.classname != "body")
- if (other.classname != "gib")
- if (other.classname != "missile")
- if (other.classname != "rocket")
- if (other.classname != "casing")
- if (other.classname != "grenade")
- if (other.classname != "plasma")
- if (other.classname != "plasma_prim")
- if (other.classname != "plasma_chain")
- if (other.classname != "droppedweapon")
- if (other.classname != "nexball_basketball")
- if (other.classname != "nexball_football")
- return;
-
- if (other.deadflag && other.iscreature)
+ if (!isPushable(other))
return;
EXACTTRIGGER_TOUCH;
self.state = 0;
self.use = multivibrator_toggle;
self.think = multivibrator_send;
- self.nextthink = time;
+ self.nextthink = max(1, time);
IFTARGETED
multivibrator_reset();
return;
if(vs.message == "")
return;
- if(pl.classname != "player")
+ if (!IS_PLAYER(pl))
return;
if(gameover)
return;
// added after this message
// wait: average time between messages
// delay: initial delay before the first message
-
+
float i, n;
self.use = target_voicescript_use;
}
float magicear_matched;
+float W_Tuba_HasPlayed(entity pl, string melody, float instrument, float ignorepitch, float mintempo, float maxtempo);
string trigger_magicear_processmessage(entity ear, entity source, float teamsay, entity privatesay, string msgin)
{
float domatch, dotrigger, matchstart, l;
string s, msg;
entity oldself;
+ string savemessage;
magicear_matched = FALSE;
- dotrigger = ((self.classname == "player") && (self.deadflag == DEAD_NO) && ((ear.radius == 0) || (vlen(source.origin - ear.origin) <= ear.radius)));
+ dotrigger = ((IS_PLAYER(source)) && (source.deadflag == DEAD_NO) && ((ear.radius == 0) || (vlen(source.origin - ear.origin) <= ear.radius)));
domatch = ((ear.spawnflags & 32) || dotrigger);
- if not(domatch)
+
+ if (!domatch)
+ return msgin;
+
+ if (!msgin)
+ {
+ // we are in TUBA mode!
+ if (!(ear.spawnflags & 256))
+ return msgin;
+
+ if(!W_Tuba_HasPlayed(source, ear.message, ear.movedir_x, !(ear.spawnflags & 512), ear.movedir_y, ear.movedir_z))
+ return msgin;
+
+ magicear_matched = TRUE;
+
+ if(dotrigger)
+ {
+ oldself = self;
+ activator = source;
+ self = ear;
+ savemessage = self.message;
+ self.message = string_null;
+ SUB_UseTargets();
+ self.message = savemessage;
+ self = oldself;
+ }
+
+ if(ear.netname != "")
+ return ear.netname;
+
+ return msgin;
+ }
+
+ if(ear.spawnflags & 256) // ENOTUBA
return msgin;
if(privatesay)
if(ear.spawnflags & 8)
return msgin;
}
-
+
matchstart = -1;
l = strlen(ear.message);
- if(self.spawnflags & 128)
+ if(ear.spawnflags & 128)
msg = msgin;
else
msg = strdecolorize(msgin);
if(dotrigger)
{
- oldself = activator = self;
+ oldself = self;
+ activator = source;
self = ear;
+ savemessage = self.message;
+ self.message = string_null;
SUB_UseTargets();
+ self.message = savemessage;
self = oldself;
}
for(ear = magicears; ear; ear = ear.enemy)
{
msgout = trigger_magicear_processmessage(ear, source, teamsay, privatesay, msgin);
- if not(ear.spawnflags & 64)
+ if (!(ear.spawnflags & 64))
if(magicear_matched)
return msgout;
msgin = msgout;
// actually handled in "say" processing
// spawnflags:
- // 1 = ignore say
- // 2 = ignore teamsay
- // 4 = ignore tell
- // 8 = ignore tell to unknown player
+ // 1 = ignore say
+ // 2 = ignore teamsay
+ // 4 = ignore tell
+ // 8 = ignore tell to unknown player
// 16 = let netname replace the whole message (otherwise, netname is a word replacement if set)
// 32 = perform the replacement even if outside the radius or dead
// 64 = continue replacing/triggering even if this one matched
+ // 128 = don't decolorize message before matching
+ // 256 = message is a tuba note sequence (pitch.duration pitch.duration ...)
+ // 512 = tuba notes must be exact right pitch, no transposing
// message: either
// *pattern*
// or
// "hearing distance"
// target:
// what to trigger
+ // movedir:
+ // for spawnflags 256, defines 'instrument+1 mintempo maxtempo' (zero component doesn't matter)
+
+ self.movedir_x -= 1; // map to tuba instrument numbers
}
void relay_activators_use()
{
entity trg, os;
-
+
os = self;
-
+
for(trg = world; (trg = find(trg, targetname, os.target)); )
{
self = trg;
if(os.cnt == ACTIVE_TOGGLE)
if(trg.active == ACTIVE_ACTIVE)
trg.active = ACTIVE_NOT;
- else
+ else
trg.active = ACTIVE_ACTIVE;
else
trg.active = os.cnt;
- }
+ }
}
self = os;
}
void spawnfunc_relay_deactivate()
{
self.cnt = ACTIVE_NOT;
- self.use = relay_activators_use;
+ self.use = relay_activators_use;
}
void spawnfunc_relay_activatetoggle()
{
self.cnt = ACTIVE_TOGGLE;
- self.use = relay_activators_use;
+ self.use = relay_activators_use;
}
.string chmap, gametype;
localcmd("endmatch\n");
else
localcmd(strcat("changelevel ", self.chmap, "\n"));
-};
+}
void spawnfunc_target_changelevel()
{
self.use = spawnfunc_target_changelevel_use;
-};
+}