Changed slipstream handling: boost will now be given when getting out

of slipstream and enough 'slipstream credits' have been accumulated
(which is shown by a little bit of nitro). This should avoid the problem of
crashing into the kart ahead when getting nitro, and also make it less
likely that the AI creates trains.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6153 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2010-09-26 22:44:23 +00:00
parent 90cfa6bb4a
commit 3c2f45a556
4 changed files with 99 additions and 41 deletions

View File

@@ -37,7 +37,7 @@
#include <iostream>
#ifdef AI_DEBUG
#include "graphics/irr_driver.hpp"
# include "graphics/irr_driver.hpp"
#endif
#include "modes/linear_world.hpp"
#include "network/network_manager.hpp"
@@ -92,6 +92,7 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
{
case RaceManager::RD_EASY:
m_wait_for_players = true;
m_make_use_of_slipstream = false;
m_max_handicap_accel = 0.9f;
m_item_tactic = IT_TEN_SECONDS;
m_false_start_probability = 0.08f;
@@ -104,6 +105,7 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
break;
case RaceManager::RD_MEDIUM:
m_wait_for_players = true;
m_make_use_of_slipstream = false;
m_max_handicap_accel = 0.95f;
m_item_tactic = IT_CALCULATE;
m_false_start_probability = 0.04f;
@@ -116,6 +118,7 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart)
break;
case RaceManager::RD_HARD:
m_wait_for_players = false;
m_make_use_of_slipstream = true;
m_max_handicap_accel = 1.0f;
m_item_tactic = IT_CALCULATE;
m_false_start_probability = 0.01f;
@@ -821,6 +824,19 @@ void DefaultAIController::checkCrashes(int steps, const Vec3& pos )
//tell when a kart is going to get out of the track so it steers.
m_crashes.clear();
// If slipstream should be handled actively, trigger overtaking the
// kart which gives us slipstream if slipstream is readyA
if(m_make_use_of_slipstream && m_kart->isSlipstreamReady() &&
m_kart->getSlipstreamKart())
{
//printf("%s overtaking %s\n", m_kart->getIdent().c_str(),
// m_kart->getSlipstreamKart()->getIdent().c_str());
// FIXME: we might define a minimum distance, and if the target kart
// is too close break first - otherwise the AI hits the kart when
// trying to overtake it, actually speeding the other kart up.
m_crashes.m_kart = m_kart->getSlipstreamKart()->getWorldKartId();
}
const size_t NUM_KARTS = m_world->getNumKarts();
//Protection against having vel_normal with nan values

View File

@@ -69,22 +69,28 @@ private:
/** The actual start delay used. */
float m_start_delay;
int m_min_steps; //Minimum number of steps to check. If 0, the AI doesn't
//even has check around the kart, if 1, it checks around
//the kart always, and more than that will check the
//remaining number of steps in front of the kart, always
bool m_wait_for_players; //If true, the acceleration is decreased when
//the AI is in a better position than all the
//human players.
float m_max_handicap_accel; //The allowed maximum speed, in percentage,
//from 0.0 to 1.0. Used only when
//m_wait_for_players == true.
/** Minimum number of steps to check. If 0, the AI doesn't even has check
* around the kart, if 1, it checks around the kart always, and more
* than that will check the remaining number of steps in front of the
* kart, always. */
int m_min_steps;
/** If true, the acceleration is decreased when the AI is in a better
* position than all the human players. */
bool m_wait_for_players;
/** The allowed maximum speed, in percentage, from 0.0 to 1.0. Used only
* when m_wait_for_players == true. */
float m_max_handicap_accel;
ItemTactic m_item_tactic; //How are items going to be used?
/** How are items going to be used? */
ItemTactic m_item_tactic;
/** True if the kart should try to pass on a bomb to another kart. */
bool m_handle_bomb;
/** True if the AI should avtively try to make use of slipstream. */
bool m_make_use_of_slipstream;
/*General purpose variables*/
//The crash percentage is how much of the time the AI has been crashing,
//if the AI has been crashing for some time, use the rescue.
@@ -127,7 +133,7 @@ private:
* graph nodes. */
std::vector<std::vector<int> > m_all_look_aheads;
float m_time_since_stuck;
float m_time_since_stuck;
int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash.

View File

