diff --git a/data/stk_config.xml b/data/stk_config.xml index 9225d258e..2a987d00e 100644 --- a/data/stk_config.xml +++ b/data/stk_config.xml @@ -272,6 +272,9 @@ 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! + collect-item-probability: Probability of the AI actually + trying to collect an item (if an item is selected for + collection in the first place). --> @@ -301,6 +305,7 @@ speed-cap="10:1.0 50:0.8" max-item-angle="0.7" max-item-angle-high-speed="0.3" bad-item-closeness="6" + collect-item-probability="-10:1.0 0:0" rb-skid-probability="0:0.0" skidding-threshold="3.0" /> @@ -316,6 +321,7 @@ speed-cap="20:1.0 50:0.8" max-item-angle="0.7" max-item-angle-high-speed="0.3" bad-item-closeness="6" + collect-item-probability="10:1.0 20:0" rb-skid-probability="-50:1.0 -20:0.7 20:0.2 50:0.0" skidding-threshold="2.0" /> diff --git a/src/karts/controller/ai_properties.cpp b/src/karts/controller/ai_properties.cpp index 33f554b72..7c0c75b2a 100644 --- a/src/karts/controller/ai_properties.cpp +++ b/src/karts/controller/ai_properties.cpp @@ -28,6 +28,7 @@ float AIProperties::UNDEFINED = -99.9f; AIProperties::AIProperties(RaceManager::Difficulty difficulty) : m_skid_probability(/*decreasing*/false) , m_speed_cap(/*decreasing*/true) + , m_collect_item_probability(/*decreasing*/true) { switch(difficulty) { @@ -65,6 +66,7 @@ void AIProperties::load(const XMLNode *ai_node) ai_node->get("max-item-angle-high-speed", &m_max_item_angle_high_speed ); ai_node->get("time-full-steer", &m_time_full_steer ); ai_node->get("bad-item-closeness", &m_bad_item_closeness_2 ); + ai_node->get("collect-item-probability", &m_collect_item_probability ); 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 ); @@ -130,6 +132,12 @@ void AIProperties::checkAllSet(const std::string &filename) const exit(-1); } + if(m_collect_item_probability.size()==0) + { + printf("No collect-item-probability defined.\n"); + exit(-1); + } + } // checkAllSet /* EOF */ diff --git a/src/karts/controller/ai_properties.hpp b/src/karts/controller/ai_properties.hpp index 94638f400..714dc633f 100644 --- a/src/karts/controller/ai_properties.hpp +++ b/src/karts/controller/ai_properties.hpp @@ -77,6 +77,9 @@ protected: /** To cap maximum speed if the kart is ahead of the player. */ InterpolationArray m_speed_cap; + /** To determine the probability of selecting an item. */ + InterpolationArray m_collect_item_probability; + /** Probability of a false start. Note that Nolok in boss battle will never * have a false start. */ float m_false_start_probability; @@ -131,6 +134,13 @@ public: { return m_speed_cap.get(distance); } // getSpeedCap + // ------------------------------------------------------------------------ + /** Returns the probability to collect an item depending on the distance + * to the first player kart. */ + float getItemCollectProbability(float distance) const + { + return m_collect_item_probability.get(distance); + } // getItemcollectProbability }; // AIProperties diff --git a/src/karts/controller/skidding_ai.cpp b/src/karts/controller/skidding_ai.cpp index 2949aaa23..ff8482a56 100644 --- a/src/karts/controller/skidding_ai.cpp +++ b/src/karts/controller/skidding_ai.cpp @@ -707,17 +707,45 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point, } } - // 5) Try to aim for items-to-collect + // 5) We are aiming for a new item. If necessary, determine + // randomly if this item sshould actually be collected. + // -------------------------------------------------------- + if(items_to_collect.size()>0) + { + if(items_to_collect[0] != m_last_item_random) + { + int p = (int)(100.0f*m_ai_properties-> + getItemCollectProbability(m_distance_to_player)); + m_really_collect_item = m_random_collect_item.get(100)0) { const Item *item_to_collect = items_to_collect[0]; // Test if we would hit a bad item when aiming at this good item. // If so, don't change the aim. In this case it has already been - // ensured that we won't hit the bad item (otherwise steerToAVoid + // ensured that we won't hit the bad item (otherwise steerToAvoid // would have detected this earlier). if(!hitBadItemWhenAimAt(item_to_collect, items_to_avoid)) { + // If the item is hit (with the current steering), it means + // it's on a good enough driveline, so make this item a permanent + // target. Otherwise only try to get closer (till hopefully this + // item s on our driveline) if(item_to_collect->hitLine(line_to_target, m_kart)) { #ifdef AI_DEBUG @@ -731,8 +759,10 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point, item_to_collect->getType()); m_item_to_collect = item_to_collect; } - else // kart will not hit item + else { + // Kart will not hit item, try to get closer to this item + // so that it can potentially become a permanent target. Vec3 xyz = item_to_collect->getXYZ(); float item_angle = atan2(xyz.getX() - m_kart->getXYZ().getX(), xyz.getZ() - m_kart->getXYZ().getZ()); diff --git a/src/karts/controller/skidding_ai.hpp b/src/karts/controller/skidding_ai.hpp index a92d34bc0..149282ea3 100644 --- a/src/karts/controller/skidding_ai.hpp +++ b/src/karts/controller/skidding_ai.hpp @@ -126,6 +126,16 @@ private: enum {SKID_PROBAB_NOT_YET, SKID_PROBAB_NO_SKID, SKID_PROBAB_SKID} m_skid_probability_state; + /** The last item selected for collection, for which a probability + * was determined. */ + const Item *m_last_item_random; + + /** True if m_last_item_random was randomly selected to be collected. */ + bool m_really_collect_item; + + /** A random number generator for collecting items. */ + RandomGenerator m_random_collect_item; + /** Which of the three Point Selection Algorithms (i.e. * findNoNCrashingPoint* functions) to use: * the default (which is actually slightly buggy, but so far best one