From 186f186bae9d87f4d4170db5da3ab00c87190799 Mon Sep 17 00:00:00 2001 From: flowtron Date: Mon, 19 Jul 2021 15:13:28 +0200 Subject: [PATCH] fix nade:remote stuck on plateau --- source/src/clients2c.cpp | 2 +- source/src/weapon.cpp | 44 +++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index a767c6bc..20cbc31c 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -681,7 +681,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) case SV_THROWNADE: { vec from, vel; - loopk(3) from[k] = getint(p)/DMF; + loopk(3) from[k] = getint(p)/DNF; loopk(3) vel[k] = getint(p)/DNF; int nademillis = getint(p); if(!d) break; diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 3d97cac5..cb708577 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -1149,19 +1149,16 @@ void grenadeent::splash() } } -void grenadeent::activate(const vec &from, const vec &to) +void grenadeent::activate(const vec &from, const vec &vel) { if(nadestate!=NS_NONE) return; nadestate = NS_ACTIVATED; if(local) { - addmsg(SV_SHOOT, "ri2i3i", millis, owner->weaponsel->type, -// (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), - (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), - 0); + addmsg(SV_SHOOT, "ri2i3i", millis, owner->weaponsel->type, (int)(vel.x*DMF), (int)(vel.y*DMF), (int)(vel.z*DMF), 0); // server reads all weapons with DMF precision audiomgr.playsound(S_GRENADEPULL, SP_HIGH); - player1->pstatshots[GUN_GRENADE]++; //NEW + player1->pstatshots[GUN_GRENADE]++; } } @@ -1175,7 +1172,7 @@ void grenadeent::_throw(const vec &from, const vec &vel) inwater = waterlevel > o.z; if(local) { - addmsg(SV_THROWNADE, "ri7", int(o.x*DMF), int(o.y*DMF), int(o.z*DMF), int(vel.x*DNF), int(vel.y*DNF), int(vel.z*DNF), lastmillis-millis); + addmsg(SV_THROWNADE, "ri7", int(o.x*DNF), int(o.y*DNF), int(o.z*DNF), int(vel.x*DNF), int(vel.y*DNF), int(vel.z*DNF), lastmillis-millis); audiomgr.playsound(S_GRENADETHROW, SP_HIGH); } else audiomgr.playsound(S_GRENADETHROW, owner); @@ -1217,7 +1214,7 @@ bool grenades::busy() { return state!=GST_NONE; } bool grenades::attack(vec &targ) { int attackmillis = lastmillis-owner->lastaction; - vec &to = targ; + vec &vel = targ; bool waitdone = attackmillis>=gunwait && !(m_arena && m_teammode && arenaintermission); if(waitdone) gunwait = reloading = 0; @@ -1228,23 +1225,23 @@ bool grenades::attack(vec &targ) if(waitdone && owner->attacking && this==owner->weaponsel) { attackevent(owner, type); - activatenade(to); // activate + activatenade(vel); } break; case GST_INHAND: if(waitdone) { - if(!owner->attacking || this!=owner->weaponsel) thrownade(); // throw - else if(!inhandnade->isalive(lastmillis)) dropnade(); // drop & have fun + if(!owner->attacking || this!=owner->weaponsel) thrownade(); + else if(!inhandnade->isalive(lastmillis)) dropnade(); } break; case GST_THROWING: - if(attackmillis >= throwwait) // throw done + if(attackmillis >= throwwait) { reset(); - if(!mag && this==owner->weaponsel) // switch to primary immediately + if(!mag && this==owner->weaponsel) { owner->weaponchanging = lastmillis-1-(weaponchangetime/2); owner->nextweaponsel = owner->weaponsel = owner->primweap; @@ -1256,21 +1253,21 @@ bool grenades::attack(vec &targ) return true; } -void grenades::attackfx(const vec &from, const vec &to, int millis) // other player's grenades +void grenades::attackfx(const vec &from, const vec &vel, int millis) // other player's grenades { throwmillis = lastmillis-millis; cookingmillis = millis; if(millis == 0 || millis == -1) { state = GST_INHAND; - audiomgr.playsound(S_GRENADEPULL, owner); // activate + audiomgr.playsound(S_GRENADEPULL, owner); } else if(millis > 0) // throw { grenadeent *g = new grenadeent(owner, millis); state = GST_THROWING; bounceents.add(g); - g->_throw(from, to); + g->_throw(from, vel); } } @@ -1289,7 +1286,7 @@ int grenades::modelanim() return ANIM_GUN_IDLE; } -void grenades::activatenade(const vec &to) +void grenades::activatenade(const vec &vel) { if(!mag) return; throwmillis = 0; @@ -1302,21 +1299,26 @@ void grenades::activatenade(const vec &to) gunwait = info.attackdelay; owner->lastattackweapon = this; state = GST_INHAND; - inhandnade->activate(owner->o, to); + inhandnade->activate(owner->o, vel); } void grenades::thrownade() { if(!inhandnade) return; const float speed = cosf(RAD*owner->pitch); - vec vel(sinf(RAD*owner->yaw)*speed, -cosf(RAD*owner->yaw)*speed, sinf(RAD*owner->pitch)); - vel.mul(1.5f); - thrownade(vel); + vec lvel(sinf(RAD*owner->yaw)*speed, -cosf(RAD*owner->yaw)*speed, sinf(RAD*owner->pitch)); + lvel.mul(1.5f); + vec uvel(int(lvel.x*DNF)/DNF,int(lvel.y*DNF)/DNF,int(lvel.z*DNF)/DNF); // force universal granularity + thrownade(uvel); } void grenades::thrownade(const vec &vel) { inhandnade->moveoutsidebbox(vel, owner); + // sending with DNF precision fixes current "remote stuck on plateau"-bug, but "universal granularity"(TM) lessens discrepancies between worlds even more + inhandnade->o.x = int(inhandnade->o.x*DNF)/DNF; + inhandnade->o.y = int(inhandnade->o.y*DNF)/DNF; + inhandnade->o.z = int(inhandnade->o.z*DNF)/DNF; inhandnade->_throw(inhandnade->o, vel); inhandnade = NULL;