fix nade:remote stuck on plateau

This commit is contained in:
flowtron
2021-07-19 15:13:28 +02:00
parent 4687f00e47
commit 186f186bae
2 changed files with 24 additions and 22 deletions
+1 -1
View File
@@ -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;
+23 -21
View File
@@ -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;