]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Fix #2567 "electro balls sticking to players who respawn have the balls teleported...
authorterencehill <piuntn@gmail.com>
Mon, 5 Apr 2021 13:21:55 +0000 (15:21 +0200)
committerterencehill <piuntn@gmail.com>
Mon, 5 Apr 2021 13:21:55 +0000 (15:21 +0200)
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/common/weapons/weapon/electro.qc
qcsrc/server/hook.qc

index f2448998c7c634888cba59c7b2d1f9aecc47c83c..d7de988d710d7db4fba611d49e339f6b23b551b5 100644 (file)
@@ -1922,26 +1922,29 @@ void SetMovetypeFollow(entity ent, entity e)
        ent.aiment_classname = strzone(e.classname);
        ent.aiment_deadflag = e.deadflag;
 }
+
 void UnsetMovetypeFollow(entity ent)
 {
        set_movetype(ent, MOVETYPE_FLY);
        PROJECTILE_MAKETRIGGER(ent);
-       ent.aiment = NULL;
+       // FIXME: engine bug?
+       // resetting aiment the engine will set orb's origin close to world's origin
+       //ent.aiment = NULL;
 }
-float LostMovetypeFollow(entity ent)
+
+int LostMovetypeFollow(entity ent)
 {
 /*
        if(ent.move_movetype != MOVETYPE_FOLLOW)
                if(ent.aiment)
                        error("???");
 */
-       if(ent.aiment)
-       {
-               if(ent.aiment.classname != ent.aiment_classname)
-                       return 1;
-               if(ent.aiment.deadflag != ent.aiment_deadflag)
-                       return 1;
-       }
+       // FIXME: engine bug?
+       // when aiment disconnects the engine will set orb's origin close to world's origin
+       if(!ent.aiment)
+               return 2;
+       if(ent.aiment.classname != ent.aiment_classname || ent.aiment.deadflag != ent.aiment_deadflag)
+               return 1;
        return 0;
 }
 #endif
index 7db9dcc6a2c8b1debd4ee76955a0ebe555319d24..bf63bbb914982311e664363f98e8cf31ccbb2f01 100644 (file)
@@ -229,16 +229,12 @@ int Mod_Q1BSP_NativeContentsFromSuperContents(int supercontents);
 
 #ifdef SVQC
 void attach_sameorigin(entity e, entity to, string tag);
-
 void detach_sameorigin(entity e);
-
 void follow_sameorigin(entity e, entity to);
 
 void SetMovetypeFollow(entity ent, entity e);
-
 void UnsetMovetypeFollow(entity ent);
-
-float LostMovetypeFollow(entity ent);
+int LostMovetypeFollow(entity ent);
 #endif
 
 #ifdef GAMEQC
index 0e2ef52cd0c1df80755a7330b86113dfdb0e8871..86cab70486cd8c86617e9166baf598d70209d51a 100644 (file)
@@ -248,6 +248,37 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity)
        // proj.com_phys_vel = proj.velocity;
 }
 
+void W_Electro_Orb_Follow_Think(entity this)
+{
+       if (time > this.death_time)
+       {
+               adaptor_think2use_hittype_splash(this);
+               return;
+       }
+       if (this.move_movetype == MOVETYPE_FOLLOW)
+       {
+               int lost = LostMovetypeFollow(this);
+               if (lost == 2)
+               {
+                       // FIXME if player disconnected, it isn't possible to drop the orb at player's origin
+                       // see comment in LostMovetypeFollow implementation
+                       delete(this);
+                       return;
+               }
+               if (lost)
+               {
+                       // drop the orb at the corpse's location
+                       PROJECTILE_MAKETRIGGER(this);
+                       set_movetype(this, MOVETYPE_TOSS);
+
+                       setthink(this, adaptor_think2use_hittype_splash);
+                       this.nextthink = this.death_time;
+                       return;
+               }
+       }
+       this.nextthink = time;
+}
+
 void W_Electro_Orb_Stick(entity this, entity to)
 {
        entity newproj = spawn();
@@ -276,8 +307,7 @@ void W_Electro_Orb_Stick(entity this, entity to)
        newproj.weaponentity_fld = this.weaponentity_fld;
 
        settouch(newproj, func_null);
-       setthink(newproj, getthink(this));
-       newproj.nextthink = this.nextthink;
+       newproj.death_time = this.death_time;
        newproj.use = this.use;
        newproj.flags = this.flags;
        IL_PUSH(g_projectiles, newproj);
@@ -292,7 +322,17 @@ void W_Electro_Orb_Stick(entity this, entity to)
        delete(this);
 
        if(to)
+       {
                SetMovetypeFollow(newproj, to);
+
+               setthink(newproj, W_Electro_Orb_Follow_Think);
+               newproj.nextthink = time;
+       }
+       else
+       {
+               setthink(newproj, adaptor_think2use_hittype_splash);
+               newproj.nextthink = newproj.death_time;
+       }
 }
 
 void W_Electro_Orb_Touch(entity this, entity toucher)
@@ -375,6 +415,7 @@ void W_Electro_Attack_Orb(Weapon thiswep, entity actor, .entity weaponentity)
        proj.bot_dodge = true;
        proj.bot_dodgerating = WEP_CVAR_SEC(electro, damage);
        proj.nextthink = time + WEP_CVAR_SEC(electro, lifetime);
+       proj.death_time = time + WEP_CVAR_SEC(electro, lifetime);
        PROJECTILE_MAKETRIGGER(proj);
        proj.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY;
        proj.weaponentity_fld = weaponentity;
index 51e5803704b779e63fb9ab7d2eb670dd5f2e1618..a50830348a49caaf109b60fd7269ca3fc02c1554 100644 (file)
@@ -161,7 +161,9 @@ void GrapplingHookThink(entity this)
                error("Owner lost the hook!\n");
                return;
        }
-       if(LostMovetypeFollow(this) || game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
+       if((this.move_movetype == MOVETYPE_FOLLOW && LostMovetypeFollow(this))
+               || game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted())
+               || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
        {
                RemoveHook(this);
                return;