]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/g_triggers.qc
Merge branch 'master' into tzork/ents-onoff
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_triggers.qc
index 1ef07d4904047691a19f4954a26f8eb5dde6fd2e..cecca06d2e030fe96375326099fdedb9f3948472 100644 (file)
@@ -462,6 +462,7 @@ void spawnfunc_trigger_hurt()
                self.message = "was in the wrong place";
        if (!self.message2)
                self.message2 = "was thrown into a world of hurt by";
+       // self.message = "someone like %s always gets wrongplaced";
 
        if(!trigger_hurt_first)
                trigger_hurt_first = self;
@@ -533,57 +534,113 @@ void spawnfunc_trigger_heal()
 //
 //////////////////////////////////////////////////////////////
 
-.float triggergravity, triggergravitytime;
 .entity trigger_gravity_check;
-void trigger_gravity_check_think()
+void trigger_gravity_remove(entity own)
 {
-       if(self.owner.triggergravitytime < time + 0.1) // need to figure out a correct formula here
+       if(own.trigger_gravity_check.owner == own)
        {
-               dprint("XXXXXXXXXXXXXXXXXXXXXXXXXX ");
-               self.owner.gravity = 0;
-               self.nextthink = self.owner.triggergravity = 0;
-               remove(self);
+               UpdateCSQCProjectile(own);
+               own.gravity = own.trigger_gravity_check.gravity;
+               remove(own.trigger_gravity_check);
        }
+       else
+               backtrace("Removing a trigger_gravity_check with no valid owner");
+       own.trigger_gravity_check = world;
 }
+void trigger_gravity_check_think()
+{
+       // This spawns when a player enters the gravity zone and checks if he left.
+       // Each frame, self.count is set to 2 by trigger_gravity_touch() and decreased by 1 here.
+       // It the player has left the gravity trigger, this will be allowed to reach 0 and indicate that.
+       if(self.count <= 0)
+       {
+               if(self.owner.trigger_gravity_check == self)
+                       trigger_gravity_remove(self.owner);
+               else
+                       remove(self);
+               return;
+       }
+       else
+       {
+               self.count -= 1;
+               self.nextthink = time;
+       }
+};
+
+void trigger_gravity_use()
+{
+       self.state = !self.state;
+};
 
 void trigger_gravity_touch()
 {
-       if(sv_gravity != 800)
+       float g;
+
+       if(self.state != TRUE)
                return;
-       // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
-       if (other.triggergravitytime < time)
-       {
-               EXACTTRIGGER_TOUCH;
-               other.triggergravitytime = time + 1;
 
-               if(!other.triggergravity)
-               {
-                       other.triggergravity = 1;
-                       other.trigger_gravity_check = spawn();
-                       other.trigger_gravity_check.owner = other;
-                       other.trigger_gravity_check.think = trigger_gravity_check_think;
-                       other.trigger_gravity_check.nextthink = time;
-               }
+       EXACTTRIGGER_TOUCH;
+
+       g = self.gravity;
 
-               if (other.gravity != self.gravity)
+       if not(self.spawnflags & 1)
+       {
+               if(other.trigger_gravity_check)
                {
-                       other.gravity = self.gravity;
-                       if(self.noise != "")
-                               sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM);
+                       if(self == other.trigger_gravity_check.enemy)
+                       {
+                               // same?
+                               other.trigger_gravity_check.count = 2; // gravity one more frame...
+                               return;
+                       }
+
+                       // compare prio
+                       if(self.cnt > other.trigger_gravity_check.enemy.cnt)
+                               trigger_gravity_remove(other);
+                       else
+                               return;
                }
+               other.trigger_gravity_check = spawn();
+               other.trigger_gravity_check.enemy = self;
+               other.trigger_gravity_check.owner = other;
+               other.trigger_gravity_check.gravity = other.gravity;
+               other.trigger_gravity_check.think = trigger_gravity_check_think;
+               other.trigger_gravity_check.nextthink = time;
+               other.trigger_gravity_check.count = 2;
+               if(other.gravity)
+                       g *= other.gravity;
+       }
+
+       if (other.gravity != g)
+       {
+               other.gravity = g;
+               if(self.noise != "")
+                       sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM);
+               UpdateCSQCProjectile(self.owner);
        }
 };
 
 void spawnfunc_trigger_gravity()
 {
-       if(!self.gravity)
+       if(self.gravity == 1)
                return;
+
        EXACTTRIGGER_INIT;
        self.touch = trigger_gravity_touch;
        if(self.noise != "")
                precache_sound(self.noise);
+
+       self.state = TRUE;
+       IFTARGETED
+       {
+               self.use = trigger_gravity_use;
+               if(self.spawnflags & 2)
+                       self.state = FALSE;
+       }
 };
 
+//=============================================================================
+
 // TODO add a way to do looped sounds with sound(); then complete this entity
 .float volume, atten;
 void target_speaker_use() {sound(self, CHAN_TRIGGER, self.noise, VOL_BASE * self.volume, self.atten);}
@@ -762,7 +819,7 @@ void spawnfunc_func_pointparticles()
        if(!self.cnt)
                self.cnt = particleeffectnum(self.mdl);
 
-       Net_LinkEntity(self, FALSE, 0, pointparticles_SendEntity);
+       Net_LinkEntity(self, (self.spawnflags & 4), 0, pointparticles_SendEntity);
 
        IFTARGETED
        {
@@ -1875,3 +1932,46 @@ void spawnfunc_trigger_magicear()
        // target:
        //   what to trigger
 }
+
+void relay_activateors_use()
+{
+       entity trg, os;
+       
+       os = self;
+       
+       for(trg = world; (trg = find(trg, targetname, os.target)); )
+       {
+               self = trg;
+               if (trg.setactive)
+                       trg.setactive(os.cnt);
+               else
+               {
+                       if(os.cnt == ACTIVE_TOGGLE)
+                               if(trg.active)
+                                       trg.active = ACTIVE_NOT;
+                               else    
+                                       trg.active = ACTIVE_ACTIVE;
+                       else
+                               trg.active = os.cnt;
+               }               
+       }
+       self = os;
+}
+
+void spawnfunc_relay_activate()
+{
+       self.cnt = ACTIVE_ACTIVE;
+       self.use = relay_activateors_use;
+}
+
+void spawnfunc_relay_deactivate()
+{
+       self.cnt = ACTIVE_NOT;
+       self.use = relay_activateors_use;       
+}
+
+void spawnfunc_relay_activatetoggle()
+{
+       self.cnt = ACTIVE_TOGGLE;
+       self.use = relay_activateors_use;       
+}