2012-03-25 19:16:53 -04:00
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
2015-03-29 20:31:42 -04:00
|
|
|
// Copyright (C) 2012-2015 Joerg Henrichs
|
2012-03-25 19:16:53 -04:00
|
|
|
//
|
|
|
|
// This program 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.
|
|
|
|
//
|
|
|
|
// This program 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.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
2012-04-02 21:46:54 -04:00
|
|
|
#include "tracks/check_cannon.hpp"
|
2012-03-25 19:16:53 -04:00
|
|
|
|
2012-04-03 20:48:05 -04:00
|
|
|
#include "animations/animation_base.hpp"
|
2012-04-18 09:14:18 -04:00
|
|
|
#include "animations/ipo.hpp"
|
2014-02-25 20:52:16 -05:00
|
|
|
#include "config/user_config.hpp"
|
2012-05-14 18:26:41 -04:00
|
|
|
#include "graphics/show_curve.hpp"
|
2018-01-03 02:28:29 -05:00
|
|
|
#include "graphics/material_manager.hpp"
|
|
|
|
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
2018-01-21 02:35:38 -05:00
|
|
|
#include "graphics/sp/sp_shader_manager.hpp"
|
2012-03-25 19:16:53 -04:00
|
|
|
#include "io/xml_node.hpp"
|
2017-05-12 03:11:46 -04:00
|
|
|
#include "items/flyable.hpp"
|
2012-03-25 19:16:53 -04:00
|
|
|
#include "karts/abstract_kart.hpp"
|
2012-04-02 21:46:54 -04:00
|
|
|
#include "karts/cannon_animation.hpp"
|
2017-03-13 21:51:10 -04:00
|
|
|
#include "karts/skidding.hpp"
|
2012-03-25 19:16:53 -04:00
|
|
|
#include "modes/world.hpp"
|
2012-04-03 20:48:05 -04:00
|
|
|
|
2013-05-29 18:04:35 -04:00
|
|
|
/** Constructor for a check cannon.
|
2012-03-25 19:16:53 -04:00
|
|
|
* \param node XML node containing the parameters for this checkline.
|
|
|
|
* \param index Index of this check structure in the check manager.
|
|
|
|
*/
|
2013-05-29 18:04:35 -04:00
|
|
|
CheckCannon::CheckCannon(const XMLNode &node, unsigned int index)
|
2012-04-29 19:08:50 -04:00
|
|
|
: CheckLine(node, index)
|
2012-03-25 19:16:53 -04:00
|
|
|
{
|
2017-03-09 16:38:03 -05:00
|
|
|
std::string p1("target-p1");
|
|
|
|
std::string p2("target-p2");
|
|
|
|
|
2020-02-27 20:42:44 -05:00
|
|
|
if (RaceManager::get()->getReverseTrack())
|
2017-03-09 16:38:03 -05:00
|
|
|
{
|
|
|
|
p1 = "p1";
|
|
|
|
p2 = "p2";
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !node.get(p1, &m_target_left ) ||
|
|
|
|
!node.get(p2, &m_target_right) )
|
2014-07-19 14:43:19 -04:00
|
|
|
Log::fatal("CheckCannon", "No target line specified.");
|
2017-02-19 15:41:33 -05:00
|
|
|
|
2013-05-29 18:04:35 -04:00
|
|
|
m_curve = new Ipo(*(node.getNode("curve")),
|
|
|
|
/*fps*/25,
|
2020-02-27 20:42:44 -05:00
|
|
|
/*reverse*/RaceManager::get()->getReverseTrack());
|
2017-02-19 15:41:33 -05:00
|
|
|
|
2016-04-19 03:36:12 -04:00
|
|
|
#if defined(DEBUG) && !defined(SERVER_ONLY)
|
2020-02-23 21:58:17 -05:00
|
|
|
m_show_curve = NULL;
|
2012-05-14 18:26:41 -04:00
|
|
|
if(UserConfigParams::m_track_debug)
|
|
|
|
{
|
|
|
|
m_show_curve = new ShowCurve(0.5f, 0.5f);
|
|
|
|
const std::vector<Vec3> &p = m_curve->getPoints();
|
|
|
|
for(unsigned int i=0; i<p.size(); i++)
|
|
|
|
m_show_curve->addPoint(p[i]);
|
|
|
|
}
|
2020-02-15 01:00:48 -05:00
|
|
|
if (UserConfigParams::m_check_debug && !GUIEngine::isNoGraphics())
|
2017-02-22 17:00:07 -05:00
|
|
|
{
|
2018-01-03 02:28:29 -05:00
|
|
|
m_debug_target_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
2018-01-21 02:35:38 -05:00
|
|
|
(scene::EPT_TRIANGLE_STRIP,
|
|
|
|
SP::SPShaderManager::get()->getSPShader("additive"),
|
2018-01-10 00:10:12 -05:00
|
|
|
material_manager->getDefaultSPMaterial("additive"));
|
2018-01-03 02:28:29 -05:00
|
|
|
SP::addDynamicDrawCall(m_debug_target_dy_dc);
|
|
|
|
m_debug_target_dy_dc->getVerticesVector().resize(4);
|
|
|
|
auto& vertices = m_debug_target_dy_dc->getVerticesVector();
|
2017-02-22 17:00:07 -05:00
|
|
|
Vec3 height(0, 3, 0);
|
2018-01-03 02:28:29 -05:00
|
|
|
vertices[0].m_position = m_target_left.toIrrVector();
|
|
|
|
vertices[1].m_position = m_target_right.toIrrVector();
|
|
|
|
vertices[2].m_position = Vec3(m_target_left + height).toIrrVector();
|
|
|
|
vertices[3].m_position = Vec3(m_target_right + height).toIrrVector();
|
|
|
|
for (unsigned int i = 0; i < 4; i++)
|
2017-02-22 17:00:07 -05:00
|
|
|
{
|
2018-01-03 02:28:29 -05:00
|
|
|
vertices[i].m_color = m_active_at_reset
|
2017-02-22 17:00:07 -05:00
|
|
|
? video::SColor(128, 255, 0, 0)
|
|
|
|
: video::SColor(128, 128, 128, 128);
|
|
|
|
}
|
2018-01-03 02:28:29 -05:00
|
|
|
m_debug_target_dy_dc->recalculateBoundingBox();
|
2017-02-22 17:00:07 -05:00
|
|
|
}
|
2016-04-19 03:36:12 -04:00
|
|
|
#endif // DEBUG AND !SERVER_ONLY
|
2017-02-22 17:00:07 -05:00
|
|
|
|
2012-04-02 21:46:54 -04:00
|
|
|
} // CheckCannon
|
2012-03-25 19:16:53 -04:00
|
|
|
|
2012-04-03 20:48:05 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
2012-04-26 18:17:46 -04:00
|
|
|
/** Destructor, frees the curve data (which the cannon animation objects only
|
|
|
|
* have a read-only copy of).
|
|
|
|
*/
|
2012-04-03 20:48:05 -04:00
|
|
|
CheckCannon::~CheckCannon()
|
|
|
|
{
|
|
|
|
delete m_curve;
|
2016-04-19 03:36:12 -04:00
|
|
|
#if defined(DEBUG) && !defined(SERVER_ONLY)
|
2020-02-23 21:58:17 -05:00
|
|
|
delete m_show_curve;
|
2018-01-03 02:28:29 -05:00
|
|
|
if (m_debug_target_dy_dc)
|
|
|
|
m_debug_target_dy_dc->removeFromSP();
|
2012-05-14 18:26:41 -04:00
|
|
|
#endif
|
2012-04-03 20:48:05 -04:00
|
|
|
} // ~CheckCannon
|
|
|
|
|
2017-02-22 17:00:07 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2017-05-12 03:11:46 -04:00
|
|
|
/** Changes the colour of a check cannon depending on state.
|
|
|
|
*/
|
2017-02-22 17:00:07 -05:00
|
|
|
void CheckCannon::changeDebugColor(bool is_active)
|
|
|
|
{
|
|
|
|
#if defined(DEBUG) && !defined(SERVER_ONLY)
|
|
|
|
CheckLine::changeDebugColor(is_active);
|
|
|
|
|
|
|
|
video::SColor color = is_active ? video::SColor(192, 255, 0, 0)
|
|
|
|
: video::SColor(192, 128, 128, 128);
|
2018-01-03 02:28:29 -05:00
|
|
|
for (unsigned int i = 0; i < 4; i++)
|
2017-02-22 17:00:07 -05:00
|
|
|
{
|
2018-01-03 02:28:29 -05:00
|
|
|
m_debug_target_dy_dc->getVerticesVector()[i].m_color = color;
|
2017-02-22 17:00:07 -05:00
|
|
|
}
|
2018-01-03 02:28:29 -05:00
|
|
|
m_debug_target_dy_dc->setUpdateOffset(0);
|
2017-02-22 17:00:07 -05:00
|
|
|
#endif
|
|
|
|
} // changeDebugColor
|
|
|
|
|
2017-05-12 03:11:46 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/** Overriden to also check all flyables registered with the cannon.
|
|
|
|
*/
|
|
|
|
void CheckCannon::update(float dt)
|
|
|
|
{
|
2019-03-17 00:35:42 -04:00
|
|
|
World* world = World::getWorld();
|
2019-03-25 04:19:29 -04:00
|
|
|
// When goal phase is happening karts is made stationary, so no animation
|
|
|
|
// will be created
|
|
|
|
if (world->isGoalPhase())
|
|
|
|
return;
|
|
|
|
|
2019-03-17 00:35:42 -04:00
|
|
|
for (unsigned int i = 0; i < world->getNumKarts(); i++)
|
|
|
|
{
|
|
|
|
AbstractKart* kart = world->getKart(i);
|
|
|
|
if (kart->getKartAnimation() || kart->isGhostKart() ||
|
|
|
|
kart->isEliminated() || !m_is_active[i])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
const Vec3& xyz = world->getKart(i)->getFrontXYZ();
|
|
|
|
Vec3 prev_xyz = xyz - kart->getVelocity() * dt;
|
|
|
|
if (isTriggered(prev_xyz, xyz, /*kart index - ignore*/ -1))
|
|
|
|
{
|
|
|
|
// The constructor AbstractKartAnimation resets the skidding to 0.
|
|
|
|
// So in order to smooth rotate the kart, we need to keep the
|
|
|
|
// current visual rotation and pass it to the CannonAnimation.
|
|
|
|
float skid_rot = kart->getSkidding()->getVisualSkidRotation();
|
|
|
|
new CannonAnimation(kart, this, skid_rot);
|
|
|
|
}
|
|
|
|
} // for i < getNumKarts
|
|
|
|
|
|
|
|
for (Flyable* flyable : m_all_flyables)
|
2017-05-12 03:11:46 -04:00
|
|
|
{
|
2019-02-26 03:07:22 -05:00
|
|
|
if (!flyable->hasServerState() || flyable->hasAnimation())
|
2018-08-07 23:50:45 -04:00
|
|
|
continue;
|
2019-02-26 03:07:22 -05:00
|
|
|
|
|
|
|
const Vec3 current_position = flyable->getXYZ();
|
2019-03-17 00:35:42 -04:00
|
|
|
Vec3 previous_position = current_position - flyable->getVelocity() * dt;
|
2019-02-26 03:07:22 -05:00
|
|
|
|
2018-12-03 02:26:04 -05:00
|
|
|
setIgnoreHeight(true);
|
2019-02-26 03:07:22 -05:00
|
|
|
bool triggered = isTriggered(previous_position, current_position,
|
|
|
|
/*kart index - ignore*/ -1);
|
2017-05-12 03:11:46 -04:00
|
|
|
setIgnoreHeight(false);
|
2019-03-17 00:35:42 -04:00
|
|
|
if (!triggered)
|
|
|
|
continue;
|
2017-05-12 03:11:46 -04:00
|
|
|
|
|
|
|
// Cross the checkline - add the cannon animation
|
2019-03-17 00:35:42 -04:00
|
|
|
CannonAnimation* animation = new CannonAnimation(flyable, this);
|
2019-02-26 03:07:22 -05:00
|
|
|
flyable->setAnimation(animation);
|
2017-05-12 03:11:46 -04:00
|
|
|
} // for i in all flyables
|
|
|
|
} // update
|
2020-02-23 21:58:17 -05:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
CheckStructure* CheckCannon::clone()
|
|
|
|
{
|
|
|
|
CheckCannon* cc = new CheckCannon(*this);
|
|
|
|
#if defined(DEBUG) && !defined(SERVER_ONLY)
|
|
|
|
// Remove unsupported stuff when cloning
|
|
|
|
cc->m_show_curve = NULL;
|
|
|
|
cc->m_debug_target_dy_dc = nullptr;
|
|
|
|
#endif
|
|
|
|
// IPO curve needs to be copied manually
|
|
|
|
cc->m_curve = m_curve->clone();
|
|
|
|
return cc;
|
|
|
|
} // clone
|