openspades/Sources/Client/Grenade.cpp

116 lines
3.0 KiB
C++
Raw Normal View History

2013-08-29 11:45:22 +09:00
/*
Copyright (c) 2013 yvt
2013-09-05 00:52:03 +09:00
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
2013-08-29 11:45:22 +09:00
This file is part of OpenSpades.
2013-08-29 11:45:22 +09:00
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
2013-08-29 11:45:22 +09:00
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
2013-08-29 11:45:22 +09:00
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
2013-08-29 11:45:22 +09:00
*/
2013-08-18 16:18:06 +09:00
#include "Grenade.h"
#include "GameMap.h"
#include "IWorldListener.h"
#include "PhysicsConstants.h"
#include "World.h"
#include <Core/Debug.h>
2013-08-18 16:18:06 +09:00
namespace spades {
namespace client {
Grenade::Grenade(World &w, Vector3 pos, Vector3 vel, float fuse) : world{w} {
2013-08-18 16:18:06 +09:00
SPADES_MARK_FUNCTION();
2013-08-18 16:18:06 +09:00
position = pos;
velocity = vel;
this->fuse = fuse;
orientation = Quaternion{0.0f, 0.0f, 0.0f, 1.0f};
2013-08-18 16:18:06 +09:00
}
Grenade::~Grenade() { SPADES_MARK_FUNCTION(); }
2013-08-18 16:18:06 +09:00
bool Grenade::Update(float dt) {
SPADES_MARK_FUNCTION();
2013-08-18 16:18:06 +09:00
fuse -= dt;
if (fuse < 0.f) {
2013-08-18 16:18:06 +09:00
Explode();
return true;
}
if (MoveGrenade(dt) == 2) {
if (world.GetListener())
world.GetListener()->GrenadeBounced(*this);
2013-08-18 16:18:06 +09:00
}
2013-08-18 16:18:06 +09:00
return false;
}
2013-08-18 16:18:06 +09:00
void Grenade::Explode() {
SPADES_MARK_FUNCTION();
if (world.GetListener())
world.GetListener()->GrenadeExploded(*this);
2013-08-18 16:18:06 +09:00
}
2013-08-18 16:18:06 +09:00
int Grenade::MoveGrenade(float fsynctics) {
SPADES_MARK_FUNCTION();
2013-08-18 16:18:06 +09:00
float f = fsynctics * 32.f;
Vector3 oldPos = position;
velocity.z += fsynctics;
position += velocity * f;
2017-01-08 00:43:55 +09:00
// Make it roll
float radius = 4.0f * 0.03f;
orientation =
Quaternion::MakeRotation(Vector3(-velocity.y, velocity.x, 0.0f) * (f / radius)) *
orientation;
2017-01-08 00:43:55 +09:00
orientation = orientation.Normalize();
// Collision
2013-08-18 16:18:06 +09:00
IntVector3 lp = position.Floor();
IntVector3 lp2 = oldPos.Floor();
Handle<GameMap> m = world.GetMap();
if (lp.z >= 63 && lp2.z < 63) {
if (world.GetListener())
world.GetListener()->GrenadeDroppedIntoWater(*this);
2013-08-18 16:18:06 +09:00
}
2013-08-18 16:18:06 +09:00
int ret = 0;
if (m->ClipWorld(position.x, position.y, position.z)) {
2013-08-18 16:18:06 +09:00
// hit a wall
ret = 1;
if (fabsf(velocity.x) > BOUNCE_SOUND_THRESHOLD ||
fabsf(velocity.y) > BOUNCE_SOUND_THRESHOLD ||
fabsf(velocity.z) > BOUNCE_SOUND_THRESHOLD)
2013-08-18 16:18:06 +09:00
ret = 2;
if (lp.z != lp2.z &&
((lp.x == lp2.x && lp.y == lp2.y) || !m->ClipWorld(lp.x, lp.y, lp2.z)))
2013-08-18 16:18:06 +09:00
velocity.z = -velocity.z;
else if (lp.x != lp2.x &&
((lp.y == lp2.y && lp.z == lp2.z) || !m->ClipWorld(lp2.x, lp.y, lp.z)))
2013-08-18 16:18:06 +09:00
velocity.x = -velocity.x;
else if (lp.y != lp2.y &&
((lp.x == lp2.x && lp.z == lp2.z) || !m->ClipWorld(lp.x, lp2.y, lp.z)))
2013-08-18 16:18:06 +09:00
velocity.y = -velocity.y;
position = oldPos;
velocity *= .36f;
}
return ret;
}
} // namespace client
} // namespace spades