From: terencehill Date: Mon, 5 Apr 2021 13:21:55 +0000 (+0200) Subject: Fix #2567 "electro balls sticking to players who respawn have the balls teleported... X-Git-Tag: xonotic-v0.8.5~467 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=3f9034c2fec80f69f791cb4ef78e7eb672dea2bb Fix #2567 "electro balls sticking to players who respawn have the balls teleported to them instead of being left at the corpse's location" --- diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index f2448998c7..d7de988d71 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -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 diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index 7db9dcc6a2..bf63bbb914 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -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 diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index 0e2ef52cd0..86cab70486 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -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; diff --git a/qcsrc/server/hook.qc b/qcsrc/server/hook.qc index 51e5803704..a50830348a 100644 --- a/qcsrc/server/hook.qc +++ b/qcsrc/server/hook.qc @@ -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;