AIs will now reduce their speed if they are too far ahead of the

player.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11697 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-10-17 06:14:43 +00:00
parent c32791d027
commit b04194303a
5 changed files with 62 additions and 36 deletions

View File

@ -249,12 +249,17 @@
distance ahead, the value for the largest distance is used,
and similarly if the kart is more than the minimum value
behind).
speed-cap: Fraction of maximum speed the kart should drive
at. Used to slow down karts that are ahead of the player.
Note that setting this to a value >1 does NOT increase
the speed the kart can drive at!
-->
<ai max-item-angle="0.7" max-item-angle-high-speed="0.3"
time-full-steer="0.1"
bad-item-closeness="6"
straight-length-for-zipper="35"
rb-skid-probability="-50:1.0 -20:0.7 20:0.2 50:0.0"/>
rb-skid-probability="-50:1.0 -20:0.7 20:0.2 50:0.0"
speed-cap="10:1.0 50:0.8"/>
<!-- Slipstream: length: How far behind a kart slipstream works
collect-time: How many seconds of sstream give maximum benefit

View File

@ -27,6 +27,7 @@ float AIProperties::UNDEFINED = -99.9f;
*/
AIProperties::AIProperties()
: m_skid_probability(/*decreasing*/false)
, m_speed_cap(/*decreasing*/true)
{
m_max_item_angle = UNDEFINED;
m_max_item_angle_high_speed = UNDEFINED;
@ -47,13 +48,8 @@ void AIProperties::load(const XMLNode *ai_node)
ai_node->get("bad-item-closeness", &m_bad_item_closeness_2 );
ai_node->get("straight-length-for-zipper",&m_straight_length_for_zipper);
ai_node->get("rb-skid-probability", &m_skid_probability );
ai_node->get("speed-cap", &m_speed_cap );
if(m_skid_probability.size()==0)
{
printf("No skid probability defined.\n");
exit(-1);
}
// We actually need the square of the distance later
m_bad_item_closeness_2 *= m_bad_item_closeness_2;
@ -76,12 +72,18 @@ void AIProperties::checkAllSet(const std::string &filename) const
CHECK_NEG(m_bad_item_closeness_2, "bad-item-closeness" );
CHECK_NEG(m_straight_length_for_zipper,"straight-length-for-zipper");
if(m_skid_probability.size()==0)
{
printf("No skid probability defined.\n");
exit(-1);
}
if(m_speed_cap.size()==0)
{
printf("No speed cap defined.\n");
exit(-1);
}
} // checkAllSet
// ----------------------------------------------------------------------------
void AIProperties::copyFrom(const AIProperties *destination)
{
*this = *destination;
} // copyFrom
/* EOF */

View File

@ -72,11 +72,14 @@ protected:
/** The array of (distance, skid_probability) points. */
InterpolationArray m_skid_probability;
/** To cap maximum speed if the kart is ahead of the player. */
InterpolationArray m_speed_cap;
public:
AIProperties();
void load(const XMLNode *skid_node);
void copyFrom(const AIProperties *destination);
void checkAllSet(const std::string &filename) const;
// ------------------------------------------------------------------------
/** Returns the skidding probability dependent on the specified distance
@ -85,6 +88,13 @@ public:
{
return m_skid_probability.get(distance);
} // getSkiddingProbability
// ------------------------------------------------------------------------
/** Returns the fraction of maximum speed the AI should drive at, depending
* on the distance from the player. */
float getSpeedCap(float distance) const
{
return m_speed_cap.get(distance);
} // getSpeedCap
}; // AIProperties

View File

@ -358,6 +358,9 @@ void SkiddingAI::update(float dt)
// Get information that is needed by more than 1 of the handling funcs
computeNearestKarts();
m_kart->setSlowdown(MaxSpeed::MS_DECREASE_AI,
m_ai_properties->getSpeedCap(m_distance_to_player),
/*fade_in_time*/0.0f);
//Detect if we are going to crash with the track and/or kart
checkCrashes(m_kart->getXYZ());
determineTrackDirection();
@ -1359,22 +1362,37 @@ void SkiddingAI::computeNearestKarts()
}
m_distance_ahead = m_distance_behind = 9999999.9f;
float my_dist = m_world->getDistanceDownTrackForKart(m_kart->getWorldKartId());
float my_dist = m_world->getOverallDistance(m_kart->getWorldKartId());
if(m_kart_ahead)
{
m_distance_ahead =
m_world->getDistanceDownTrackForKart(m_kart_ahead->getWorldKartId())
- my_dist;
if(m_distance_ahead<0.0f)
m_distance_ahead += m_track->getTrackLength();
m_world->getOverallDistance(m_kart_ahead->getWorldKartId())
-my_dist;
}
if(m_kart_behind)
{
m_distance_behind = my_dist
-m_world->getDistanceDownTrackForKart(m_kart_behind->getWorldKartId());
if(m_distance_behind<0.0f)
m_distance_behind += m_track->getTrackLength();
-m_world->getOverallDistance(m_kart_behind->getWorldKartId());
}
// Compute distance to nearest player kart
m_distance_to_player = 0.0f;
unsigned int n = ProfileWorld::isProfileMode()
? 0 : race_manager->getNumPlayers();
// Initially use m_distance_to_player as 'maximum overall distance'
for(unsigned int i=0; i<n; i++)
{
unsigned int kart_id =
m_world->getPlayerKart(i)->getWorldKartId();
if(m_world->getOverallDistance(kart_id)>m_distance_to_player)
m_distance_to_player = m_world->getOverallDistance(kart_id);
}
if(m_distance_to_player==0.0f)
m_distance_to_player = 999999.9f; // force best driving
// Now convert 'maximum overall distance' to distance to player.
m_distance_to_player =
m_world->getOverallDistance(m_kart->getWorldKartId())
- m_distance_to_player;
} // computeNearestKarts
//-----------------------------------------------------------------------------
@ -2223,22 +2241,9 @@ void SkiddingAI::setSteering(float angle, float dt)
: KartControl::SC_LEFT;
if(!m_tried_skid_last_frame)
{
float max_distance = 0.0f;
unsigned int n = ProfileWorld::isProfileMode()
? 0 : race_manager->getNumPlayers();
for(unsigned int i=0; i<n; i++)
{
unsigned int kart_id =
m_world->getPlayerKart(i)->getWorldKartId();
if(m_world->getOverallDistance(kart_id)>max_distance)
max_distance = m_world->getOverallDistance(kart_id);
}
if(max_distance==0.0f)
max_distance = 999999.9f; // force best driving
float distance =
m_world->getOverallDistance(m_kart->getWorldKartId())
- max_distance;
- m_distance_to_player;
int prob = (int)
(100.0f*m_ai_properties->getSkiddingProbability(distance));

View File

@ -1,3 +1,4 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
@ -151,6 +152,9 @@ private:
* (which would make it more difficult to avoid items). */
bool m_avoid_item_close;
/** Distance to the player, used for rubber-banding. */
float m_distance_to_player;
/** A random number generator to decide if the AI should skid or not. */
RandomGenerator m_random_skid;