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;
activator = act;
self = stemp;
other = otemp;
-};
+}
//=============================================================================
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
}
-};
+}
// the trigger was just touched/killed/used
// called wheil C code is looping through area links...
self.touch = SUB_Null;
}
-};
+}
void multi_use()
{
self.goalentity = other;
self.enemy = activator;
multi_trigger();
-};
+}
void multi_touch()
{
self.enemy = other;
self.goalentity = other;
multi_trigger ();
-};
+}
void multi_eventdamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
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()
{
centerprint(activator, "Sequence completed!");
self.enemy = activator;
multi_trigger ();
-};
+}
void counter_reset()
{
self.use = counter_use;
self.reset = counter_reset;
-};
+}
void trigger_hurt_use()
{
Damage (other, self, own, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
}
}
+ else if(other.damagedbytriggers)
+ {
+ if(other.takedamage)
+ {
+ EXACTTRIGGER_TOUCH;
+ Damage(other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
+ }
+ }
else
{
if (!other.owner)
{
- 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
+ if (other.classname == "rune") // reset runes
{
EXACTTRIGGER_TOUCH;
other.nextthink = min(other.nextthink, time + 1);
}
return;
-};
+}
/*QUAKED spawnfunc_trigger_hurt (.5 .5 .5) ?
Any object touching this will be hurt
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)
{
if (other.iscreature)
{
if (other.takedamage)
+ if (!other.deadflag)
if (other.triggerhealtime < time)
{
EXACTTRIGGER_TOUCH;
}
}
}
-};
+}
void spawnfunc_trigger_heal()
{
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()
{
sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM);
UpdateCSQCProjectile(self.owner);
}
-};
+}
void spawnfunc_trigger_gravity()
{
if(self.spawnflags & 2)
self.state = FALSE;
}
-};
+}
//=============================================================================
ambientsound (self.origin, self.noise, VOL_BASE * self.volume, self.atten);
remove(self);
}
-};
+}
void spawnfunc_func_stardust() {
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);
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)
self.state = 0;
self.use = multivibrator_toggle;
self.think = multivibrator_send;
- self.nextthink = time;
+ self.nextthink = max(1, time);
IFTARGETED
multivibrator_reset();
}
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 = ((source.classname == "player") && (source.deadflag == DEAD_NO) && ((ear.radius == 0) || (vlen(source.origin - ear.origin) <= ear.radius)));
domatch = ((ear.spawnflags & 32) || dotrigger);
+
if not(domatch)
return msgin;
+ if not(msgin)
+ {
+ // we are in TUBA mode!
+ if not(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 & 4)
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;
}
// 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()
localcmd("endmatch\n");
else
localcmd(strcat("changelevel ", self.chmap, "\n"));
-};
+}
void spawnfunc_target_changelevel()
{
self.use = spawnfunc_target_changelevel_use;
-};
+}