]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/triggers/triggers.qc
Properly support team field on trigger_multiple
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / triggers.qc
index cd1d0260c01c8d2836f6e1fc369ae1208591e0a2..2a76d80c41a7a7f41675d9a06826b2e236683d28 100644 (file)
@@ -1,12 +1,12 @@
-void SUB_DontUseTargets() { }
+#include "triggers.qh"
+void SUB_DontUseTargets(entity this, entity actor, entity trigger) { }
 
-void() SUB_UseTargets;
+void SUB_UseTargets(entity this, entity actor, entity trigger);
 
-void DelayThink()
-{SELFPARAM();
-       activator = self.enemy;
-       SUB_UseTargets ();
-       remove(self);
+void DelayThink(entity this)
+{
+       SUB_UseTargets (this, this.enemy, NULL);
+       delete(this);
 }
 
 void FixSize(entity e)
@@ -22,28 +22,33 @@ void FixSize(entity e)
 
 #ifdef SVQC
 
+bool autocvar_g_triggers_debug = true;
+
 void trigger_init(entity this)
 {
        string m = this.model;
-       WITH(entity, self, this, WarpZoneLib_ExactTrigger_Init());
-       if(m != "")
-       {
-               precache_model(m);
-               _setmodel(this, m); // no precision needed
+       EXACTTRIGGER_INIT;
+       if(autocvar_g_triggers_debug)
+       {
+               if(m != "")
+               {
+                       precache_model(m);
+                       _setmodel(this, m); // no precision needed
+               }
+               setorigin(this, this.origin);
+               if(this.scale)
+                       setsize(this, this.mins * this.scale, this.maxs * this.scale);
+               else
+                       setsize(this, this.mins, this.maxs);
        }
-       setorigin(this, this.origin);
-       if(this.scale)
-               setsize(this, this.mins * this.scale, this.maxs * this.scale);
-       else
-               setsize(this, this.mins, this.maxs);
 
-       BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
+       if(autocvar_g_triggers_debug)
+               BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
 }
 
 void trigger_link(entity this, bool(entity this, entity to, int sendflags) sendfunc)
 {
-       this.SendEntity = SendEntity_self;
-       this.SendEntity3 = sendfunc;
+       setSendEntity(this, sendfunc);
        this.SendFlags = 0xFFFFFF;
 }
 
@@ -93,157 +98,155 @@ void trigger_common_write(entity this, bool withtarget)
 
 #elif defined(CSQC)
 
-void trigger_common_read(bool withtarget)
-{SELFPARAM();
+void trigger_common_read(entity this, bool withtarget)
+{
        int f = ReadByte();
-       self.warpzone_isboxy = (f & 1);
+       this.warpzone_isboxy = (f & 1);
 
        if(withtarget)
        {
-               if(self.target) { strunzone(self.target); }
-               self.target = strzone(ReadString());
-               if(self.target2) { strunzone(self.target2); }
-               self.target2 = strzone(ReadString());
-               if(self.target3) { strunzone(self.target3); }
-               self.target3 = strzone(ReadString());
-               if(self.target4) { strunzone(self.target4); }
-               self.target4 = strzone(ReadString());
-               if(self.targetname) { strunzone(self.targetname); }
-               self.targetname = strzone(ReadString());
-               if(self.killtarget) { strunzone(self.killtarget); }
-               self.killtarget = strzone(ReadString());
+               if(this.target) { strunzone(this.target); }
+               this.target = strzone(ReadString());
+               if(this.target2) { strunzone(this.target2); }
+               this.target2 = strzone(ReadString());
+               if(this.target3) { strunzone(this.target3); }
+               this.target3 = strzone(ReadString());
+               if(this.target4) { strunzone(this.target4); }
+               this.target4 = strzone(ReadString());
+               if(this.targetname) { strunzone(this.targetname); }
+               this.targetname = strzone(ReadString());
+               if(this.killtarget) { strunzone(this.killtarget); }
+               this.killtarget = strzone(ReadString());
        }
 
        if(f & 4)
        {
-               self.origin_x = ReadCoord();
-               self.origin_y = ReadCoord();
-               self.origin_z = ReadCoord();
+               this.origin_x = ReadCoord();
+               this.origin_y = ReadCoord();
+               this.origin_z = ReadCoord();
        }
        else
-               self.origin = '0 0 0';
-       setorigin(self, self.origin);
-
-       self.modelindex = ReadShort();
-       self.mins_x = ReadCoord();
-       self.mins_y = ReadCoord();
-       self.mins_z = ReadCoord();
-       self.maxs_x = ReadCoord();
-       self.maxs_y = ReadCoord();
-       self.maxs_z = ReadCoord();
-       self.scale = ReadByte() / 16;
-       setsize(self, self.mins, self.maxs);
-
-       self.movedir_x = ReadCoord();
-       self.movedir_y = ReadCoord();
-       self.movedir_z = ReadCoord();
-
-       self.angles_x = ReadCoord();
-       self.angles_y = ReadCoord();
-       self.angles_z = ReadCoord();
+               this.origin = '0 0 0';
+       setorigin(this, this.origin);
+
+       this.modelindex = ReadShort();
+       this.mins_x = ReadCoord();
+       this.mins_y = ReadCoord();
+       this.mins_z = ReadCoord();
+       this.maxs_x = ReadCoord();
+       this.maxs_y = ReadCoord();
+       this.maxs_z = ReadCoord();
+       this.scale = ReadByte() / 16;
+       setsize(this, this.mins, this.maxs);
+
+       this.movedir_x = ReadCoord();
+       this.movedir_y = ReadCoord();
+       this.movedir_z = ReadCoord();
+
+       this.angles_x = ReadCoord();
+       this.angles_y = ReadCoord();
+       this.angles_z = ReadCoord();
 }
 
-void trigger_remove_generic()
-{SELFPARAM();
-       if(self.target) { strunzone(self.target); }
-       self.target = string_null;
+void trigger_remove_generic(entity this)
+{
+       if(this.target) { strunzone(this.target); }
+       this.target = string_null;
 
-       if(self.target2) { strunzone(self.target2); }
-       self.target2 = string_null;
+       if(this.target2) { strunzone(this.target2); }
+       this.target2 = string_null;
 
-       if(self.target3) { strunzone(self.target3); }
-       self.target3 = string_null;
+       if(this.target3) { strunzone(this.target3); }
+       this.target3 = string_null;
 
-       if(self.target4) { strunzone(self.target4); }
-       self.target4 = string_null;
+       if(this.target4) { strunzone(this.target4); }
+       this.target4 = string_null;
 
-       if(self.targetname) { strunzone(self.targetname); }
-       self.target = string_null;
+       if(this.targetname) { strunzone(this.targetname); }
+       this.target = string_null;
 
-       if(self.killtarget) { strunzone(self.killtarget); }
-       self.killtarget = string_null;
+       if(this.killtarget) { strunzone(this.killtarget); }
+       this.killtarget = string_null;
 }
 #endif
 
+
 /*
 ==============================
 SUB_UseTargets
 
 the global "activator" should be set to the entity that initiated the firing.
 
-If self.delay is set, a DelayedUse entity will be created that will actually
+If this.delay is set, a DelayedUse entity will be created that will actually
 do the SUB_UseTargets after that many seconds have passed.
 
-Centerprints any self.message to the activator.
+Centerprints any this.message to the activator.
 
-Removes all entities with a targetname that match self.killtarget,
+Removes all entities with a targetname that match this.killtarget,
 and removes them, so some events can remove other triggers.
 
 Search for (string)targetname in all entities that
-match (string)self.target and call their .use function
+match (string)this.target and call their .use function
 
 ==============================
 */
-void SUB_UseTargets()
-{SELFPARAM();
-       entity t, otemp, act;
-       string s;
-       float i;
 
+void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse)
+{
 //
 // check for a delay
 //
-       if (self.delay)
+       if (this.delay)
        {
        // create a temp object to fire at a later time
-               t = new(DelayedUse);
-               t.nextthink = time + self.delay;
-               t.think = DelayThink;
-               t.enemy = activator;
-               t.message = self.message;
-               t.killtarget = self.killtarget;
-               t.target = self.target;
-               t.target2 = self.target2;
-               t.target3 = self.target3;
-               t.target4 = self.target4;
+               entity t = new(DelayedUse);
+               t.nextthink = time + this.delay;
+               setthink(t, DelayThink);
+               t.enemy = actor;
+               t.message = this.message;
+               t.killtarget = this.killtarget;
+               t.target = this.target;
+               t.target2 = this.target2;
+               t.target3 = this.target3;
+               t.target4 = this.target4;
+               t.antiwall_flag = this.antiwall_flag;
                return;
        }
 
+       string s;
 
 //
 // print the message
 //
 #ifdef SVQC
-       if(self)
-       if(IS_PLAYER(activator) && self.message != "")
-       if(IS_REAL_CLIENT(activator))
+       if(this)
+       if(IS_PLAYER(actor) && this.message != "")
+       if(IS_REAL_CLIENT(actor))
        {
-               centerprint(activator, self.message);
-               if (self.noise == "")
-                       play2(activator, SND(TALK));
+               centerprint(actor, this.message);
+               if (this.noise == "")
+                       play2(actor, SND(TALK));
        }
 
 //
 // kill the killtagets
 //
-       s = self.killtarget;
+       s = this.killtarget;
        if (s != "")
        {
-               for(t = world; (t = find(t, targetname, s)); )
-                       remove(t);
+               for(entity t = NULL; (t = find(t, targetname, s)); )
+                       delete(t);
        }
 #endif
 
 //
 // fire targets
 //
-       act = activator;
-       otemp = other;
 
        if(this.target_random)
                RandomSelection_Init();
 
-       for(i = 0; i < 4; ++i)
+       for(int i = 0; i < 4; ++i)
        {
                switch(i)
                {
@@ -257,22 +260,24 @@ void SUB_UseTargets()
                {
                        // Flag to set func_clientwall state
                        // 1 == deactivate, 2 == activate, 0 == do nothing
-                       float aw_flag = self.antiwall_flag;
-                       for(t = world; (t = find(t, targetname, s)); )
-                       if(t.use)
+                       int aw_flag = this.antiwall_flag;
+                       for(entity t = NULL; (t = find(t, targetname, s)); )
                        {
-                               if(this.target_random)
+                               if(t.use && (t.sub_target_used != time || !preventReuse))
                                {
-                                       RandomSelection_Add(t, 0, string_null, 1, 0);
-                               }
-                               else
-                               {
-                                       if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
-                                               t.antiwall_flag = aw_flag;
-                                       setself(t);
-                                       other = this;
-                                       activator = act;
-                                       self.use();
+                                       if(this.target_random)
+                                       {
+                                               RandomSelection_AddEnt(t, 1, 0);
+                                       }
+                                       else
+                                       {
+                                               if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
+                                                       t.antiwall_flag = aw_flag;
+
+                                               t.use(t, actor, this);
+                                               if(preventReuse)
+                                                       t.sub_target_used = time;
+                                       }
                                }
                        }
                }
@@ -280,44 +285,16 @@ void SUB_UseTargets()
 
        if(this.target_random && RandomSelection_chosen_ent)
        {
-               setself(RandomSelection_chosen_ent);
-               other = this;
-               activator = act;
-               self.use();
+               RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this);
+               if(preventReuse)
+                       RandomSelection_chosen_ent.sub_target_used = time;
        }
-
-       activator = act;
-       setself(this);
-       other = otemp;
 }
 
-#ifdef CSQC
-void trigger_touch_generic(void() touchfunc)
-{SELFPARAM();
-       entity e;
-       for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
-       if(e.isplayermodel || e.classname == "csqcprojectile")
-       {
-               vector emin = e.absmin, emax = e.absmax;
-               if(self.solid == SOLID_BSP)
-               {
-                       emin -= '1 1 1';
-                       emax += '1 1 1';
-               }
-               if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
-               if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
-               {
-                       other = e;
-                       touchfunc();
-               }
-       }
-}
-void trigger_draw_generic(entity this)
-{
-       float dt = time - self.move_time;
-       self.move_time = time;
-       if(dt <= 0) { return; }
+void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); }
+void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); }
 
-       if(self.trigger_touch) { trigger_touch_generic(self.trigger_touch); }
+void SUB_UseTargets_self(entity this)
+{
+       SUB_UseTargets(this, NULL, NULL);
 }
-#endif