@@ -85,13 +85,13 @@ Kart::Kart (const std::string& ident, int position,
m_collected_energy = 0;
m_finished_race = false;
m_finish_time = 0.0f;
m_slipstream_time = 0.0f;
m_shadow_enabled = false;
m_shadow = NULL;
m_smoke_system = NULL;
m_water_splash_system = NULL;
m_nitro = NULL;
m_slip_stream = NULL;
m_slipstream = NULL;
m_slipstream_time = 0.0f;
m_skidmarks = NULL;
m_camera = NULL;
m_controller = NULL;
@@ -308,7 +308,7 @@ Kart::~Kart()
if(m_smoke_system) delete m_smoke_system;
if(m_water_splash_system) delete m_water_splash_system;
if(m_nitro) delete m_nitro;
if(m_slip_stream) delete m_slip_stream;
if(m_slipstream) delete m_slipstream;
delete m_shadow;
@@ -386,6 +386,7 @@ void Kart::reset()
m_kart_model->setAnimation(KartModel::AF_DEFAULT);
m_view_blocked_by_plunger = 0.0;
m_attachment->clear();
m_nitro->setCreationRate(0.0f);
m_powerup.reset();
m_race_position = m_initial_position;
@@ -420,7 +421,7 @@ void Kart::reset()
m_controls.m_drift = false;
m_controls.m_fire = false;
m_controls.m_look_back = false;
m_slip_stream->reset();
m_slipstream->reset();
m_vehicle->deactivateZipper();
// Set the brakes so that karts don't slide downhill
@@ -687,7 +688,7 @@ void Kart::update(float dt)
m_smoke_system->update(dt);
m_water_splash_system->update(dt);
m_nitro->update(dt);
m_slip_stream->update(dt);
m_slipstream->update(dt);
} // UserConfigParams::m_graphical_effects
updatePhysics(dt);
@@ -880,9 +881,9 @@ float Kart::handleNitro(float dt)
*/
float Kart::handleSlipstream(float dt)
{
// Update this karts slipstream quad (even for low level AI, since even
// then player karts can get slipstream, and so have to compare with
// the modified slipstream quad.
// Update this karts slipstream quad (even for low level AI which don't
// use slipstream, since even then player karts can get slipstream,
// and so have to compare with the modified slipstream quad.
m_slipstream_original_quad->transform(getTrans(), m_slipstream_quad);
// Low level AIs should not do any slipstreaming.
@@ -895,7 +896,7 @@ float Kart::handleSlipstream(float dt)
{
m_slipstream_time -= dt;
if(m_slipstream_time<0) m_slipstream_mode=SS_NONE;
m_slip_stream->setIntensity(2.0f, NULL);
m_slipstream->setIntensity(2.0f, NULL);
return m_kart_properties->getSlipstreamAddPower();
}
@@ -908,7 +909,7 @@ float Kart::handleSlipstream(float dt)
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
if(getSpeed()<m_kart_properties->getSlipstreamMinSpeed())
{
m_slip_stream->setIntensity(0, NULL);
m_slipstream->setIntensity(0, NULL);
return 0;
}
#endif
@@ -917,16 +918,16 @@ float Kart::handleSlipstream(float dt)
World *world = World::getWorld();
unsigned int num_karts = world->getNumKarts();
bool is_sstreaming = false;
Kart *target_kart;
m_slipstream_target = NULL;
// Note that this loop can not be simply replaced with a shorter loop
// using only the karts with a better position - since a kart might
// be a lap behind
for(unsigned int i=0; i<num_karts; i++)
{
target_kart = world->getKart(i);
m_slipstream_target= world->getKart(i);
// Don't test for slipstream with itself.
if(target_kart==this ||
target_kart->isEliminated() ) continue;
if(m_slipstream_target==this ||
m_slipstream_target->isEliminated() ) continue;
// If the kart we are testing against is too slow, no need to test
// slipstreaming. Note: We compare the speed of the other kart
@@ -934,16 +935,18 @@ float Kart::handleSlipstream(float dt)
// entirely sure if this makes sense, but it makes it easier to
// give karts different slipstream properties.
#ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING
if(target_kart->getSpeed()<m_kart_properties->getSlipstreamMinSpeed())
if(m_slipstream_target->getSpeed() <
m_kart_properties->getSlipstreamMinSpeed())
continue;
#endif
// Quick test: the kart must be not more than
// slipstream length+kart_length() away from the other kart
Vec3 delta = getXYZ() - target_kart->getXYZ();
float l = target_kart->m_kart_properties->getSlipstreamLength()
+ target_kart->getKartLength()*0.5f;
Vec3 delta = getXYZ() - m_slipstream_target->getXYZ();
float l = m_slipstream_target->m_kart_properties->getSlipstreamLength()
+ m_slipstream_target->getKartLength()*0.5f;
if(delta.length2_2d() > l*l) continue;
if(target_kart->m_slipstream_quad->pointInQuad(getXYZ()))
// Real test: if in slipstream quad of other kart
if(m_slipstream_target->m_slipstream_quad->pointInQuad(getXYZ()))
{
is_sstreaming = true;
break;
@@ -952,9 +955,26 @@ float Kart::handleSlipstream(float dt)
if(!is_sstreaming)
{
if(isSlipstreamReady())
{
// The first time slipstream is ready after collecting
// and you are leaving the slipstream area, you get a
// zipper bonus.
if(m_slipstream_mode==SS_COLLECT)
{
m_slipstream_mode = SS_USE;
handleZipper();
// And the time is set to a maximum (to avoid that e.g. AI
// karts slipstream for a long time and then get a very long
// bonus).
m_slipstream_time =
m_kart_properties->getSlipstreamCollectTime();
return m_kart_properties->getSlipstreamAddPower();
}
}
m_slipstream_time -=dt;
if(m_slipstream_time<0) m_slipstream_mode = SS_NONE;
m_slip_stream->setIntensity(0, NULL);
m_slipstream->setIntensity(0, NULL);
return 0;
} // for i<number of karts
@@ -962,21 +982,29 @@ float Kart::handleSlipstream(float dt)
m_slipstream_time = m_slipstream_mode==SS_NONE ? dt
: m_slipstream_time+dt;
//printf("Collecting slipstream %f\n", m_slipstream_time);
m_slip_stream->setIntensity(m_slipstream_time, target_kart);
if(isSlipstreamReady())
m_nitro->setCreationRate(3.0f);
m_slipstream->setIntensity(m_slipstream_time, m_slipstream_target);
m_slipstream_mode = SS_COLLECT;
if(m_slipstream_time>m_kart_properties->getSlipstreamCollectTime())
{
m_slipstream_mode = SS_USE;
handleZipper(); // FIXME(/REMOVE?) Zipper gives a sharp push, maybe too sharp
m_slipstream->setIntensity(1.0f, m_slipstream_target);
return 0; // see below about abusing m_zipper_time_left without zipper
//return m_kart_properties->getSlipstreamAddPower();
}
//m_zipper_time_left = 5.0f; // FIXME, this is a hack to test higher speed limit without zipper, better would be own counter
return 0;
//return m_kart_properties->getSlipstreamAddPower();
} // handleSlipstream
// -----------------------------------------------------------------------------
/** Returns true if enough slipstream credits have been accumulated
* to get a boost when leaving the slipstream area.
*/
bool Kart::isSlipstreamReady() const
{
return m_slipstream_time>m_kart_properties->getSlipstreamCollectTime();
} // isSlipstreamReady
// -----------------------------------------------------------------------------
/** This function is called when the race starts. Up to then all brakes are
@@ -1353,7 +1381,7 @@ void Kart::loadData()
m_smoke_system = new Smoke(this);
m_water_splash_system = new WaterSplash(this);
m_nitro = new Nitro(this);
m_slip_stream = new SlipStream(this);
m_slipstream = new SlipStream(this);
if(m_kart_properties->hasSkidmarks())
m_skidmarks = new SkidMarks(*this);

View File

@@ -145,7 +145,7 @@ private:
Nitro *m_nitro;
/** Graphical effect when slipstreaming. */
SlipStream *m_slip_stream;
SlipStream *m_slipstream;
float m_wheel_rotation;
/** For each wheel it stores the suspension length after the karts are at
@@ -169,6 +169,10 @@ private:
/** The time a kart was in slipstream. */
float m_slipstream_time;
/** The kart from which this kart gets slipstream. Used by the AI to
** overtake the right kart. */
Kart *m_slipstream_target;
/** Slipstream mode: either nothing happening, or the kart is collecting
* 'slipstream credits', or the kart is using accumulated credits. */
@@ -367,6 +371,10 @@ public:
/** Returns true if the kart is close to the ground, used to dis/enable
* the upright constraint to allow for more realistic explosions. */
bool isNearGround () const;
bool isSlipstreamReady() const;
/** Returns which kart is giving slip stream to this kart. */
const Kart* getSlipstreamKart() const {return m_slipstream_target;};
void resetBrakes ();
void startEngineSFX ();
void adjustSpeed (float f);