Fix swatter issue
This commit is contained in:
parent
c789b1a8df
commit
140a229f71
@ -59,7 +59,10 @@ Swatter::Swatter(AbstractKart *kart, bool was_bomb,
|
||||
: AttachmentPlugin(kart)
|
||||
{
|
||||
m_animation_phase = SWATTER_AIMING;
|
||||
m_discard_now = false;
|
||||
m_discard_timeout = 0.0f;
|
||||
m_target = NULL;
|
||||
m_closest_kart = NULL;
|
||||
m_removing_bomb = was_bomb;
|
||||
m_bomb_scene_node = bomb_scene_node;
|
||||
m_swat_bomb_frame = 0.0f;
|
||||
@ -112,7 +115,8 @@ Swatter::~Swatter()
|
||||
*/
|
||||
bool Swatter::updateAndTestFinished(float dt)
|
||||
{
|
||||
bool discard_now = false;
|
||||
if (!m_discard_now)
|
||||
{
|
||||
if (m_removing_bomb)
|
||||
{
|
||||
m_swat_bomb_frame += dt*25.0f;
|
||||
@ -122,10 +126,10 @@ bool Swatter::updateAndTestFinished(float dt)
|
||||
|
||||
if (m_swat_bomb_frame >= 32.5f && m_bomb_scene_node != NULL)
|
||||
{
|
||||
m_bomb_scene_node->setPosition(m_bomb_scene_node->getPosition() +
|
||||
core::vector3df(-dt*15.0f, 0.0f, 0.0f) );
|
||||
m_bomb_scene_node->setRotation(m_bomb_scene_node->getRotation() +
|
||||
core::vector3df(-dt*15.0f, 0.0f, 0.0f) );
|
||||
m_bomb_scene_node->setPosition(m_bomb_scene_node
|
||||
->getPosition() + core::vector3df(-dt*15.0f, 0.0f, 0.0f) );
|
||||
m_bomb_scene_node->setRotation(m_bomb_scene_node
|
||||
->getRotation() + core::vector3df(-dt*15.0f, 0.0f, 0.0f) );
|
||||
}
|
||||
|
||||
if (m_swat_bomb_frame >= m_scene_node->getEndFrame())
|
||||
@ -150,15 +154,20 @@ bool Swatter::updateAndTestFinished(float dt)
|
||||
{
|
||||
chooseTarget();
|
||||
pointToTarget();
|
||||
if(!m_target) break;
|
||||
if(!m_target || !m_closest_kart) break;
|
||||
|
||||
// Is the target too near?
|
||||
float dist_to_target2 =
|
||||
(m_target->getXYZ()- Vec3(m_scene_node->getAbsolutePosition()))
|
||||
.length2();
|
||||
// Get the node corresponding to the joint at the center of the
|
||||
// swatter (by swatter, I mean the thing hold in the hand, not
|
||||
// the whole thing)
|
||||
scene::ISceneNode* swatter_node =
|
||||
m_scene_node->getJointNode("Swatter");
|
||||
assert(swatter_node);
|
||||
Vec3 swatter_pos = swatter_node->getAbsolutePosition();
|
||||
float dist2 = (m_closest_kart->getXYZ()-swatter_pos).length2();
|
||||
float min_dist2
|
||||
= m_kart->getKartProperties()->getSwatterDistance();
|
||||
if(dist_to_target2 < min_dist2)
|
||||
|
||||
if(dist2 < min_dist2)
|
||||
{
|
||||
// Start squashing
|
||||
m_animation_phase = SWATTER_TO_TARGET;
|
||||
@ -167,13 +176,16 @@ bool Swatter::updateAndTestFinished(float dt)
|
||||
m_scene_node->setCurrentFrame(0.0f);
|
||||
m_scene_node->setLoopMode(false);
|
||||
m_scene_node->setAnimationSpeed(SWATTER_ANIMATION_SPEED);
|
||||
|
||||
// Play swat sound
|
||||
m_swat_sound->setPosition(swatter_pos);
|
||||
m_swat_sound->play();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWATTER_TO_TARGET:
|
||||
{
|
||||
pointToTarget();
|
||||
|
||||
const float middle_frame = m_scene_node->getEndFrame()/2.0f;
|
||||
float current_frame = m_scene_node->getFrameNr();
|
||||
|
||||
@ -182,13 +194,15 @@ bool Swatter::updateAndTestFinished(float dt)
|
||||
{
|
||||
// Squash the karts and items around and
|
||||
// change the current phase
|
||||
if (squashThingsAround() &&
|
||||
race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES)
|
||||
{
|
||||
//Remove swatter from kart in 3 strikes battle after one successful hit
|
||||
discard_now = true;
|
||||
}
|
||||
squashThingsAround();
|
||||
m_animation_phase = SWATTER_FROM_TARGET;
|
||||
if (race_manager->getMinorMode()==
|
||||
RaceManager::MINOR_MODE_3_STRIKES)
|
||||
{
|
||||
// Remove swatter from kart in 3 strikes battle
|
||||
// after one successful hit
|
||||
m_discard_now = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -196,11 +210,11 @@ bool Swatter::updateAndTestFinished(float dt)
|
||||
case SWATTER_FROM_TARGET:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_discard_timeout += dt;
|
||||
|
||||
// If the swatter is used up, trigger cleaning up
|
||||
// TODO: use a timeout
|
||||
// TODO: how does it work currently...?
|
||||
return (discard_now ? true : false);
|
||||
return (m_discard_now && m_discard_timeout > 0.5f ? true : false);
|
||||
} // updateAndTestFinished
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -240,6 +254,7 @@ void Swatter::chooseTarget()
|
||||
}
|
||||
}
|
||||
m_target = closest_kart; // may be NULL
|
||||
m_closest_kart = closest_kart;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -267,42 +282,13 @@ void Swatter::pointToTarget()
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Squash karts or items that are around the end position (determined using
|
||||
* a joint) of the swatter.
|
||||
* \return True if target kart is hit.
|
||||
*/
|
||||
bool Swatter::squashThingsAround()
|
||||
void Swatter::squashThingsAround()
|
||||
{
|
||||
const KartProperties *kp = m_kart->getKartProperties();
|
||||
// Square of the minimum distance
|
||||
float min_dist2 = kp->getSwatterDistance();
|
||||
const World* world = World::getWorld();
|
||||
|
||||
// Get the node corresponding to the joint at the center of the swatter
|
||||
// (by swatter, I mean the thing hold in the hand, not the whole thing)
|
||||
scene::ISceneNode* swatter_node = m_scene_node->getJointNode("Swatter");
|
||||
assert(swatter_node);
|
||||
Vec3 swatter_pos = swatter_node->getAbsolutePosition();
|
||||
|
||||
m_swat_sound->setPosition(swatter_pos);
|
||||
m_swat_sound->play();
|
||||
bool target_is_hit = false;
|
||||
|
||||
// Squash karts around
|
||||
for(unsigned int i = 0; i < world->getNumKarts(); i++)
|
||||
{
|
||||
AbstractKart *kart = world->getKart(i);
|
||||
// TODO: isSwatterReady()
|
||||
if(kart->isEliminated() || kart==m_kart)
|
||||
continue;
|
||||
// don't swat an already hurt kart
|
||||
if (kart->isInvulnerable() || kart->isSquashed())
|
||||
continue;
|
||||
|
||||
float dist2 = (kart->getXYZ()-swatter_pos).length2();
|
||||
|
||||
if(dist2 >= min_dist2) continue; // too far away, ignore this kart
|
||||
|
||||
kart->setSquash(kp->getSwatterSquashDuration(), kp->getSwatterSquashSlowdown());
|
||||
target_is_hit = true;
|
||||
m_closest_kart->setSquash(kp->getSwatterSquashDuration(),
|
||||
kp->getSwatterSquashSlowdown());
|
||||
|
||||
//Handle achievement if the swatter is used by the current player
|
||||
const StateManager::ActivePlayer *const ap = m_kart->getController()
|
||||
@ -313,18 +299,16 @@ bool Swatter::squashThingsAround()
|
||||
"swatter", 1);
|
||||
}
|
||||
|
||||
if (kart->getAttachment()->getType()==Attachment::ATTACH_BOMB)
|
||||
if (m_closest_kart->getAttachment()->getType()==Attachment::ATTACH_BOMB)
|
||||
{ // make bomb explode
|
||||
kart->getAttachment()->update(10000);
|
||||
m_closest_kart->getAttachment()->update(10000);
|
||||
HitEffect *he = new Explosion(m_kart->getXYZ(), "explosion", "explosion.xml");
|
||||
if(m_kart->getController()->isPlayerController())
|
||||
he->setPlayerKartHit();
|
||||
projectile_manager->addHitEffect(he);
|
||||
ExplosionAnimation::create(kart);
|
||||
ExplosionAnimation::create(m_closest_kart);
|
||||
} // if kart has bomb attached
|
||||
World::getWorld()->kartHit(kart->getWorldKartId());
|
||||
} // for i < num_kartrs
|
||||
return target_is_hit;
|
||||
World::getWorld()->kartHit(m_closest_kart->getWorldKartId());
|
||||
|
||||
// TODO: squash items
|
||||
} // squashThingsAround
|
||||
|
@ -49,9 +49,17 @@ private:
|
||||
enum {SWATTER_AIMING, SWATTER_TO_TARGET, SWATTER_FROM_TARGET}
|
||||
m_animation_phase;
|
||||
|
||||
/** True if the swatter will be discarded now. */
|
||||
bool m_discard_now;
|
||||
|
||||
/** Require for the sfx to complete. */
|
||||
float m_discard_timeout;
|
||||
|
||||
/** The kart the swatter is aiming at. */
|
||||
Moveable *m_target;
|
||||
|
||||
AbstractKart *m_closest_kart;
|
||||
|
||||
SFXBase *m_swat_sound;
|
||||
|
||||
/** True if the swatter is removing an attached bomb. */
|
||||
@ -91,7 +99,7 @@ private:
|
||||
void pointToTarget();
|
||||
|
||||
/** Squash karts or items that are around the end position (determined using a joint) of the swatter */
|
||||
bool squashThingsAround();
|
||||
void squashThingsAround();
|
||||
}; // Swatter
|
||||
|
||||
#endif
|
||||
|
@ -98,18 +98,17 @@ void BattleAI::reset()
|
||||
{
|
||||
m_current_node = BattleGraph::UNKNOWN_POLY;
|
||||
m_target_node = BattleGraph::UNKNOWN_POLY;
|
||||
m_closest_kart = NULL;
|
||||
m_closest_kart_node = BattleGraph::UNKNOWN_POLY;
|
||||
m_closest_kart_point = Vec3(0, 0, 0);
|
||||
m_closest_kart_pos_data = {0};
|
||||
m_cur_kart_pos_data = {0};
|
||||
m_is_stuck = false;
|
||||
m_is_uturn = false;
|
||||
m_is_steering_overridden = false;
|
||||
m_target_point = Vec3(0, 0, 0);
|
||||
m_time_since_last_shot = 0.0f;
|
||||
m_time_since_driving = 0.0f;
|
||||
m_time_since_reversing = 0.0f;
|
||||
m_time_since_steering_overridden = 0.0f;
|
||||
m_time_since_uturn = 0.0f;
|
||||
m_on_node.clear();
|
||||
m_path_corners.clear();
|
||||
@ -166,7 +165,6 @@ void BattleAI::update(float dt)
|
||||
findClosestKart(true);
|
||||
findTarget();
|
||||
handleItems(dt);
|
||||
handleSwatter();
|
||||
|
||||
if (m_kart->getSpeed() > 15.0f && m_cur_kart_pos_data.angle < 0.2f)
|
||||
{
|
||||
@ -308,22 +306,17 @@ void BattleAI::findClosestKart(bool difficulty)
|
||||
}
|
||||
|
||||
if (!difficulty)
|
||||
{
|
||||
m_closest_kart = m_world->getKart(closest_kart_num);
|
||||
checkPosition(m_closest_kart_point, &m_closest_kart_pos_data);
|
||||
}
|
||||
} // findClosestKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BattleAI::findTarget()
|
||||
{
|
||||
// Don't try to hit a player continuously with swatter for easy and medium
|
||||
// mode, which make it too aggressive
|
||||
const bool continuous_swatter =
|
||||
m_kart->getAttachment()->getType() == Attachment::ATTACH_SWATTER &&
|
||||
(m_cur_difficulty == RaceManager::DIFFICULTY_HARD ||
|
||||
m_cur_difficulty == RaceManager::DIFFICULTY_BEST);
|
||||
|
||||
// Find a suitable target to drive to, either powerup or kart
|
||||
if (m_kart->getPowerup()->getType() == PowerupManager::POWERUP_NOTHING &&
|
||||
!continuous_swatter)
|
||||
if (m_kart->getPowerup()->getType() == PowerupManager::POWERUP_NOTHING)
|
||||
handleItemCollection(&m_target_point , &m_target_node);
|
||||
else
|
||||
{
|
||||
@ -389,19 +382,6 @@ void BattleAI::handleSteering(const float dt)
|
||||
if (m_current_node == BattleGraph::UNKNOWN_POLY ||
|
||||
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
||||
|
||||
if (m_is_steering_overridden)
|
||||
{
|
||||
// Steering is overridden to avoid collision with the target kart
|
||||
m_time_since_steering_overridden += dt;
|
||||
setSteering(-1.0f, dt);
|
||||
if (m_time_since_steering_overridden > 0.5f)
|
||||
{
|
||||
m_is_steering_overridden = false;
|
||||
m_time_since_steering_overridden = 0.0f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_target_node == m_current_node)
|
||||
{
|
||||
// Very close to the item, steer directly
|
||||
@ -452,27 +432,6 @@ void BattleAI::handleSteering(const float dt)
|
||||
}
|
||||
} // handleSteering
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Make AI avoid collison with target as much as possible when attacking with
|
||||
* swatter.
|
||||
*/
|
||||
void BattleAI::handleSwatter()
|
||||
{
|
||||
if (m_is_steering_overridden) return;
|
||||
|
||||
if (m_kart->getAttachment()->getType() == Attachment::ATTACH_SWATTER)
|
||||
{
|
||||
findClosestKart(false);
|
||||
if (m_closest_kart_pos_data.angle < 0.25f &&
|
||||
m_closest_kart_pos_data.distance < 5.0f)
|
||||
{
|
||||
// Check whether it's straight ahead towards target
|
||||
m_is_steering_overridden = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // handleSwatter
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function finds the polyon edges(portals) that the AI will cross before
|
||||
* reaching its destination. We start from the current polygon and call
|
||||
@ -632,18 +591,6 @@ void BattleAI::handleBraking()
|
||||
{
|
||||
m_controls->m_brake = false;
|
||||
|
||||
if (m_is_steering_overridden && m_kart->getSpeed() > 10.0f)
|
||||
{
|
||||
// Hard-brake for too fast
|
||||
if (m_kart->getSpeed() > 15.0f)
|
||||
{
|
||||
m_controls->m_accel = -12.5f;
|
||||
return;
|
||||
}
|
||||
m_controls->m_brake = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// A kart will not brake when the speed is already slower than this
|
||||
// value. This prevents a kart from going too slow (or even backwards)
|
||||
// in tight curves.
|
||||
@ -741,6 +688,9 @@ void BattleAI::handleItems(const float dt)
|
||||
|
||||
// Find a closest kart again, this time we ignore difficulty
|
||||
findClosestKart(false);
|
||||
|
||||
if (!m_closest_kart) return;
|
||||
|
||||
m_time_since_last_shot += dt;
|
||||
|
||||
float min_bubble_time = 2.0f;
|
||||
@ -797,7 +747,8 @@ void BattleAI::handleItems(const float dt)
|
||||
// Leave some time between shots
|
||||
if (m_time_since_last_shot < 1.0f) break;
|
||||
|
||||
if (m_closest_kart_pos_data.distance < 25.0f)
|
||||
if (m_closest_kart_pos_data.distance < 25.0f &&
|
||||
!m_closest_kart->isInvulnerable())
|
||||
{
|
||||
m_controls->m_fire = true;
|
||||
m_controls->m_look_back = fire_behind;
|
||||
@ -829,11 +780,15 @@ void BattleAI::handleItems(const float dt)
|
||||
|
||||
case PowerupManager::POWERUP_SWATTER:
|
||||
{
|
||||
// Squared distance for which the swatter works
|
||||
float d2 = m_kart->getKartProperties()->getSwatterDistance();
|
||||
// if the kart has a shield, do not break it by using a swatter.
|
||||
if (m_kart->getShieldTime() > min_bubble_time)
|
||||
break;
|
||||
|
||||
if (m_closest_kart_pos_data.distance < 7.0f)
|
||||
if (!m_closest_kart->isSquashed() &&
|
||||
m_closest_kart_pos_data.distance < d2 &&
|
||||
m_closest_kart->getSpeed() < m_kart->getSpeed())
|
||||
{
|
||||
m_controls->m_fire = true;
|
||||
m_controls->m_look_back = false;
|
||||
|
@ -61,6 +61,9 @@ private:
|
||||
int m_closest_kart_node;
|
||||
Vec3 m_closest_kart_point;
|
||||
|
||||
/** Pointer to the closest kart around this kart. */
|
||||
AbstractKart *m_closest_kart;
|
||||
|
||||
posData m_closest_kart_pos_data;
|
||||
posData m_cur_kart_pos_data;
|
||||
|
||||
@ -71,10 +74,6 @@ private:
|
||||
* counting down. */
|
||||
bool m_is_stuck;
|
||||
|
||||
/** Indicates that the steering of kart is overridden, and
|
||||
* m_time_since_steering_overridden is counting down. */
|
||||
bool m_is_steering_overridden;
|
||||
|
||||
/** Indicates that the kart need a uturn to reach a node behind, and
|
||||
* m_time_since_uturn is counting down. */
|
||||
bool m_is_uturn;
|
||||
@ -108,9 +107,6 @@ private:
|
||||
/** This is a timer that counts down when the kart is starting to drive. */
|
||||
float m_time_since_driving;
|
||||
|
||||
/** This is a timer that counts down when the steering of kart is overridden. */
|
||||
float m_time_since_steering_overridden;
|
||||
|
||||
/** This is a timer that counts down when the kart is doing u-turn. */
|
||||
float m_time_since_uturn;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user