]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mapobjects/func/button.qc
Rename sv_vq3compat to sv_q3defragcompat to clarify its purpose
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / func / button.qc
index 28e6481c880886c18d240fc3cc55719eb80668d6..423ac5e7b6d927f9fa2f8cdd42cf9797fe6b2f56 100644 (file)
@@ -5,6 +5,43 @@
 void button_wait(entity this);
 void button_return(entity this);
 
+// in case button is deactivated by a relay_deactivate while it pressed down
+// set both fields to -1 in button_return!!
+.float wait_remaining;
+.float activation_time;
+
+void button_setactive(entity this, int astate)
+{
+       int oldstate = this.active;
+       if (astate == ACTIVE_TOGGLE)
+       {
+               if (this.active == ACTIVE_ACTIVE)
+                       this.active = ACTIVE_NOT;
+               else
+                       this.active = ACTIVE_ACTIVE;
+       }
+       else
+               this.active = astate;
+
+       if (this.active == ACTIVE_ACTIVE && oldstate == ACTIVE_NOT)
+       {
+               // button was deactivated while it was pressed
+               if (this.wait_remaining >= 0)
+               {
+                       this.nextthink =  this.wait_remaining + this.ltime;
+                       setthink(this, button_return);
+               }
+       }
+       else if (this.active == ACTIVE_NOT && oldstate == ACTIVE_ACTIVE)
+       {
+               // check if button is in pressed state
+               if (this.activation_time >= 0)
+               {
+                       this.wait_remaining = this.wait - (time - this.activation_time);
+               }
+       }
+}
+
 void button_wait(entity this)
 {
        this.state = STATE_TOP;
@@ -24,11 +61,17 @@ void button_done(entity this)
 
 void button_return(entity this)
 {
+       if (this.active != ACTIVE_ACTIVE)
+       {
+               return;
+       }
        this.state = STATE_DOWN;
        SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, button_done);
        this.frame = 0;                 // use normal textures
-       if (this.health)
+       if (GetResource(this, RES_HEALTH))
                this.takedamage = DAMAGE_YES;   // can be shot again
+       this.wait_remaining = -1;
+       this.activation_time = -1;
 }
 
 
@@ -40,12 +83,14 @@ void button_blocked(entity this, entity blocker)
 
 void button_fire(entity this)
 {
-       this.health = this.max_health;
+       SetResourceExplicit(this, RES_HEALTH, this.max_health);
        this.takedamage = DAMAGE_NO;    // will be reset upon return
 
        if (this.state == STATE_UP || this.state == STATE_TOP)
                return;
 
+       this.activation_time = time;
+
        if (this.noise != "")
                _sound (this, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
 
@@ -55,14 +100,17 @@ void button_fire(entity this)
 
 void button_reset(entity this)
 {
-       this.health = this.max_health;
+       SetResourceExplicit(this, RES_HEALTH, this.max_health);
        setorigin(this, this.pos1);
        this.frame = 0;                 // use normal textures
        this.state = STATE_BOTTOM;
        this.velocity = '0 0 0';
+       this.wait_remaining = -1;
+       this.activation_time = -1;
+       this.active = ACTIVE_ACTIVE;
        setthink(this, func_null);
        this.nextthink = 0;
-       if (this.health)
+       if (GetResource(this, RES_HEALTH))
                this.takedamage = DAMAGE_YES;   // can be shot again
 }
 
@@ -77,6 +125,8 @@ void button_use(entity this, entity actor, entity trigger)
 
 void button_touch(entity this, entity toucher)
 {
+       if (this.active != ACTIVE_ACTIVE)
+               return;
        if (!toucher)
                return;
        if (!toucher.iscreature)
@@ -91,12 +141,14 @@ void button_touch(entity this, entity toucher)
 
 void button_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
+       if (this.active != ACTIVE_ACTIVE)
+               return;
        if(this.spawnflags & NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
        if (this.spawnflags & BUTTON_DONTACCUMULATEDMG)
        {
-               if (this.health <= damage)
+               if (GetResource(this, RES_HEALTH) <= damage)
                {
                        this.enemy = attacker;
                        button_fire(this);
@@ -104,8 +156,8 @@ void button_damage(entity this, entity inflictor, entity attacker, float damage,
        }
        else
        {
-               this.health = this.health - damage;
-               if (this.health <= 0)
+               TakeResource(this, RES_HEALTH, damage);
+               if (GetResource(this, RES_HEALTH) <= 0)
                {
                        this.enemy = attacker;
                        button_fire(this);
@@ -138,9 +190,9 @@ spawnfunc(func_button)
 
 //     if (this.health == 0) // all buttons are now shootable
 //             this.health = 10;
-       if (this.health)
+       if (GetResource(this, RES_HEALTH))
        {
-               this.max_health = this.health;
+               this.max_health = GetResource(this, RES_HEALTH);
                this.event_damage = button_damage;
                this.takedamage = DAMAGE_YES;
        }
@@ -154,10 +206,15 @@ spawnfunc(func_button)
        if (!this.lip)
                this.lip = 4;
 
+       if(this.wait == -1 && autocvar_sv_q3defragcompat)
+               this.wait = 0.1; // compatibility for q3df: "instant" return
+
     if(this.noise != "")
         precache_sound(this.noise);
 
-       this.active = ACTIVE_ACTIVE;
+       this.draggable = drag_undraggable;
+
+       this.setactive = button_setactive;
 
        this.pos1 = this.origin;
        this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);