diff --git a/source/src/entity.h b/source/src/entity.h index 18659e77..ac4513e6 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -100,14 +100,14 @@ struct physent int timeinair; // used for fake gravity float radius, eyeheight, aboveeye; // bounding box size bool inwater; - bool onfloor, onladder, jumpnext, crouching, trycrouch; + bool onfloor, onladder, jumpnext, crouching, trycrouch, cancollide; int lastcrouch; char move, strafe; uchar state, type; static const int crouchtime; physent() : o(0, 0, 0), yaw(270), pitch(0), roll(0), pitchvel(0), - crouching(false), trycrouch(false), lastcrouch(0), state(CS_ALIVE) + crouching(false), trycrouch(false), cancollide(true), lastcrouch(0), state(CS_ALIVE) { reset(); } @@ -480,11 +480,12 @@ struct grenadeent : bounceent bool local; int nadestate; grenadeent (playerent *owner, int millis = 0); - void activate(vec &from, vec &to); + void activate(const vec &from, const vec &to); void _throw(const vec &from, const vec &vel); void explode(); void splash(); virtual void destroy(); virtual bool applyphysics(); + void grenadeent::moveoutsidebbox(const vec &direction, playerent *boundingbox); }; diff --git a/source/src/geom.h b/source/src/geom.h index 15c0af2b..58d07d41 100644 --- a/source/src/geom.h +++ b/source/src/geom.h @@ -17,6 +17,7 @@ struct vec bool operator==(const vec &o) const { return x == o.x && y == o.y && z == o.z; } bool operator!=(const vec &o) const { return x != o.x || y != o.y || z != o.z; } + vec operator-() const { return vec(-x, -y, -z); } vec &mul(float f) { x *= f; y *= f; z *= f; return *this; } vec &div(float f) { x /= f; y /= f; z /= f; return *this; } diff --git a/source/src/physics.cpp b/source/src/physics.cpp index 53b64a86..ef813bbf 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -63,7 +63,7 @@ physent *hitplayer = NULL; bool plcollide(physent *d, physent *o, float &headspace, float &hi, float &lo) // collide with physent { - if(o->state!=CS_ALIVE) return true; + if(o->state!=CS_ALIVE || !o->cancollide) return true; const float r = o->radius+d->radius, dx = o->o.x-d->o.x, dy = o->o.y-d->o.y; const float deyeheight = d->dyneyeheight(), oeyeheight = o->dyneyeheight(); if(d->type==ENT_PLAYER && o->type==ENT_PLAYER ? dx*dx + dy*dy < r*r : fabs(dx) 0 && (player1->isspectating() || !multiplayer(false)); // allow fx only in spect mode and locally diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 77b3f111..505259e7 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -587,7 +587,7 @@ void grenadeent::splash() } } -void grenadeent::activate(vec &from, vec &to) +void grenadeent::activate(const vec &from, const vec &to) { if(nadestate!=NS_NONE) return; nadestate = NS_ACTIVATED; @@ -606,21 +606,27 @@ void grenadeent::_throw(const vec &from, const vec &vel) { if(nadestate!=NS_ACTIVATED) return; nadestate = NS_THROWED; - - this->o = from; this->vel = vel; - nadestate = NS_THROWED; - loopi(10) moveplayer(this, 10, true, 10); + this->o = from; if(local) { addmsg(SV_THROWNADE, "ri7", int(o.x*DMF), int(o.y*DMF), int(o.z*DMF), int(vel.x*DMF), int(vel.y*DMF), int(vel.z*DMF), lastmillis-millis); playsound(S_GRENADETHROW, SP_HIGH); - if(!collide(this, false, 0.0f, 0.0f)) destroy(); } else playsound(S_GRENADETHROW, owner); } +void grenadeent::moveoutsidebbox(const vec &direction, playerent *boundingbox) +{ + vel = direction; + o = boundingbox->o; + + boundingbox->cancollide = false; + loopi(10) moveplayer(this, 10, true, 10); + boundingbox->cancollide = true; +} + void grenadeent::destroy() { explode(); } bool grenadeent::applyphysics() { return nadestate==NS_THROWED; } @@ -632,7 +638,6 @@ grenades::grenades(playerent *owner) : weapon(owner, GUN_GRENADE), inhandnade(NU bool grenades::attack(vec &targ) { int attackmillis = lastmillis-owner->lastaction; - vec &from = owner->o; vec &to = targ; bool waitdone = attackmillis>=gunwait; @@ -640,7 +645,7 @@ bool grenades::attack(vec &targ) switch(state) { case GST_NONE: - if(waitdone && owner->attacking) activatenade(from, to); // activate + if(waitdone && owner->attacking) activatenade(to); // activate break; case GST_INHAND: @@ -669,15 +674,15 @@ bool grenades::attack(vec &targ) return true; } -void grenades::attackfx(vec &from, vec &to, int millis) // other player's grenades +void grenades::attackfx(const vec &from, const vec &to, int millis) // other player's grenades { throwmillis = lastmillis-millis; if(millis == 0) playsound(S_GRENADEPULL, owner); // activate else if(millis > 0) // throw { - inhandnade = new grenadeent(owner, millis); - bounceents.add(inhandnade); - thrownade(from, to); + grenadeent *g = new grenadeent(owner, millis); + bounceents.add(g); + g->_throw(from, to); } } @@ -692,7 +697,7 @@ int grenades::modelanim() return ANIM_GUN_IDLE; } -void grenades::activatenade(vec &from, vec &to) +void grenades::activatenade(const vec &to) { if(!mag) return; throwmillis = 0; @@ -703,41 +708,34 @@ void grenades::activatenade(vec &from, vec &to) gunwait = info.attackdelay; owner->lastattackweapon = this; state = GST_INHAND; - inhandnade->activate(from, to); + inhandnade->activate(owner->o, to); } 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); - - vec from(vel); - from.normalize(); - from.mul(owner->radius+inhandnade->radius); - from.mul(1.85f); - from.add(owner->o); - - thrownade(from, vel); + thrownade(vel); } -void grenades::thrownade(const vec &from, const vec &vel) +void grenades::thrownade(const vec &vel) { - if(!inhandnade) return; - inhandnade->_throw(from, vel); + inhandnade->moveoutsidebbox(vel, owner); + inhandnade->_throw(inhandnade->o, vel); + inhandnade = NULL; throwmillis = lastmillis; updatelastaction(player1); state = GST_THROWING; - - inhandnade = NULL; owner->attacking = false; } void grenades::dropnade() { vec n(0,0,0); - thrownade(owner->o, n); + thrownade(n); } void grenades::renderstats() @@ -808,7 +806,7 @@ bool gun::attack(vec &targ) return true; } -void gun::attackfx(vec &from, vec &to, int millis) +void gun::attackfx(const vec &from, const vec &to, int millis) { addbullethole(from, to); addshotline(owner, from, to); @@ -832,7 +830,7 @@ bool shotgun::attack(vec &targ) return gun::attack(targ); } -void shotgun::attackfx(vec &from, vec &to, int millis) +void shotgun::attackfx(const vec &from, const vec &to, int millis) { loopi(SGRAYS) particle_splash(0, 5, 200, sg[i]); if(addbullethole(from, to)) @@ -856,7 +854,7 @@ bool subgun::selectable() { return weapon::selectable() && !m_noprimary && this sniperrifle::sniperrifle(playerent *owner) : gun(owner, GUN_SNIPER), scoped(false) {} -void sniperrifle::attackfx(vec &from, vec &to, int millis) +void sniperrifle::attackfx(const vec &from, const vec &to, int millis) { addbullethole(from, to); addshotline(owner, from, to); @@ -984,7 +982,7 @@ bool knife::attack(vec &targ) int knife::modelanim() { return modelattacking() ? ANIM_GUN_SHOOT : ANIM_GUN_IDLE; }; void knife::drawstats() {} -void knife::attackfx(vec &from, vec &to, int millis) { attacksound(); } +void knife::attackfx(const vec &from, const vec &to, int millis) { attacksound(); } void knife::renderstats() { }; diff --git a/source/src/weapon.h b/source/src/weapon.h index 3e63fa1a..c5f4a756 100644 --- a/source/src/weapon.h +++ b/source/src/weapon.h @@ -19,7 +19,7 @@ struct weapon int reloading, lastaction; virtual bool attack(vec &targ) = 0; - virtual void attackfx(vec &from, vec &to, int millis) = 0; + virtual void attackfx(const vec &from, const vec &to, int millis) = 0; virtual void attackphysics(vec &from, vec &to); virtual void attacksound(); virtual bool reload(); @@ -57,11 +57,11 @@ struct grenades : weapon grenades(playerent *owner); bool attack(vec &targ); - void attackfx(vec &from, vec &to, int millis); + void attackfx(const vec &from, const vec &to, int millis); int modelanim(); - void activatenade(vec &from, vec &to); + void activatenade(const vec &to); void thrownade(); - void thrownade(const vec &from, const vec &vel); + void thrownade(const vec &vel); void dropnade(); void renderstats(); bool selectable(); @@ -75,7 +75,7 @@ struct gun : weapon { gun(playerent *owner, int type); virtual bool attack(vec &targ); - virtual void attackfx(vec &from, vec &to, int millis); + virtual void attackfx(const vec &from, const vec &to, int millis); int modelanim(); void checkautoreload(); }; @@ -93,7 +93,7 @@ struct sniperrifle : gun bool scoped; sniperrifle(playerent *owner); - void attackfx(vec &from, vec &to, int millis); + void attackfx(const vec &from, const vec &to, int millis); bool reload(); int dynspread(); @@ -112,7 +112,7 @@ struct shotgun : gun { shotgun(playerent *owner); bool attack(vec &targ); - void attackfx(vec &from, vec &to, int millis); + void attackfx(const vec &from, const vec &to, int millis); bool selectable(); }; @@ -160,7 +160,7 @@ struct knife : weapon int modelanim(); void drawstats(); - void attackfx(vec &from, vec &to, int millis); + void attackfx(const vec &from, const vec &to, int millis); void renderstats(); };