diff --git a/.gitignore b/.gitignore index 1ba98ce23..b437bf1b2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ stk-editor/ .config/ supertuxkart-64 make*.bat +__pycache__ data/editor data/karts diff --git a/data/CREDITS b/data/CREDITS index 64991a2a6..d36394892 100755 Binary files a/data/CREDITS and b/data/CREDITS differ diff --git a/data/kart_characteristics.xml b/data/kart_characteristics.xml new file mode 100644 index 000000000..e72f40f8f --- /dev/null +++ b/data/kart_characteristics.xml @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/stk_config.xml b/data/stk_config.xml index a36995311..d1b198a0f 100644 --- a/data/stk_config.xml +++ b/data/stk_config.xml @@ -85,24 +85,6 @@ - - - - - - @@ -150,22 +132,6 @@ ============================ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -411,23 +314,6 @@ (like 10000000) disables bullet skidding. --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/sources.cmake b/sources.cmake index e7f553234..ba4868d71 100644 --- a/sources.cmake +++ b/sources.cmake @@ -1,5 +1,5 @@ -# Modify this file to change the last-modified date when you add/remove a file. -# This will then trigger a new cmake run automatically. +# Modify this file to change the last-modified date when you add/remove a file. +# This will then trigger a new cmake run automatically. file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*") diff --git a/src/config/stk_config.cpp b/src/config/stk_config.cpp index 58650278e..6ca5ce857 100644 --- a/src/config/stk_config.cpp +++ b/src/config/stk_config.cpp @@ -27,7 +27,6 @@ #include "io/xml_node.hpp" #include "items/item.hpp" #include "karts/kart_properties.hpp" -#include "karts/player_difficulty.hpp" #include "utils/log.hpp" STKConfig* stk_config=0; @@ -119,19 +118,8 @@ void STKConfig::load(const std::string &filename) } CHECK_NEG(m_max_karts, "" ); @@ -163,18 +151,13 @@ void STKConfig::load(const std::string &filename) */ void STKConfig::init_defaults() { - m_anvil_weight = m_parachute_friction = - m_parachute_time = m_parachute_lbound_fraction = - m_parachute_time_other = m_anvil_speed_factor = - m_bomb_time = m_bomb_time_increase = - m_anvil_time = m_music_credit_time = + m_bomb_time = m_bomb_time_increase = + m_explosion_impulse_objects = m_music_credit_time = m_delay_finish_time = m_skid_fadeout_time = m_near_ground = m_item_switch_time = - m_smooth_angle_limit = m_parachute_ubound_fraction = - m_penalty_time = m_explosion_impulse_objects = - m_parachute_max_speed = UNDEFINED; + m_smooth_angle_limit = m_penalty_time = + UNDEFINED; m_bubblegum_counter = -100; - m_bubblegum_shield_time = -100; m_shield_restrict_weapos = false; m_max_karts = -100; m_max_skidmarks = -100; @@ -310,23 +293,6 @@ void STKConfig::getAllData(const XMLNode * root) credits_node->get("music", &m_music_credit_time); - if(const XMLNode *anvil_node= root->getNode("anvil")) - { - anvil_node->get("weight", &m_anvil_weight ); - anvil_node->get("speed-factor", &m_anvil_speed_factor); - anvil_node->get("time", &m_anvil_time ); - } - - if(const XMLNode *parachute_node= root->getNode("parachute")) - { - parachute_node->get("friction", &m_parachute_friction ); - parachute_node->get("time", &m_parachute_time ); - parachute_node->get("time-other", &m_parachute_time_other ); - parachute_node->get("lbound-fraction", &m_parachute_lbound_fraction); - parachute_node->get("ubound-fraction", &m_parachute_ubound_fraction); - parachute_node->get("max-speed", &m_parachute_max_speed ); - } - if(const XMLNode *bomb_node= root->getNode("bomb")) { bomb_node->get("time", &m_bomb_time); @@ -359,7 +325,6 @@ void STKConfig::getAllData(const XMLNode * root) if(const XMLNode *bubblegum_node= root->getNode("bubblegum")) { bubblegum_node->get("disappear-counter", &m_bubblegum_counter ); - bubblegum_node->get("shield-time", &m_bubblegum_shield_time ); bubblegum_node->get("restrict-weapons", &m_shield_restrict_weapos); } @@ -415,14 +380,6 @@ void STKConfig::getAllData(const XMLNode * root) m_kart_properties[type->getName()]->copyFrom(m_default_kart_properties); m_kart_properties[type->getName()]->getAllData(type); } - - child_node = node->getNode("difficulties"); - for (unsigned int i = 0; i < child_node->getNumNodes(); ++i) - { - const XMLNode* type = child_node->getNode(i); - m_player_difficulties[i] = new PlayerDifficulty(); - m_player_difficulties[i]->getAllData(type); - } } // getAllData // ---------------------------------------------------------------------------- diff --git a/src/config/stk_config.hpp b/src/config/stk_config.hpp index 62da73c98..89245a0f8 100644 --- a/src/config/stk_config.hpp +++ b/src/config/stk_config.hpp @@ -34,7 +34,6 @@ #include class KartProperties; -class PlayerDifficulty; class MusicInformation; class XMLNode; @@ -51,8 +50,6 @@ protected: /** Default kart properties. */ KartProperties *m_default_kart_properties; std::map m_kart_properties; - /** Per-player difficulties. */ - PlayerDifficulty* m_player_difficulties[PLAYER_DIFFICULTY_COUNT]; public: /** What to do if a kart already has a powerup when it hits a bonus box: @@ -66,26 +63,12 @@ public: m_same_powerup_mode; static float UNDEFINED; - float m_anvil_weight; /**getKartProperties(); float max_increase_with_zipper = kp->getZipperMaxSpeedIncrease(); - float max_speed_without_zipper = kp->getMaxSpeed(); + float max_speed_without_zipper = kp->getEngineMaxSpeed(); float current_speed = m_kart->getSpeed(); const Skidding *ks = m_kart->getSkidding(); @@ -469,7 +469,7 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle, else { *above_kart = 0.75f; - *cam_angle = kp->getCameraForwardUpAngle(); + *cam_angle = kp->getCameraForwardUpAngle() * DEGREE_TO_RAD; *distance = -m_distance; } float steering = m_kart->getSteerPercent() @@ -484,7 +484,7 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle, case CM_REVERSE: // Same as CM_NORMAL except it looks backwards { *above_kart = 0.75f; - *cam_angle = kp->getCameraBackwardUpAngle(); + *cam_angle = kp->getCameraBackwardUpAngle() * DEGREE_TO_RAD; *sideway = 0; *distance = 2.0f*m_distance; *smoothing = false; @@ -843,8 +843,7 @@ void Camera::handleEndCamera(float dt) } case EndCameraInformation::EC_AHEAD_OF_KART: { - const KartProperties *kp=m_kart->getKartProperties(); - float cam_angle = kp->getCameraBackwardUpAngle(); + float cam_angle = m_kart->getKartProperties()->getCameraBackwardUpAngle() * DEGREE_TO_RAD; positionCamera(dt, /*above_kart*/0.75f, cam_angle, /*side_way*/0, diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index fd95af7c3..e9f810d97 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -57,6 +57,7 @@ #include "modes/profile_world.hpp" #include "modes/world.hpp" #include "physics/physics.hpp" +#include "scriptengine/property_animator.hpp" #include "states_screens/dialogs/confirm_resolution_dialog.hpp" #include "states_screens/state_manager.hpp" #include "tracks/track_manager.hpp" @@ -2153,6 +2154,8 @@ void IrrDriver::update(float dt) m_wind->update(); + PropertyAnimator::get()->update(dt); + World *world = World::getWorld(); if (GUIEngine::getCurrentScreen() != NULL && diff --git a/src/graphics/slip_stream.cpp b/src/graphics/slip_stream.cpp index 1cb52b9da..0b59f7407 100644 --- a/src/graphics/slip_stream.cpp +++ b/src/graphics/slip_stream.cpp @@ -25,8 +25,8 @@ #include "graphics/material_manager.hpp" #include "graphics/stk_mesh_scene_node.hpp" #include "io/file_manager.hpp" -#include "karts/controller/controller.hpp" #include "karts/abstract_kart.hpp" +#include "karts/controller/controller.hpp" #include "karts/kart_properties.hpp" #include "karts/max_speed.hpp" #include "modes/world.hpp" @@ -67,11 +67,9 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart) setTextureMatrix(&(m_node->getMaterial(0).getTextureMatrix(0))); m_slipstream_time = 0.0f; - float length = m_kart->getKartProperties()->getSlipstreamLength() * - m_kart->getPlayerDifficulty()->getSlipstreamLength(); + float length = m_kart->getKartProperties()->getSlipstreamLength(); float kw = m_kart->getKartWidth(); - float ew = m_kart->getKartProperties()->getSlipstreamWidth() * - m_kart->getPlayerDifficulty()->getSlipstreamWidth(); + float ew = m_kart->getKartProperties()->getSlipstreamWidth(); float kl = m_kart->getKartLength(); Vec3 p[4]; @@ -314,8 +312,7 @@ void SlipStream::setIntensity(float f, const AbstractKart *kart) bool SlipStream::isSlipstreamReady() const { return m_slipstream_time> - m_kart->getKartProperties()->getSlipstreamCollectTime() * - m_kart->getPlayerDifficulty()->getSlipstreamCollectTime(); + m_kart->getKartProperties()->getSlipstreamCollectTime(); } // isSlipstreamReady //----------------------------------------------------------------------------- @@ -329,16 +326,12 @@ void SlipStream::updateSlipstreamPower() if(m_slipstream_mode==SS_USE) { setIntensity(2.0f, NULL); - const KartProperties *kp=m_kart->getKartProperties(); + const KartProperties *kp = m_kart->getKartProperties(); m_kart->increaseMaxSpeed(MaxSpeed::MS_INCREASE_SLIPSTREAM, - kp->getSlipstreamMaxSpeedIncrease() * - m_kart->getPlayerDifficulty()->getSlipstreamMaxSpeedIncrease(), - kp->getSlipstreamAddPower() * - m_kart->getPlayerDifficulty()->getSlipstreamAddPower(), - kp->getSlipstreamDuration() * - m_kart->getPlayerDifficulty()->getSlipstreamDuration(), - kp->getSlipstreamFadeOutTime() * - m_kart->getPlayerDifficulty()->getSlipstreamFadeOutTime()); + kp->getSlipstreamMaxSpeedIncrease(), + kp->getSlipstreamAddPower(), + kp->getSlipstreamDuration(), + kp->getSlipstreamFadeOutTime()); } } // upateSlipstreamPower @@ -368,6 +361,8 @@ void SlipStream::setDebugColor(const video::SColor &color) */ void SlipStream::update(float dt) { + const KartProperties *kp = m_kart->getKartProperties(); + // Low level AIs should not do any slipstreaming. if(m_kart->getController()->disableSlipstreamBonus()) return; @@ -394,8 +389,7 @@ void SlipStream::update(float dt) // not moving. This is useful for debugging the graphics of SS-ing. //#define DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING #ifndef DISPLAY_SLIPSTREAM_WITH_0_SPEED_FOR_DEBUGGING - if(m_kart->getSpeed()getKartProperties()->getSlipstreamMinSpeed() * - m_kart->getPlayerDifficulty()->getSlipstreamMinSpeed()) + if(m_kart->getSpeed() < kp->getSlipstreamMinSpeed()) { setIntensity(0, NULL); m_slipstream_mode = SS_NONE; @@ -436,9 +430,7 @@ void SlipStream::update(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(m_target_kart->getSpeed() < - m_kart->getKartProperties()->getSlipstreamMinSpeed() * - m_kart->getPlayerDifficulty()->getSlipstreamMinSpeed()) + if (m_target_kart->getSpeed() < kp->getSlipstreamMinSpeed()) { if(UserConfigParams::m_slipstream_debug && m_kart->getController()->isPlayerController()) @@ -452,8 +444,7 @@ void SlipStream::update(float dt) // slipstream length+0.5*kart_length()+0.5*target_kart_length // away from the other kart Vec3 delta = m_kart->getXYZ() - m_target_kart->getXYZ(); - float l = m_kart->getKartProperties()->getSlipstreamLength() * - m_kart->getPlayerDifficulty()->getSlipstreamLength() + float l = kp->getSlipstreamLength() + 0.5f*( m_target_kart->getKartLength() +m_kart->getKartLength() ); if(delta.length2_2d() > l*l) @@ -493,9 +484,7 @@ void SlipStream::update(float dt) { m_slipstream_mode = SS_USE; m_kart->handleZipper(); - m_slipstream_time = - m_kart->getKartProperties()->getSlipstreamCollectTime() * - m_kart->getPlayerDifficulty()->getSlipstreamCollectTime(); + m_slipstream_time = kp->getSlipstreamCollectTime(); return; } } @@ -516,8 +505,7 @@ void SlipStream::update(float dt) setIntensity(m_slipstream_time, m_target_kart); m_slipstream_mode = SS_COLLECT; - if(m_slipstream_time>m_kart->getKartProperties()->getSlipstreamCollectTime() * - m_kart->getPlayerDifficulty()->getSlipstreamCollectTime()) + if (m_slipstream_time > kp->getSlipstreamCollectTime()) { setIntensity(1.0f, m_target_kart); } diff --git a/src/guiengine/widgets/kart_stats_widget.cpp b/src/guiengine/widgets/kart_stats_widget.cpp index 6de73a0d1..ab7400329 100644 --- a/src/guiengine/widgets/kart_stats_widget.cpp +++ b/src/guiengine/widgets/kart_stats_widget.cpp @@ -15,21 +15,19 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include "config/user_config.hpp" #include "guiengine/engine.hpp" #include "guiengine/widgets/kart_stats_widget.hpp" -#include "utils/string_utils.hpp" -#include +#include "karts/abstract_characteristic.hpp" #include "karts/kart_properties.hpp" #include "karts/kart_properties_manager.hpp" - #include "utils/log.hpp" #include "utils/string_utils.hpp" -#include "config/user_config.hpp" - #include #include #include +#include using namespace GUIEngine; using namespace irr::core; @@ -81,15 +79,21 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id, m_children.push_back(skill_bar); } - m_skills[SKILL_MASS]->setValue((int)(props->getMass()/5)); + // Scale the values so they look better + // The scaling factor and offset were found by trial and error. + // It should look nice and you should be able to see the difference between + // different masses or velocities. + m_skills[SKILL_MASS]->setValue((int) + ((props->getCombinedCharacteristic()->getMass() - 20) / 4)); m_skills[SKILL_MASS]->setLabel(_("WEIGHT")); m_skills[SKILL_MASS]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_mass", m_player_id); - m_skills[SKILL_SPEED]->setValue((int)((props->getAbsMaxSpeed()-20)*9)); + m_skills[SKILL_SPEED]->setValue((int) + ((props->getCombinedCharacteristic()->getEngineMaxSpeed() - 15) * 6)); m_skills[SKILL_SPEED]->setLabel(_("SPEED")); m_skills[SKILL_SPEED]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_speed", m_player_id); - m_skills[SKILL_POWER]->setValue((int)(props->getAvgPower())); + m_skills[SKILL_POWER]->setValue((int) ((props->getAvgPower() - 30) / 20)); m_skills[SKILL_POWER]->setLabel(_("POWER")); m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id); diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 3fb4fef28..d016cff26 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -225,6 +225,7 @@ void Attachment::clear() */ void Attachment::hitBanana(Item *item, int new_attachment) { + const KartProperties *kp = m_kart->getKartProperties(); const StateManager::ActivePlayer *const ap = m_kart->getController() ->getPlayer(); if(ap && ap->getConstProfile()==PlayerManager::getCurrentPlayer()) @@ -266,9 +267,7 @@ void Attachment::hitBanana(Item *item, int new_attachment) // default time. This is necessary to avoid that a kart lands on the // same banana again once the explosion animation is finished, giving // the kart the same penalty twice. - float f = std::max(item->getDisableTime(), - m_kart->getKartProperties()->getExplosionTime() * - m_kart->getPlayerDifficulty()->getExplosionTime() + 2.0f); + float f = std::max(item->getDisableTime(), kp->getExplosionDuration() + 2.0f); item->setDisableTime(f); break; } @@ -296,7 +295,7 @@ void Attachment::hitBanana(Item *item, int new_attachment) switch (new_attachment) { case 0: - set( ATTACH_PARACHUTE,stk_config->m_parachute_time+leftover_time); + set(ATTACH_PARACHUTE, kp->getParachuteDuration() + leftover_time); m_initial_speed = m_kart->getSpeed(); // if going very slowly or backwards, @@ -310,12 +309,12 @@ void Attachment::hitBanana(Item *item, int new_attachment) // sound -> playSfx ( SOUND_SHOOMF ) ; break ; case 2: - set( ATTACH_ANVIL, stk_config->m_anvil_time+leftover_time); + set(ATTACH_ANVIL, kp->getAnvilDuration() + leftover_time); // if ( m_kart == m_kart[0] ) // sound -> playSfx ( SOUND_SHOOMF ) ; // Reduce speed once (see description above), all other changes are // handled in Kart::updatePhysics - m_kart->adjustSpeed(stk_config->m_anvil_speed_factor); + m_kart->adjustSpeed(kp->getAnvilSpeedFactor()); m_kart->updateWeight(); break ; } // switch @@ -420,12 +419,14 @@ void Attachment::update(float dt) // This percentage is based on the ratio of // initial_speed / initial_max_speed - float f = m_initial_speed / stk_config->m_parachute_max_speed; + const KartProperties *kp = m_kart->getKartProperties(); + + float f = m_initial_speed / kp->getParachuteMaxSpeed(); if (f > 1.0f) f = 1.0f; // cap fraction if (m_kart->getSpeed() <= m_initial_speed * - (stk_config->m_parachute_lbound_fraction + - f * ( stk_config->m_parachute_ubound_fraction - - stk_config->m_parachute_lbound_fraction))) + (kp->getParachuteLboundFraction() + + f * (kp->getParachuteUboundFraction() + - kp->getParachuteLboundFraction()))) { m_time_left = -1; } @@ -507,6 +508,12 @@ void Attachment::update(float dt) clear(); } // update +// ---------------------------------------------------------------------------- +float Attachment::weightAdjust() const +{ + return m_type == ATTACH_ANVIL ? m_kart->getKartProperties()->getAnvilWeight() : 0.0f; +} + // ---------------------------------------------------------------------------- /** Inform any eventual plugin when an animation is done. */ void Attachment::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node) diff --git a/src/items/attachment.hpp b/src/items/attachment.hpp index 825db163f..100654bb7 100644 --- a/src/items/attachment.hpp +++ b/src/items/attachment.hpp @@ -130,8 +130,7 @@ public: AbstractKart* getPreviousOwner() const { return m_previous_owner; } // ------------------------------------------------------------------------ /** Returns additional weight for the kart. */ - float weightAdjust() const { - return m_type==ATTACH_ANVIL ? stk_config->m_anvil_weight : 0.0f; } + float weightAdjust() const; // ------------------------------------------------------------------------ /** Return the currently associated scene node (used by e.g the swatter) */ scene::IAnimatedMeshSceneNode* getNode() {return m_node;} diff --git a/src/items/plunger.cpp b/src/items/plunger.cpp index 403340972..e2f69adfb 100644 --- a/src/items/plunger.cpp +++ b/src/items/plunger.cpp @@ -176,8 +176,7 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj) } else { - m_keep_alive = m_owner->getKartProperties()->getRubberBandDuration() * - m_owner->getPlayerDifficulty()->getRubberBandDuration(); + m_keep_alive = m_owner->getKartProperties()->getPlungerBandDuration(); // Make this object invisible by placing it faaar down. Not that if this // objects is simply removed from the scene graph, it might be auto-deleted diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index b354b7aff..3b06e41c6 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -171,6 +171,8 @@ void Powerup::adjustSound() */ void Powerup::use() { + const KartProperties *kp = m_owner->getKartProperties(); + // The player gets an achievement point for using a powerup StateManager::ActivePlayer * player = m_owner->getController()->getPlayer(); if (m_type != PowerupManager::POWERUP_NOTHING && @@ -221,9 +223,7 @@ void Powerup::use() case PowerupManager::POWERUP_SWATTER: m_owner->getAttachment() - ->set(Attachment::ATTACH_SWATTER, - m_owner->getKartProperties()->getSwatterDuration() * - m_owner->getPlayerDifficulty()->getSwatterDuration()); + ->set(Attachment::ATTACH_SWATTER, kp->getSwatterDuration()); break; case PowerupManager::POWERUP_BUBBLEGUM: @@ -258,12 +258,12 @@ void Powerup::use() if (m_owner->getIdent() == "nolok") { m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, - stk_config->m_bubblegum_shield_time); + kp->getBubblegumShieldDuration()); } else { m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD, - stk_config->m_bubblegum_shield_time); + kp->getBubblegumShieldDuration()); } } else // using a bubble gum while still having a shield @@ -271,12 +271,12 @@ void Powerup::use() if (m_owner->getIdent() == "nolok") { m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, - stk_config->m_bubblegum_shield_time + m_owner->getShieldTime()); + kp->getBubblegumShieldDuration() + m_owner->getShieldTime()); } else { m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD, - stk_config->m_bubblegum_shield_time + m_owner->getShieldTime()); + kp->getBubblegumShieldDuration() + m_owner->getShieldTime()); } } @@ -300,9 +300,9 @@ void Powerup::use() if(kart->getPosition() == 1) { kart->getAttachment()->set(Attachment::ATTACH_ANVIL, - stk_config->m_anvil_time); + kp->getAnvilDuration()); kart->updateWeight(); - kart->adjustSpeed(stk_config->m_anvil_speed_factor*0.5f); + kart->adjustSpeed(kp->getAnvilSpeedFactor() * 0.5f); // should we position the sound at the kart that is hit, // or the kart "throwing" the anvil? Ideally it should be both. @@ -337,9 +337,8 @@ void Powerup::use() } if(m_owner->getPosition() > kart->getPosition()) { - kart->getAttachment() - ->set(Attachment::ATTACH_PARACHUTE, - stk_config->m_parachute_time_other); + kart->getAttachment()->set(Attachment::ATTACH_PARACHUTE, + kp->getParachuteDurationOther()); if(kart->getController()->isPlayerController()) player_kart = kart; diff --git a/src/items/rubber_band.cpp b/src/items/rubber_band.cpp index 0c000012b..22c0f9ab5 100644 --- a/src/items/rubber_band.cpp +++ b/src/items/rubber_band.cpp @@ -134,6 +134,8 @@ void RubberBand::updatePosition() */ void RubberBand::update(float dt) { + const KartProperties *kp = m_owner->getKartProperties(); + if(m_owner->isEliminated()) { // Rubber band snaps @@ -149,8 +151,7 @@ void RubberBand::update(float dt) // Check for rubber band snapping // ------------------------------ float l = (m_end_position-k).length2(); - float max_len = m_owner->getKartProperties()->getRubberBandMaxLength() * - m_owner->getPlayerDifficulty()->getRubberBandMaxLength(); + float max_len = kp->getPlungerBandMaxLength(); if(l>max_len*max_len) { // Rubber band snaps @@ -163,8 +164,7 @@ void RubberBand::update(float dt) // ---------------------------- if(m_attached_state!=RB_TO_PLUNGER) { - float force = m_owner->getKartProperties()->getRubberBandForce() * - m_owner->getPlayerDifficulty()->getRubberBandForce(); + float force = kp->getPlungerBandForce(); Vec3 diff = m_end_position-k; // detach rubber band if kart gets very close to hit point @@ -180,12 +180,10 @@ void RubberBand::update(float dt) diff.normalize(); // diff can't be zero here m_owner->getBody()->applyCentralForce(diff*force); m_owner->increaseMaxSpeed(MaxSpeed::MS_INCREASE_RUBBER, - m_owner->getKartProperties()->getRubberBandSpeedIncrease() * - m_owner->getPlayerDifficulty()->getRubberBandSpeedIncrease(), + kp->getPlungerBandSpeedIncrease(), /*engine_force*/ 0.0f, /*duration*/0.1f, - m_owner->getKartProperties()->getRubberBandFadeOutTime() * - m_owner->getPlayerDifficulty()->getRubberBandFadeOutTime()); + kp->getPlungerBandFadeOutTime()); if(m_attached_state==RB_TO_KART) m_hit_kart->getBody()->applyCentralForce(diff*(-force)); } diff --git a/src/items/swatter.cpp b/src/items/swatter.cpp index 386b1ef29..00432133a 100644 --- a/src/items/swatter.cpp +++ b/src/items/swatter.cpp @@ -157,7 +157,7 @@ bool Swatter::updateAndTestFinished(float dt) (m_target->getXYZ()- Vec3(m_scene_node->getAbsolutePosition())) .length2(); float min_dist2 - = m_kart->getKartProperties()->getSwatterDistance2(); + = m_kart->getKartProperties()->getSwatterDistance(); if(dist_to_target2 < min_dist2) { // Start squashing @@ -271,10 +271,10 @@ void Swatter::pointToTarget() */ bool Swatter::squashThingsAround() { - const KartProperties* kp = m_kart->getKartProperties(); + const KartProperties *kp = m_kart->getKartProperties(); // Square of the minimum distance - float min_dist2 = kp->getSwatterDistance2(); - const World* world = World::getWorld(); + 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) @@ -287,7 +287,7 @@ bool Swatter::squashThingsAround() bool target_is_hit = false; // Squash karts around - for(unsigned int i=0; igetNumKarts(); i++) + for(unsigned int i = 0; i < world->getNumKarts(); i++) { AbstractKart *kart = world->getKart(i); // TODO: isSwatterReady() @@ -301,8 +301,7 @@ bool Swatter::squashThingsAround() if(dist2 >= min_dist2) continue; // too far away, ignore this kart - kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(), - kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown()); + kart->setSquash(kp->getSwatterSquashDuration(), kp->getSwatterSquashSlowdown()); target_is_hit = true; //Handle achievement if the swatter is used by the current player diff --git a/src/karts/abstract_characteristic.cpp b/src/karts/abstract_characteristic.cpp new file mode 100755 index 000000000..f25c41150 --- /dev/null +++ b/src/karts/abstract_characteristic.cpp @@ -0,0 +1,1723 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#include "karts/abstract_characteristic.hpp" + +#include "utils/log.hpp" +#include "utils/interpolation_array.hpp" + +#include + +AbstractCharacteristic::AbstractCharacteristic() +{ +} + +// ---------------------------------------------------------------------------- +/** The process function should change the given value. + * The input and output argument is saved in value. + * is_set describes if the value is already set or if it's undefined. + * The function also has to set is_set if the state changed. + */ +void AbstractCharacteristic::process(CharacteristicType type, Value value, + bool *is_set) const +{ + Log::warn("AbstractCharacteristic", "This type does not do anything"); +} // process + +// ---------------------------------------------------------------------------- +/** Returns the type of a given characteristic. */ +AbstractCharacteristic::ValueType AbstractCharacteristic::getType( + CharacteristicType type) +{ + switch (type) + { + case CHARACTERISTIC_COUNT: + Log::fatal("AbstractCharacteristic::getType", "Can't get type of COUNT"); + break; + // Script-generated content generated by tools/create_kart_properties.py getProp1 + // Please don't change the following tag. It will be automatically detected + // by the script and replace the contained content. + // To update the code, use tools/update_characteristics.py + /* */ + case SUSPENSION_STIFFNESS: + return TYPE_FLOAT; + case SUSPENSION_REST: + return TYPE_FLOAT; + case SUSPENSION_TRAVEL: + return TYPE_FLOAT; + case SUSPENSION_EXP_SPRING_RESPONSE: + return TYPE_BOOL; + case SUSPENSION_MAX_FORCE: + return TYPE_FLOAT; + case STABILITY_ROLL_INFLUENCE: + return TYPE_FLOAT; + case STABILITY_CHASSIS_LINEAR_DAMPING: + return TYPE_FLOAT; + case STABILITY_CHASSIS_ANGULAR_DAMPING: + return TYPE_FLOAT; + case STABILITY_DOWNWARD_IMPULSE_FACTOR: + return TYPE_FLOAT; + case STABILITY_TRACK_CONNECTION_ACCEL: + return TYPE_FLOAT; + case STABILITY_SMOOTH_FLYING_IMPULSE: + return TYPE_FLOAT; + case TURN_RADIUS: + return TYPE_INTERPOLATION_ARRAY; + case TURN_TIME_RESET_STEER: + return TYPE_FLOAT; + case TURN_TIME_FULL_STEER: + return TYPE_INTERPOLATION_ARRAY; + case ENGINE_POWER: + return TYPE_FLOAT; + case ENGINE_MAX_SPEED: + return TYPE_FLOAT; + case ENGINE_BRAKE_FACTOR: + return TYPE_FLOAT; + case ENGINE_BRAKE_TIME_INCREASE: + return TYPE_FLOAT; + case ENGINE_MAX_SPEED_REVERSE_RATIO: + return TYPE_FLOAT; + case GEAR_SWITCH_RATIO: + return TYPE_FLOAT_VECTOR; + case GEAR_POWER_INCREASE: + return TYPE_FLOAT_VECTOR; + case MASS: + return TYPE_FLOAT; + case WHEELS_DAMPING_RELAXATION: + return TYPE_FLOAT; + case WHEELS_DAMPING_COMPRESSION: + return TYPE_FLOAT; + case CAMERA_DISTANCE: + return TYPE_FLOAT; + case CAMERA_FORWARD_UP_ANGLE: + return TYPE_FLOAT; + case CAMERA_BACKWARD_UP_ANGLE: + return TYPE_FLOAT; + case JUMP_ANIMATION_TIME: + return TYPE_FLOAT; + case LEAN_MAX: + return TYPE_FLOAT; + case LEAN_SPEED: + return TYPE_FLOAT; + case ANVIL_DURATION: + return TYPE_FLOAT; + case ANVIL_WEIGHT: + return TYPE_FLOAT; + case ANVIL_SPEED_FACTOR: + return TYPE_FLOAT; + case PARACHUTE_FRICTION: + return TYPE_FLOAT; + case PARACHUTE_DURATION: + return TYPE_FLOAT; + case PARACHUTE_DURATION_OTHER: + return TYPE_FLOAT; + case PARACHUTE_LBOUND_FRACTION: + return TYPE_FLOAT; + case PARACHUTE_UBOUND_FRACTION: + return TYPE_FLOAT; + case PARACHUTE_MAX_SPEED: + return TYPE_FLOAT; + case BUBBLEGUM_DURATION: + return TYPE_FLOAT; + case BUBBLEGUM_SPEED_FRACTION: + return TYPE_FLOAT; + case BUBBLEGUM_TORQUE: + return TYPE_FLOAT; + case BUBBLEGUM_FADE_IN_TIME: + return TYPE_FLOAT; + case BUBBLEGUM_SHIELD_DURATION: + return TYPE_FLOAT; + case ZIPPER_DURATION: + return TYPE_FLOAT; + case ZIPPER_FORCE: + return TYPE_FLOAT; + case ZIPPER_SPEED_GAIN: + return TYPE_FLOAT; + case ZIPPER_MAX_SPEED_INCREASE: + return TYPE_FLOAT; + case ZIPPER_FADE_OUT_TIME: + return TYPE_FLOAT; + case SWATTER_DURATION: + return TYPE_FLOAT; + case SWATTER_DISTANCE: + return TYPE_FLOAT; + case SWATTER_SQUASH_DURATION: + return TYPE_FLOAT; + case SWATTER_SQUASH_SLOWDOWN: + return TYPE_FLOAT; + case PLUNGER_BAND_MAX_LENGTH: + return TYPE_FLOAT; + case PLUNGER_BAND_FORCE: + return TYPE_FLOAT; + case PLUNGER_BAND_DURATION: + return TYPE_FLOAT; + case PLUNGER_BAND_SPEED_INCREASE: + return TYPE_FLOAT; + case PLUNGER_BAND_FADE_OUT_TIME: + return TYPE_FLOAT; + case PLUNGER_IN_FACE_TIME: + return TYPE_FLOAT; + case STARTUP_TIME: + return TYPE_FLOAT_VECTOR; + case STARTUP_BOOST: + return TYPE_FLOAT_VECTOR; + case RESCUE_DURATION: + return TYPE_FLOAT; + case RESCUE_VERT_OFFSET: + return TYPE_FLOAT; + case RESCUE_HEIGHT: + return TYPE_FLOAT; + case EXPLOSION_DURATION: + return TYPE_FLOAT; + case EXPLOSION_RADIUS: + return TYPE_FLOAT; + case EXPLOSION_INVULNERABILITY_TIME: + return TYPE_FLOAT; + case NITRO_DURATION: + return TYPE_FLOAT; + case NITRO_ENGINE_FORCE: + return TYPE_FLOAT; + case NITRO_CONSUMPTION: + return TYPE_FLOAT; + case NITRO_SMALL_CONTAINER: + return TYPE_FLOAT; + case NITRO_BIG_CONTAINER: + return TYPE_FLOAT; + case NITRO_MAX_SPEED_INCREASE: + return TYPE_FLOAT; + case NITRO_FADE_OUT_TIME: + return TYPE_FLOAT; + case NITRO_MAX: + return TYPE_FLOAT; + case SLIPSTREAM_DURATION: + return TYPE_FLOAT; + case SLIPSTREAM_LENGTH: + return TYPE_FLOAT; + case SLIPSTREAM_WIDTH: + return TYPE_FLOAT; + case SLIPSTREAM_COLLECT_TIME: + return TYPE_FLOAT; + case SLIPSTREAM_USE_TIME: + return TYPE_FLOAT; + case SLIPSTREAM_ADD_POWER: + return TYPE_FLOAT; + case SLIPSTREAM_MIN_SPEED: + return TYPE_FLOAT; + case SLIPSTREAM_MAX_SPEED_INCREASE: + return TYPE_FLOAT; + case SLIPSTREAM_FADE_OUT_TIME: + return TYPE_FLOAT; + case SKID_INCREASE: + return TYPE_FLOAT; + case SKID_DECREASE: + return TYPE_FLOAT; + case SKID_MAX: + return TYPE_FLOAT; + case SKID_TIME_TILL_MAX: + return TYPE_FLOAT; + case SKID_VISUAL: + return TYPE_FLOAT; + case SKID_VISUAL_TIME: + return TYPE_FLOAT; + case SKID_REVERT_VISUAL_TIME: + return TYPE_FLOAT; + case SKID_MIN_SPEED: + return TYPE_FLOAT; + case SKID_TIME_TILL_BONUS: + return TYPE_FLOAT_VECTOR; + case SKID_BONUS_SPEED: + return TYPE_FLOAT_VECTOR; + case SKID_BONUS_TIME: + return TYPE_FLOAT_VECTOR; + case SKID_BONUS_FORCE: + return TYPE_FLOAT_VECTOR; + case SKID_PHYSICAL_JUMP_TIME: + return TYPE_FLOAT; + case SKID_GRAPHICAL_JUMP_TIME: + return TYPE_FLOAT; + case SKID_POST_SKID_ROTATE_FACTOR: + return TYPE_FLOAT; + case SKID_REDUCE_TURN_MIN: + return TYPE_FLOAT; + case SKID_REDUCE_TURN_MAX: + return TYPE_FLOAT; + case SKID_ENABLED: + return TYPE_BOOL; + + /* */ + } // switch (type) + Log::fatal("AbstractCharacteristic::getType", "Unknown type"); + return TYPE_FLOAT; +} // getType + +// ---------------------------------------------------------------------------- +/** Converts the enum value to a string. */ +std::string AbstractCharacteristic::getName(CharacteristicType type) +{ + switch (type) + { + case CHARACTERISTIC_COUNT: + return "CHARACTERISTIC_COUNT"; + // Script-generated content generated by tools/create_kart_properties.py getProp2 + // Please don't change the following tag. It will be automatically detected + // by the script and replace the contained content. + // To update the code, use tools/update_characteristics.py + /* */ + case SUSPENSION_STIFFNESS: + return "SUSPENSION_STIFFNESS"; + case SUSPENSION_REST: + return "SUSPENSION_REST"; + case SUSPENSION_TRAVEL: + return "SUSPENSION_TRAVEL"; + case SUSPENSION_EXP_SPRING_RESPONSE: + return "SUSPENSION_EXP_SPRING_RESPONSE"; + case SUSPENSION_MAX_FORCE: + return "SUSPENSION_MAX_FORCE"; + case STABILITY_ROLL_INFLUENCE: + return "STABILITY_ROLL_INFLUENCE"; + case STABILITY_CHASSIS_LINEAR_DAMPING: + return "STABILITY_CHASSIS_LINEAR_DAMPING"; + case STABILITY_CHASSIS_ANGULAR_DAMPING: + return "STABILITY_CHASSIS_ANGULAR_DAMPING"; + case STABILITY_DOWNWARD_IMPULSE_FACTOR: + return "STABILITY_DOWNWARD_IMPULSE_FACTOR"; + case STABILITY_TRACK_CONNECTION_ACCEL: + return "STABILITY_TRACK_CONNECTION_ACCEL"; + case STABILITY_SMOOTH_FLYING_IMPULSE: + return "STABILITY_SMOOTH_FLYING_IMPULSE"; + case TURN_RADIUS: + return "TURN_RADIUS"; + case TURN_TIME_RESET_STEER: + return "TURN_TIME_RESET_STEER"; + case TURN_TIME_FULL_STEER: + return "TURN_TIME_FULL_STEER"; + case ENGINE_POWER: + return "ENGINE_POWER"; + case ENGINE_MAX_SPEED: + return "ENGINE_MAX_SPEED"; + case ENGINE_BRAKE_FACTOR: + return "ENGINE_BRAKE_FACTOR"; + case ENGINE_BRAKE_TIME_INCREASE: + return "ENGINE_BRAKE_TIME_INCREASE"; + case ENGINE_MAX_SPEED_REVERSE_RATIO: + return "ENGINE_MAX_SPEED_REVERSE_RATIO"; + case GEAR_SWITCH_RATIO: + return "GEAR_SWITCH_RATIO"; + case GEAR_POWER_INCREASE: + return "GEAR_POWER_INCREASE"; + case MASS: + return "MASS"; + case WHEELS_DAMPING_RELAXATION: + return "WHEELS_DAMPING_RELAXATION"; + case WHEELS_DAMPING_COMPRESSION: + return "WHEELS_DAMPING_COMPRESSION"; + case CAMERA_DISTANCE: + return "CAMERA_DISTANCE"; + case CAMERA_FORWARD_UP_ANGLE: + return "CAMERA_FORWARD_UP_ANGLE"; + case CAMERA_BACKWARD_UP_ANGLE: + return "CAMERA_BACKWARD_UP_ANGLE"; + case JUMP_ANIMATION_TIME: + return "JUMP_ANIMATION_TIME"; + case LEAN_MAX: + return "LEAN_MAX"; + case LEAN_SPEED: + return "LEAN_SPEED"; + case ANVIL_DURATION: + return "ANVIL_DURATION"; + case ANVIL_WEIGHT: + return "ANVIL_WEIGHT"; + case ANVIL_SPEED_FACTOR: + return "ANVIL_SPEED_FACTOR"; + case PARACHUTE_FRICTION: + return "PARACHUTE_FRICTION"; + case PARACHUTE_DURATION: + return "PARACHUTE_DURATION"; + case PARACHUTE_DURATION_OTHER: + return "PARACHUTE_DURATION_OTHER"; + case PARACHUTE_LBOUND_FRACTION: + return "PARACHUTE_LBOUND_FRACTION"; + case PARACHUTE_UBOUND_FRACTION: + return "PARACHUTE_UBOUND_FRACTION"; + case PARACHUTE_MAX_SPEED: + return "PARACHUTE_MAX_SPEED"; + case BUBBLEGUM_DURATION: + return "BUBBLEGUM_DURATION"; + case BUBBLEGUM_SPEED_FRACTION: + return "BUBBLEGUM_SPEED_FRACTION"; + case BUBBLEGUM_TORQUE: + return "BUBBLEGUM_TORQUE"; + case BUBBLEGUM_FADE_IN_TIME: + return "BUBBLEGUM_FADE_IN_TIME"; + case BUBBLEGUM_SHIELD_DURATION: + return "BUBBLEGUM_SHIELD_DURATION"; + case ZIPPER_DURATION: + return "ZIPPER_DURATION"; + case ZIPPER_FORCE: + return "ZIPPER_FORCE"; + case ZIPPER_SPEED_GAIN: + return "ZIPPER_SPEED_GAIN"; + case ZIPPER_MAX_SPEED_INCREASE: + return "ZIPPER_MAX_SPEED_INCREASE"; + case ZIPPER_FADE_OUT_TIME: + return "ZIPPER_FADE_OUT_TIME"; + case SWATTER_DURATION: + return "SWATTER_DURATION"; + case SWATTER_DISTANCE: + return "SWATTER_DISTANCE"; + case SWATTER_SQUASH_DURATION: + return "SWATTER_SQUASH_DURATION"; + case SWATTER_SQUASH_SLOWDOWN: + return "SWATTER_SQUASH_SLOWDOWN"; + case PLUNGER_BAND_MAX_LENGTH: + return "PLUNGER_BAND_MAX_LENGTH"; + case PLUNGER_BAND_FORCE: + return "PLUNGER_BAND_FORCE"; + case PLUNGER_BAND_DURATION: + return "PLUNGER_BAND_DURATION"; + case PLUNGER_BAND_SPEED_INCREASE: + return "PLUNGER_BAND_SPEED_INCREASE"; + case PLUNGER_BAND_FADE_OUT_TIME: + return "PLUNGER_BAND_FADE_OUT_TIME"; + case PLUNGER_IN_FACE_TIME: + return "PLUNGER_IN_FACE_TIME"; + case STARTUP_TIME: + return "STARTUP_TIME"; + case STARTUP_BOOST: + return "STARTUP_BOOST"; + case RESCUE_DURATION: + return "RESCUE_DURATION"; + case RESCUE_VERT_OFFSET: + return "RESCUE_VERT_OFFSET"; + case RESCUE_HEIGHT: + return "RESCUE_HEIGHT"; + case EXPLOSION_DURATION: + return "EXPLOSION_DURATION"; + case EXPLOSION_RADIUS: + return "EXPLOSION_RADIUS"; + case EXPLOSION_INVULNERABILITY_TIME: + return "EXPLOSION_INVULNERABILITY_TIME"; + case NITRO_DURATION: + return "NITRO_DURATION"; + case NITRO_ENGINE_FORCE: + return "NITRO_ENGINE_FORCE"; + case NITRO_CONSUMPTION: + return "NITRO_CONSUMPTION"; + case NITRO_SMALL_CONTAINER: + return "NITRO_SMALL_CONTAINER"; + case NITRO_BIG_CONTAINER: + return "NITRO_BIG_CONTAINER"; + case NITRO_MAX_SPEED_INCREASE: + return "NITRO_MAX_SPEED_INCREASE"; + case NITRO_FADE_OUT_TIME: + return "NITRO_FADE_OUT_TIME"; + case NITRO_MAX: + return "NITRO_MAX"; + case SLIPSTREAM_DURATION: + return "SLIPSTREAM_DURATION"; + case SLIPSTREAM_LENGTH: + return "SLIPSTREAM_LENGTH"; + case SLIPSTREAM_WIDTH: + return "SLIPSTREAM_WIDTH"; + case SLIPSTREAM_COLLECT_TIME: + return "SLIPSTREAM_COLLECT_TIME"; + case SLIPSTREAM_USE_TIME: + return "SLIPSTREAM_USE_TIME"; + case SLIPSTREAM_ADD_POWER: + return "SLIPSTREAM_ADD_POWER"; + case SLIPSTREAM_MIN_SPEED: + return "SLIPSTREAM_MIN_SPEED"; + case SLIPSTREAM_MAX_SPEED_INCREASE: + return "SLIPSTREAM_MAX_SPEED_INCREASE"; + case SLIPSTREAM_FADE_OUT_TIME: + return "SLIPSTREAM_FADE_OUT_TIME"; + case SKID_INCREASE: + return "SKID_INCREASE"; + case SKID_DECREASE: + return "SKID_DECREASE"; + case SKID_MAX: + return "SKID_MAX"; + case SKID_TIME_TILL_MAX: + return "SKID_TIME_TILL_MAX"; + case SKID_VISUAL: + return "SKID_VISUAL"; + case SKID_VISUAL_TIME: + return "SKID_VISUAL_TIME"; + case SKID_REVERT_VISUAL_TIME: + return "SKID_REVERT_VISUAL_TIME"; + case SKID_MIN_SPEED: + return "SKID_MIN_SPEED"; + case SKID_TIME_TILL_BONUS: + return "SKID_TIME_TILL_BONUS"; + case SKID_BONUS_SPEED: + return "SKID_BONUS_SPEED"; + case SKID_BONUS_TIME: + return "SKID_BONUS_TIME"; + case SKID_BONUS_FORCE: + return "SKID_BONUS_FORCE"; + case SKID_PHYSICAL_JUMP_TIME: + return "SKID_PHYSICAL_JUMP_TIME"; + case SKID_GRAPHICAL_JUMP_TIME: + return "SKID_GRAPHICAL_JUMP_TIME"; + case SKID_POST_SKID_ROTATE_FACTOR: + return "SKID_POST_SKID_ROTATE_FACTOR"; + case SKID_REDUCE_TURN_MIN: + return "SKID_REDUCE_TURN_MIN"; + case SKID_REDUCE_TURN_MAX: + return "SKID_REDUCE_TURN_MAX"; + case SKID_ENABLED: + return "SKID_ENABLED"; + + /* */ + } // switch (type) + Log::error("AbstractCharacteristic::getName", "Unknown type"); + return "Unknown type"; +} // getName + +// Script-generated content generated by tools/create_kart_properties.py defs +// Please don't change the following tag. It will be automatically detected +// by the script and replace the contained content. +// To update the code, use tools/update_characteristics.py +/* */ +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSuspensionStiffness() const +{ + float result; + bool is_set = false; + process(SUSPENSION_STIFFNESS, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SUSPENSION_STIFFNESS).c_str()); + return result; +} // getSuspensionStiffness + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSuspensionRest() const +{ + float result; + bool is_set = false; + process(SUSPENSION_REST, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SUSPENSION_REST).c_str()); + return result; +} // getSuspensionRest + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSuspensionTravel() const +{ + float result; + bool is_set = false; + process(SUSPENSION_TRAVEL, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SUSPENSION_TRAVEL).c_str()); + return result; +} // getSuspensionTravel + +// ---------------------------------------------------------------------------- +bool AbstractCharacteristic::getSuspensionExpSpringResponse() const +{ + bool result; + bool is_set = false; + process(SUSPENSION_EXP_SPRING_RESPONSE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SUSPENSION_EXP_SPRING_RESPONSE).c_str()); + return result; +} // getSuspensionExpSpringResponse + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSuspensionMaxForce() const +{ + float result; + bool is_set = false; + process(SUSPENSION_MAX_FORCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SUSPENSION_MAX_FORCE).c_str()); + return result; +} // getSuspensionMaxForce + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getStabilityRollInfluence() const +{ + float result; + bool is_set = false; + process(STABILITY_ROLL_INFLUENCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STABILITY_ROLL_INFLUENCE).c_str()); + return result; +} // getStabilityRollInfluence + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getStabilityChassisLinearDamping() const +{ + float result; + bool is_set = false; + process(STABILITY_CHASSIS_LINEAR_DAMPING, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STABILITY_CHASSIS_LINEAR_DAMPING).c_str()); + return result; +} // getStabilityChassisLinearDamping + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getStabilityChassisAngularDamping() const +{ + float result; + bool is_set = false; + process(STABILITY_CHASSIS_ANGULAR_DAMPING, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STABILITY_CHASSIS_ANGULAR_DAMPING).c_str()); + return result; +} // getStabilityChassisAngularDamping + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getStabilityDownwardImpulseFactor() const +{ + float result; + bool is_set = false; + process(STABILITY_DOWNWARD_IMPULSE_FACTOR, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STABILITY_DOWNWARD_IMPULSE_FACTOR).c_str()); + return result; +} // getStabilityDownwardImpulseFactor + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getStabilityTrackConnectionAccel() const +{ + float result; + bool is_set = false; + process(STABILITY_TRACK_CONNECTION_ACCEL, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STABILITY_TRACK_CONNECTION_ACCEL).c_str()); + return result; +} // getStabilityTrackConnectionAccel + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getStabilitySmoothFlyingImpulse() const +{ + float result; + bool is_set = false; + process(STABILITY_SMOOTH_FLYING_IMPULSE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STABILITY_SMOOTH_FLYING_IMPULSE).c_str()); + return result; +} // getStabilitySmoothFlyingImpulse + +// ---------------------------------------------------------------------------- +InterpolationArray AbstractCharacteristic::getTurnRadius() const +{ + InterpolationArray result; + bool is_set = false; + process(TURN_RADIUS, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(TURN_RADIUS).c_str()); + return result; +} // getTurnRadius + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getTurnTimeResetSteer() const +{ + float result; + bool is_set = false; + process(TURN_TIME_RESET_STEER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(TURN_TIME_RESET_STEER).c_str()); + return result; +} // getTurnTimeResetSteer + +// ---------------------------------------------------------------------------- +InterpolationArray AbstractCharacteristic::getTurnTimeFullSteer() const +{ + InterpolationArray result; + bool is_set = false; + process(TURN_TIME_FULL_STEER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(TURN_TIME_FULL_STEER).c_str()); + return result; +} // getTurnTimeFullSteer + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getEnginePower() const +{ + float result; + bool is_set = false; + process(ENGINE_POWER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ENGINE_POWER).c_str()); + return result; +} // getEnginePower + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getEngineMaxSpeed() const +{ + float result; + bool is_set = false; + process(ENGINE_MAX_SPEED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ENGINE_MAX_SPEED).c_str()); + return result; +} // getEngineMaxSpeed + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getEngineBrakeFactor() const +{ + float result; + bool is_set = false; + process(ENGINE_BRAKE_FACTOR, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ENGINE_BRAKE_FACTOR).c_str()); + return result; +} // getEngineBrakeFactor + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getEngineBrakeTimeIncrease() const +{ + float result; + bool is_set = false; + process(ENGINE_BRAKE_TIME_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ENGINE_BRAKE_TIME_INCREASE).c_str()); + return result; +} // getEngineBrakeTimeIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getEngineMaxSpeedReverseRatio() const +{ + float result; + bool is_set = false; + process(ENGINE_MAX_SPEED_REVERSE_RATIO, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ENGINE_MAX_SPEED_REVERSE_RATIO).c_str()); + return result; +} // getEngineMaxSpeedReverseRatio + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getGearSwitchRatio() const +{ + std::vector result; + bool is_set = false; + process(GEAR_SWITCH_RATIO, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(GEAR_SWITCH_RATIO).c_str()); + return result; +} // getGearSwitchRatio + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getGearPowerIncrease() const +{ + std::vector result; + bool is_set = false; + process(GEAR_POWER_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(GEAR_POWER_INCREASE).c_str()); + return result; +} // getGearPowerIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getMass() const +{ + float result; + bool is_set = false; + process(MASS, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(MASS).c_str()); + return result; +} // getMass + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getWheelsDampingRelaxation() const +{ + float result; + bool is_set = false; + process(WHEELS_DAMPING_RELAXATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(WHEELS_DAMPING_RELAXATION).c_str()); + return result; +} // getWheelsDampingRelaxation + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getWheelsDampingCompression() const +{ + float result; + bool is_set = false; + process(WHEELS_DAMPING_COMPRESSION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(WHEELS_DAMPING_COMPRESSION).c_str()); + return result; +} // getWheelsDampingCompression + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getCameraDistance() const +{ + float result; + bool is_set = false; + process(CAMERA_DISTANCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(CAMERA_DISTANCE).c_str()); + return result; +} // getCameraDistance + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getCameraForwardUpAngle() const +{ + float result; + bool is_set = false; + process(CAMERA_FORWARD_UP_ANGLE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(CAMERA_FORWARD_UP_ANGLE).c_str()); + return result; +} // getCameraForwardUpAngle + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getCameraBackwardUpAngle() const +{ + float result; + bool is_set = false; + process(CAMERA_BACKWARD_UP_ANGLE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(CAMERA_BACKWARD_UP_ANGLE).c_str()); + return result; +} // getCameraBackwardUpAngle + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getJumpAnimationTime() const +{ + float result; + bool is_set = false; + process(JUMP_ANIMATION_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(JUMP_ANIMATION_TIME).c_str()); + return result; +} // getJumpAnimationTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getLeanMax() const +{ + float result; + bool is_set = false; + process(LEAN_MAX, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(LEAN_MAX).c_str()); + return result; +} // getLeanMax + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getLeanSpeed() const +{ + float result; + bool is_set = false; + process(LEAN_SPEED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(LEAN_SPEED).c_str()); + return result; +} // getLeanSpeed + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getAnvilDuration() const +{ + float result; + bool is_set = false; + process(ANVIL_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ANVIL_DURATION).c_str()); + return result; +} // getAnvilDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getAnvilWeight() const +{ + float result; + bool is_set = false; + process(ANVIL_WEIGHT, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ANVIL_WEIGHT).c_str()); + return result; +} // getAnvilWeight + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getAnvilSpeedFactor() const +{ + float result; + bool is_set = false; + process(ANVIL_SPEED_FACTOR, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ANVIL_SPEED_FACTOR).c_str()); + return result; +} // getAnvilSpeedFactor + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getParachuteFriction() const +{ + float result; + bool is_set = false; + process(PARACHUTE_FRICTION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PARACHUTE_FRICTION).c_str()); + return result; +} // getParachuteFriction + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getParachuteDuration() const +{ + float result; + bool is_set = false; + process(PARACHUTE_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PARACHUTE_DURATION).c_str()); + return result; +} // getParachuteDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getParachuteDurationOther() const +{ + float result; + bool is_set = false; + process(PARACHUTE_DURATION_OTHER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PARACHUTE_DURATION_OTHER).c_str()); + return result; +} // getParachuteDurationOther + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getParachuteLboundFraction() const +{ + float result; + bool is_set = false; + process(PARACHUTE_LBOUND_FRACTION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PARACHUTE_LBOUND_FRACTION).c_str()); + return result; +} // getParachuteLboundFraction + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getParachuteUboundFraction() const +{ + float result; + bool is_set = false; + process(PARACHUTE_UBOUND_FRACTION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PARACHUTE_UBOUND_FRACTION).c_str()); + return result; +} // getParachuteUboundFraction + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getParachuteMaxSpeed() const +{ + float result; + bool is_set = false; + process(PARACHUTE_MAX_SPEED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PARACHUTE_MAX_SPEED).c_str()); + return result; +} // getParachuteMaxSpeed + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getBubblegumDuration() const +{ + float result; + bool is_set = false; + process(BUBBLEGUM_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(BUBBLEGUM_DURATION).c_str()); + return result; +} // getBubblegumDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getBubblegumSpeedFraction() const +{ + float result; + bool is_set = false; + process(BUBBLEGUM_SPEED_FRACTION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(BUBBLEGUM_SPEED_FRACTION).c_str()); + return result; +} // getBubblegumSpeedFraction + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getBubblegumTorque() const +{ + float result; + bool is_set = false; + process(BUBBLEGUM_TORQUE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(BUBBLEGUM_TORQUE).c_str()); + return result; +} // getBubblegumTorque + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getBubblegumFadeInTime() const +{ + float result; + bool is_set = false; + process(BUBBLEGUM_FADE_IN_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(BUBBLEGUM_FADE_IN_TIME).c_str()); + return result; +} // getBubblegumFadeInTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getBubblegumShieldDuration() const +{ + float result; + bool is_set = false; + process(BUBBLEGUM_SHIELD_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(BUBBLEGUM_SHIELD_DURATION).c_str()); + return result; +} // getBubblegumShieldDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getZipperDuration() const +{ + float result; + bool is_set = false; + process(ZIPPER_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ZIPPER_DURATION).c_str()); + return result; +} // getZipperDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getZipperForce() const +{ + float result; + bool is_set = false; + process(ZIPPER_FORCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ZIPPER_FORCE).c_str()); + return result; +} // getZipperForce + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getZipperSpeedGain() const +{ + float result; + bool is_set = false; + process(ZIPPER_SPEED_GAIN, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ZIPPER_SPEED_GAIN).c_str()); + return result; +} // getZipperSpeedGain + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getZipperMaxSpeedIncrease() const +{ + float result; + bool is_set = false; + process(ZIPPER_MAX_SPEED_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ZIPPER_MAX_SPEED_INCREASE).c_str()); + return result; +} // getZipperMaxSpeedIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getZipperFadeOutTime() const +{ + float result; + bool is_set = false; + process(ZIPPER_FADE_OUT_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(ZIPPER_FADE_OUT_TIME).c_str()); + return result; +} // getZipperFadeOutTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSwatterDuration() const +{ + float result; + bool is_set = false; + process(SWATTER_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SWATTER_DURATION).c_str()); + return result; +} // getSwatterDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSwatterDistance() const +{ + float result; + bool is_set = false; + process(SWATTER_DISTANCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SWATTER_DISTANCE).c_str()); + return result; +} // getSwatterDistance + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSwatterSquashDuration() const +{ + float result; + bool is_set = false; + process(SWATTER_SQUASH_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SWATTER_SQUASH_DURATION).c_str()); + return result; +} // getSwatterSquashDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSwatterSquashSlowdown() const +{ + float result; + bool is_set = false; + process(SWATTER_SQUASH_SLOWDOWN, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SWATTER_SQUASH_SLOWDOWN).c_str()); + return result; +} // getSwatterSquashSlowdown + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getPlungerBandMaxLength() const +{ + float result; + bool is_set = false; + process(PLUNGER_BAND_MAX_LENGTH, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PLUNGER_BAND_MAX_LENGTH).c_str()); + return result; +} // getPlungerBandMaxLength + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getPlungerBandForce() const +{ + float result; + bool is_set = false; + process(PLUNGER_BAND_FORCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PLUNGER_BAND_FORCE).c_str()); + return result; +} // getPlungerBandForce + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getPlungerBandDuration() const +{ + float result; + bool is_set = false; + process(PLUNGER_BAND_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PLUNGER_BAND_DURATION).c_str()); + return result; +} // getPlungerBandDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getPlungerBandSpeedIncrease() const +{ + float result; + bool is_set = false; + process(PLUNGER_BAND_SPEED_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PLUNGER_BAND_SPEED_INCREASE).c_str()); + return result; +} // getPlungerBandSpeedIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getPlungerBandFadeOutTime() const +{ + float result; + bool is_set = false; + process(PLUNGER_BAND_FADE_OUT_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PLUNGER_BAND_FADE_OUT_TIME).c_str()); + return result; +} // getPlungerBandFadeOutTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getPlungerInFaceTime() const +{ + float result; + bool is_set = false; + process(PLUNGER_IN_FACE_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(PLUNGER_IN_FACE_TIME).c_str()); + return result; +} // getPlungerInFaceTime + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getStartupTime() const +{ + std::vector result; + bool is_set = false; + process(STARTUP_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STARTUP_TIME).c_str()); + return result; +} // getStartupTime + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getStartupBoost() const +{ + std::vector result; + bool is_set = false; + process(STARTUP_BOOST, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(STARTUP_BOOST).c_str()); + return result; +} // getStartupBoost + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getRescueDuration() const +{ + float result; + bool is_set = false; + process(RESCUE_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(RESCUE_DURATION).c_str()); + return result; +} // getRescueDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getRescueVertOffset() const +{ + float result; + bool is_set = false; + process(RESCUE_VERT_OFFSET, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(RESCUE_VERT_OFFSET).c_str()); + return result; +} // getRescueVertOffset + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getRescueHeight() const +{ + float result; + bool is_set = false; + process(RESCUE_HEIGHT, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(RESCUE_HEIGHT).c_str()); + return result; +} // getRescueHeight + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getExplosionDuration() const +{ + float result; + bool is_set = false; + process(EXPLOSION_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(EXPLOSION_DURATION).c_str()); + return result; +} // getExplosionDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getExplosionRadius() const +{ + float result; + bool is_set = false; + process(EXPLOSION_RADIUS, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(EXPLOSION_RADIUS).c_str()); + return result; +} // getExplosionRadius + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getExplosionInvulnerabilityTime() const +{ + float result; + bool is_set = false; + process(EXPLOSION_INVULNERABILITY_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(EXPLOSION_INVULNERABILITY_TIME).c_str()); + return result; +} // getExplosionInvulnerabilityTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroDuration() const +{ + float result; + bool is_set = false; + process(NITRO_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_DURATION).c_str()); + return result; +} // getNitroDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroEngineForce() const +{ + float result; + bool is_set = false; + process(NITRO_ENGINE_FORCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_ENGINE_FORCE).c_str()); + return result; +} // getNitroEngineForce + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroConsumption() const +{ + float result; + bool is_set = false; + process(NITRO_CONSUMPTION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_CONSUMPTION).c_str()); + return result; +} // getNitroConsumption + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroSmallContainer() const +{ + float result; + bool is_set = false; + process(NITRO_SMALL_CONTAINER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_SMALL_CONTAINER).c_str()); + return result; +} // getNitroSmallContainer + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroBigContainer() const +{ + float result; + bool is_set = false; + process(NITRO_BIG_CONTAINER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_BIG_CONTAINER).c_str()); + return result; +} // getNitroBigContainer + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroMaxSpeedIncrease() const +{ + float result; + bool is_set = false; + process(NITRO_MAX_SPEED_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_MAX_SPEED_INCREASE).c_str()); + return result; +} // getNitroMaxSpeedIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroFadeOutTime() const +{ + float result; + bool is_set = false; + process(NITRO_FADE_OUT_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_FADE_OUT_TIME).c_str()); + return result; +} // getNitroFadeOutTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getNitroMax() const +{ + float result; + bool is_set = false; + process(NITRO_MAX, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(NITRO_MAX).c_str()); + return result; +} // getNitroMax + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamDuration() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_DURATION, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_DURATION).c_str()); + return result; +} // getSlipstreamDuration + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamLength() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_LENGTH, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_LENGTH).c_str()); + return result; +} // getSlipstreamLength + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamWidth() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_WIDTH, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_WIDTH).c_str()); + return result; +} // getSlipstreamWidth + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamCollectTime() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_COLLECT_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_COLLECT_TIME).c_str()); + return result; +} // getSlipstreamCollectTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamUseTime() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_USE_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_USE_TIME).c_str()); + return result; +} // getSlipstreamUseTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamAddPower() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_ADD_POWER, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_ADD_POWER).c_str()); + return result; +} // getSlipstreamAddPower + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamMinSpeed() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_MIN_SPEED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_MIN_SPEED).c_str()); + return result; +} // getSlipstreamMinSpeed + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamMaxSpeedIncrease() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_MAX_SPEED_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_MAX_SPEED_INCREASE).c_str()); + return result; +} // getSlipstreamMaxSpeedIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSlipstreamFadeOutTime() const +{ + float result; + bool is_set = false; + process(SLIPSTREAM_FADE_OUT_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SLIPSTREAM_FADE_OUT_TIME).c_str()); + return result; +} // getSlipstreamFadeOutTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidIncrease() const +{ + float result; + bool is_set = false; + process(SKID_INCREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_INCREASE).c_str()); + return result; +} // getSkidIncrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidDecrease() const +{ + float result; + bool is_set = false; + process(SKID_DECREASE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_DECREASE).c_str()); + return result; +} // getSkidDecrease + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidMax() const +{ + float result; + bool is_set = false; + process(SKID_MAX, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_MAX).c_str()); + return result; +} // getSkidMax + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidTimeTillMax() const +{ + float result; + bool is_set = false; + process(SKID_TIME_TILL_MAX, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_TIME_TILL_MAX).c_str()); + return result; +} // getSkidTimeTillMax + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidVisual() const +{ + float result; + bool is_set = false; + process(SKID_VISUAL, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_VISUAL).c_str()); + return result; +} // getSkidVisual + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidVisualTime() const +{ + float result; + bool is_set = false; + process(SKID_VISUAL_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_VISUAL_TIME).c_str()); + return result; +} // getSkidVisualTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidRevertVisualTime() const +{ + float result; + bool is_set = false; + process(SKID_REVERT_VISUAL_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_REVERT_VISUAL_TIME).c_str()); + return result; +} // getSkidRevertVisualTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidMinSpeed() const +{ + float result; + bool is_set = false; + process(SKID_MIN_SPEED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_MIN_SPEED).c_str()); + return result; +} // getSkidMinSpeed + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getSkidTimeTillBonus() const +{ + std::vector result; + bool is_set = false; + process(SKID_TIME_TILL_BONUS, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_TIME_TILL_BONUS).c_str()); + return result; +} // getSkidTimeTillBonus + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getSkidBonusSpeed() const +{ + std::vector result; + bool is_set = false; + process(SKID_BONUS_SPEED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_BONUS_SPEED).c_str()); + return result; +} // getSkidBonusSpeed + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getSkidBonusTime() const +{ + std::vector result; + bool is_set = false; + process(SKID_BONUS_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_BONUS_TIME).c_str()); + return result; +} // getSkidBonusTime + +// ---------------------------------------------------------------------------- +std::vector AbstractCharacteristic::getSkidBonusForce() const +{ + std::vector result; + bool is_set = false; + process(SKID_BONUS_FORCE, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_BONUS_FORCE).c_str()); + return result; +} // getSkidBonusForce + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidPhysicalJumpTime() const +{ + float result; + bool is_set = false; + process(SKID_PHYSICAL_JUMP_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_PHYSICAL_JUMP_TIME).c_str()); + return result; +} // getSkidPhysicalJumpTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidGraphicalJumpTime() const +{ + float result; + bool is_set = false; + process(SKID_GRAPHICAL_JUMP_TIME, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_GRAPHICAL_JUMP_TIME).c_str()); + return result; +} // getSkidGraphicalJumpTime + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidPostSkidRotateFactor() const +{ + float result; + bool is_set = false; + process(SKID_POST_SKID_ROTATE_FACTOR, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_POST_SKID_ROTATE_FACTOR).c_str()); + return result; +} // getSkidPostSkidRotateFactor + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidReduceTurnMin() const +{ + float result; + bool is_set = false; + process(SKID_REDUCE_TURN_MIN, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_REDUCE_TURN_MIN).c_str()); + return result; +} // getSkidReduceTurnMin + +// ---------------------------------------------------------------------------- +float AbstractCharacteristic::getSkidReduceTurnMax() const +{ + float result; + bool is_set = false; + process(SKID_REDUCE_TURN_MAX, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_REDUCE_TURN_MAX).c_str()); + return result; +} // getSkidReduceTurnMax + +// ---------------------------------------------------------------------------- +bool AbstractCharacteristic::getSkidEnabled() const +{ + bool result; + bool is_set = false; + process(SKID_ENABLED, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName(SKID_ENABLED).c_str()); + return result; +} // getSkidEnabled + + +/* */ + diff --git a/src/karts/abstract_characteristic.hpp b/src/karts/abstract_characteristic.hpp new file mode 100755 index 000000000..0f1ac3d2c --- /dev/null +++ b/src/karts/abstract_characteristic.hpp @@ -0,0 +1,383 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#ifndef HEADER_ABSTRACT_CHARACTERISTICS_HPP +#define HEADER_ABSTRACT_CHARACTERISTICS_HPP + +#include +#include + +class InterpolationArray; + +/** + * Characteristics are the properties of a kart that influence + * gameplay mechanics. + * The biggest parts are: + * - Physics + * - Visuals + * - Items + * - and miscellaneous properties like nitro and startup boost. + * + * The documentation of these properties can be found in + * the kart_characteristics.xml file. + * Large parts of this file are generated by tools/create_kart_properties.py. + * Please don't change the generated code here, instead change the script, + * regenerate the code and overwrite the whole generated part with the result. + */ +class AbstractCharacteristic +{ +public: + union Value + { + float *f; + bool *b; + std::vector *fv; + InterpolationArray *ia; + + Value(float *f) : f(f) {} + Value(bool *b) : b(b) {} + Value(std::vector *fv) : fv(fv) {} + Value(InterpolationArray *ia) : ia(ia) {} + }; + + enum ValueType + { + TYPE_FLOAT, + TYPE_BOOL, + TYPE_FLOAT_VECTOR, + TYPE_INTERPOLATION_ARRAY + }; + + enum CharacteristicType + { + // Script-generated content generated by tools/create_kart_properties.py enum + // Please don't change the following tag. It will be automatically detected + // by the script and replace the contained content. + // To update the code, use tools/update_characteristics.py + /* */ + + // Suspension + SUSPENSION_STIFFNESS, + SUSPENSION_REST, + SUSPENSION_TRAVEL, + SUSPENSION_EXP_SPRING_RESPONSE, + SUSPENSION_MAX_FORCE, + + // Stability + STABILITY_ROLL_INFLUENCE, + STABILITY_CHASSIS_LINEAR_DAMPING, + STABILITY_CHASSIS_ANGULAR_DAMPING, + STABILITY_DOWNWARD_IMPULSE_FACTOR, + STABILITY_TRACK_CONNECTION_ACCEL, + STABILITY_SMOOTH_FLYING_IMPULSE, + + // Turn + TURN_RADIUS, + TURN_TIME_RESET_STEER, + TURN_TIME_FULL_STEER, + + // Engine + ENGINE_POWER, + ENGINE_MAX_SPEED, + ENGINE_BRAKE_FACTOR, + ENGINE_BRAKE_TIME_INCREASE, + ENGINE_MAX_SPEED_REVERSE_RATIO, + + // Gear + GEAR_SWITCH_RATIO, + GEAR_POWER_INCREASE, + + // Mass + MASS, + + // Wheels + WHEELS_DAMPING_RELAXATION, + WHEELS_DAMPING_COMPRESSION, + + // Camera + CAMERA_DISTANCE, + CAMERA_FORWARD_UP_ANGLE, + CAMERA_BACKWARD_UP_ANGLE, + + // Jump + JUMP_ANIMATION_TIME, + + // Lean + LEAN_MAX, + LEAN_SPEED, + + // Anvil + ANVIL_DURATION, + ANVIL_WEIGHT, + ANVIL_SPEED_FACTOR, + + // Parachute + PARACHUTE_FRICTION, + PARACHUTE_DURATION, + PARACHUTE_DURATION_OTHER, + PARACHUTE_LBOUND_FRACTION, + PARACHUTE_UBOUND_FRACTION, + PARACHUTE_MAX_SPEED, + + // Bubblegum + BUBBLEGUM_DURATION, + BUBBLEGUM_SPEED_FRACTION, + BUBBLEGUM_TORQUE, + BUBBLEGUM_FADE_IN_TIME, + BUBBLEGUM_SHIELD_DURATION, + + // Zipper + ZIPPER_DURATION, + ZIPPER_FORCE, + ZIPPER_SPEED_GAIN, + ZIPPER_MAX_SPEED_INCREASE, + ZIPPER_FADE_OUT_TIME, + + // Swatter + SWATTER_DURATION, + SWATTER_DISTANCE, + SWATTER_SQUASH_DURATION, + SWATTER_SQUASH_SLOWDOWN, + + // Plunger + PLUNGER_BAND_MAX_LENGTH, + PLUNGER_BAND_FORCE, + PLUNGER_BAND_DURATION, + PLUNGER_BAND_SPEED_INCREASE, + PLUNGER_BAND_FADE_OUT_TIME, + PLUNGER_IN_FACE_TIME, + + // Startup + STARTUP_TIME, + STARTUP_BOOST, + + // Rescue + RESCUE_DURATION, + RESCUE_VERT_OFFSET, + RESCUE_HEIGHT, + + // Explosion + EXPLOSION_DURATION, + EXPLOSION_RADIUS, + EXPLOSION_INVULNERABILITY_TIME, + + // Nitro + NITRO_DURATION, + NITRO_ENGINE_FORCE, + NITRO_CONSUMPTION, + NITRO_SMALL_CONTAINER, + NITRO_BIG_CONTAINER, + NITRO_MAX_SPEED_INCREASE, + NITRO_FADE_OUT_TIME, + NITRO_MAX, + + // Slipstream + SLIPSTREAM_DURATION, + SLIPSTREAM_LENGTH, + SLIPSTREAM_WIDTH, + SLIPSTREAM_COLLECT_TIME, + SLIPSTREAM_USE_TIME, + SLIPSTREAM_ADD_POWER, + SLIPSTREAM_MIN_SPEED, + SLIPSTREAM_MAX_SPEED_INCREASE, + SLIPSTREAM_FADE_OUT_TIME, + + // Skid + SKID_INCREASE, + SKID_DECREASE, + SKID_MAX, + SKID_TIME_TILL_MAX, + SKID_VISUAL, + SKID_VISUAL_TIME, + SKID_REVERT_VISUAL_TIME, + SKID_MIN_SPEED, + SKID_TIME_TILL_BONUS, + SKID_BONUS_SPEED, + SKID_BONUS_TIME, + SKID_BONUS_FORCE, + SKID_PHYSICAL_JUMP_TIME, + SKID_GRAPHICAL_JUMP_TIME, + SKID_POST_SKID_ROTATE_FACTOR, + SKID_REDUCE_TURN_MIN, + SKID_REDUCE_TURN_MAX, + SKID_ENABLED, + + /* */ + + + // Count + CHARACTERISTIC_COUNT + }; + +public: + AbstractCharacteristic(); + virtual ~AbstractCharacteristic() {} + + /** + * The process function is the core of this characteristics system. + * Any computation of the properties should happen here and modify the + * values of the value-pointer (be sure to use the right type!) and the + * is_set parameter when the value was set by the call (and wasn't set + * before). + * + * \param type The characteristic that should be modified. + * \param value The current value and result at the same time. + * \param is_set If the current value was already set (so it can be used + * for computations). + */ + virtual void process(CharacteristicType type, Value value, bool *is_set) const; + + static ValueType getType(CharacteristicType type); + static std::string getName(CharacteristicType type); + + + // Script-generated content generated by tools/create_kart_properties.py defs + // Please don't change the following tag. It will be automatically detected + // by the script and replace the contained content. + // To update the code, use tools/update_characteristics.py + /* */ + + float getSuspensionStiffness() const; + float getSuspensionRest() const; + float getSuspensionTravel() const; + bool getSuspensionExpSpringResponse() const; + float getSuspensionMaxForce() const; + + float getStabilityRollInfluence() const; + float getStabilityChassisLinearDamping() const; + float getStabilityChassisAngularDamping() const; + float getStabilityDownwardImpulseFactor() const; + float getStabilityTrackConnectionAccel() const; + float getStabilitySmoothFlyingImpulse() const; + + InterpolationArray getTurnRadius() const; + float getTurnTimeResetSteer() const; + InterpolationArray getTurnTimeFullSteer() const; + + float getEnginePower() const; + float getEngineMaxSpeed() const; + float getEngineBrakeFactor() const; + float getEngineBrakeTimeIncrease() const; + float getEngineMaxSpeedReverseRatio() const; + + std::vector getGearSwitchRatio() const; + std::vector getGearPowerIncrease() const; + + float getMass() const; + + float getWheelsDampingRelaxation() const; + float getWheelsDampingCompression() const; + + float getCameraDistance() const; + float getCameraForwardUpAngle() const; + float getCameraBackwardUpAngle() const; + + float getJumpAnimationTime() const; + + float getLeanMax() const; + float getLeanSpeed() const; + + float getAnvilDuration() const; + float getAnvilWeight() const; + float getAnvilSpeedFactor() const; + + float getParachuteFriction() const; + float getParachuteDuration() const; + float getParachuteDurationOther() const; + float getParachuteLboundFraction() const; + float getParachuteUboundFraction() const; + float getParachuteMaxSpeed() const; + + float getBubblegumDuration() const; + float getBubblegumSpeedFraction() const; + float getBubblegumTorque() const; + float getBubblegumFadeInTime() const; + float getBubblegumShieldDuration() const; + + float getZipperDuration() const; + float getZipperForce() const; + float getZipperSpeedGain() const; + float getZipperMaxSpeedIncrease() const; + float getZipperFadeOutTime() const; + + float getSwatterDuration() const; + float getSwatterDistance() const; + float getSwatterSquashDuration() const; + float getSwatterSquashSlowdown() const; + + float getPlungerBandMaxLength() const; + float getPlungerBandForce() const; + float getPlungerBandDuration() const; + float getPlungerBandSpeedIncrease() const; + float getPlungerBandFadeOutTime() const; + float getPlungerInFaceTime() const; + + std::vector getStartupTime() const; + std::vector getStartupBoost() const; + + float getRescueDuration() const; + float getRescueVertOffset() const; + float getRescueHeight() const; + + float getExplosionDuration() const; + float getExplosionRadius() const; + float getExplosionInvulnerabilityTime() const; + + float getNitroDuration() const; + float getNitroEngineForce() const; + float getNitroConsumption() const; + float getNitroSmallContainer() const; + float getNitroBigContainer() const; + float getNitroMaxSpeedIncrease() const; + float getNitroFadeOutTime() const; + float getNitroMax() const; + + float getSlipstreamDuration() const; + float getSlipstreamLength() const; + float getSlipstreamWidth() const; + float getSlipstreamCollectTime() const; + float getSlipstreamUseTime() const; + float getSlipstreamAddPower() const; + float getSlipstreamMinSpeed() const; + float getSlipstreamMaxSpeedIncrease() const; + float getSlipstreamFadeOutTime() const; + + float getSkidIncrease() const; + float getSkidDecrease() const; + float getSkidMax() const; + float getSkidTimeTillMax() const; + float getSkidVisual() const; + float getSkidVisualTime() const; + float getSkidRevertVisualTime() const; + float getSkidMinSpeed() const; + std::vector getSkidTimeTillBonus() const; + std::vector getSkidBonusSpeed() const; + std::vector getSkidBonusTime() const; + std::vector getSkidBonusForce() const; + float getSkidPhysicalJumpTime() const; + float getSkidGraphicalJumpTime() const; + float getSkidPostSkidRotateFactor() const; + float getSkidReduceTurnMin() const; + float getSkidReduceTurnMax() const; + bool getSkidEnabled() const; + + /* */ +}; + +#endif + diff --git a/src/karts/abstract_kart.cpp b/src/karts/abstract_kart.cpp index a88741718..75eea4cbc 100644 --- a/src/karts/abstract_kart.cpp +++ b/src/karts/abstract_kart.cpp @@ -35,14 +35,15 @@ AbstractKart::AbstractKart(const std::string& ident, int world_kart_id, int position, const btTransform& init_transform, - const PlayerDifficulty *difficulty) + PerPlayerDifficulty difficulty) : Moveable() { m_world_kart_id = world_kart_id; - m_kart_properties = kart_properties_manager->getKart(ident); + m_kart_properties.reset(new KartProperties()); + m_kart_properties->copyForPlayer(kart_properties_manager->getKart(ident)); m_difficulty = difficulty; m_kart_animation = NULL; - assert(m_kart_properties != NULL); + assert(m_kart_properties); // We have to take a copy of the kart model, since otherwise // the animations will be mixed up (i.e. different instances of diff --git a/src/karts/abstract_kart.hpp b/src/karts/abstract_kart.hpp index 565d8f3bd..8857889fa 100644 --- a/src/karts/abstract_kart.hpp +++ b/src/karts/abstract_kart.hpp @@ -19,10 +19,11 @@ #ifndef HEADER_ABSTRACT_KART_HPP #define HEADER_ABSTRACT_KART_HPP +#include + #include "items/powerup_manager.hpp" #include "karts/moveable.hpp" #include "karts/controller/kart_control.hpp" -#include "karts/player_difficulty.hpp" #include "race/race_manager.hpp" namespace irr @@ -70,10 +71,10 @@ private: protected: /** The kart properties. */ - const KartProperties *m_kart_properties; + std::unique_ptr m_kart_properties; /** The per-player difficulty. */ - const PlayerDifficulty *m_difficulty; + PerPlayerDifficulty m_difficulty; /** This stores a copy of the kart model. It has to be a copy * since otherwise incosistencies can happen if the same kart @@ -95,7 +96,7 @@ public: AbstractKart(const std::string& ident, int world_kart_id, int position, const btTransform& init_transform, - const PlayerDifficulty *difficulty); + PerPlayerDifficulty difficulty); virtual ~AbstractKart(); virtual core::stringw getName() const; virtual void reset(); @@ -120,20 +121,17 @@ public: // ------------------------------------------------------------------------ /** Returns the kart properties of this kart. */ const KartProperties* getKartProperties() const - { return m_kart_properties; } - // ------------------------------------------------------------------------ - /** Sets the kart properties. */ - void setKartProperties(const KartProperties *kp) { m_kart_properties=kp; } + { return m_kart_properties.get(); } // ======================================================================== // Access to the per-player difficulty. // ------------------------------------------------------------------------ /** Returns the per-player difficulty of this kart. */ - const PlayerDifficulty* getPlayerDifficulty() const + const PerPlayerDifficulty getPerPlayerDifficulty() const { return m_difficulty; } // ------------------------------------------------------------------------ /** Sets the per-player difficulty. */ - void setPlayerDifficulty(const PlayerDifficulty *pd) { m_difficulty=pd; } + void setPerPlayerDifficulty(const PerPlayerDifficulty d) { m_difficulty=d; } // ------------------------------------------------------------------------ /** Returns a unique identifier for this kart (name of the directory the @@ -144,6 +142,10 @@ public: * speed. */ virtual float getMaxSteerAngle () const = 0; // ------------------------------------------------------------------------ + /** Returns the (maximum) speed for a given turn radius. + * \param radius The radius for which the speed needs to be computed. */ + virtual float getSpeedForTurnRadius(float radius) const = 0; + // ------------------------------------------------------------------------ /** Returns the time till full steering is reached for this kart. * This can depend on the current steering value, which must be >= 0. */ diff --git a/src/karts/cached_characteristic.cpp b/src/karts/cached_characteristic.cpp new file mode 100644 index 000000000..0197f963d --- /dev/null +++ b/src/karts/cached_characteristic.cpp @@ -0,0 +1,203 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#include "karts/cached_characteristic.hpp" + +#include "utils/interpolation_array.hpp" + +CachedCharacteristic::CachedCharacteristic(const AbstractCharacteristic *origin) : + m_values(CHARACTERISTIC_COUNT), + m_origin(origin) +{ + updateSource(); +} + +// ---------------------------------------------------------------------------- +/** Deletes all allocated values. */ +CachedCharacteristic::~CachedCharacteristic() +{ + // Delete all not-null values + for (int i = 0; i < CHARACTERISTIC_COUNT; i++) + { + SaveValue &v = m_values[i]; + if (v.content) + { + switch (getType(static_cast(i))) + { + case TYPE_FLOAT: + delete static_cast(v.content); + break; + case TYPE_FLOAT_VECTOR: + delete static_cast*>(v.content); + break; + case TYPE_INTERPOLATION_ARRAY: + delete static_cast(v.content); + break; + case TYPE_BOOL: + delete static_cast(v.content); + break; + } + v.content = nullptr; + } + } +} // ~CachedCharacteristic + +// ---------------------------------------------------------------------------- +/** Recompute the values of all characteristics based on the list of + * source-characteristics. + */ +void CachedCharacteristic::updateSource() +{ + for (int i = 0; i < CHARACTERISTIC_COUNT; i++) + { + SaveValue &v = m_values[i]; + + bool is_set = false; + switch (getType(static_cast(i))) + { + case TYPE_FLOAT: + { + float value; + float *ptr = static_cast(v.content); + m_origin->process(static_cast(i), &value, &is_set); + if (is_set) + { + if (!ptr) + { + float *newPtr = new float(); + v.content = newPtr; + ptr = newPtr; + } + *ptr = value; + } + else + { + if (ptr) + { + delete ptr; + v.content = nullptr; + } + } + break; + } + case TYPE_FLOAT_VECTOR: + { + std::vector value; + std::vector *ptr = static_cast*>(v.content); + m_origin->process(static_cast(i), &value, &is_set); + if (is_set) + { + if (!ptr) + { + std::vector *newPtr = new std::vector(); + v.content = newPtr; + ptr = newPtr; + } + *ptr = value; + } + else + { + if (ptr) + { + delete ptr; + v.content = nullptr; + } + } + break; + } + case TYPE_INTERPOLATION_ARRAY: + { + InterpolationArray value; + InterpolationArray *ptr = static_cast(v.content); + m_origin->process(static_cast(i), &value, &is_set); + if (is_set) + { + if (!ptr) + { + InterpolationArray *newPtr = new InterpolationArray(); + v.content = newPtr; + ptr = newPtr; + } + *ptr = value; + } + else + { + if (ptr) + { + delete ptr; + v.content = nullptr; + } + } + break; + } + case TYPE_BOOL: + { + bool value; + bool *ptr = static_cast(v.content); + m_origin->process(static_cast(i), &value, &is_set); + if (is_set) + { + if (!ptr) + { + bool *newPtr = new bool(); + v.content = newPtr; + ptr = newPtr; + } + *ptr = value; + } + else + { + if (ptr) + { + delete ptr; + v.content = nullptr; + } + } + break; + } + } // switch (type) + } // foreach characteristic +} // updateSource + +// ---------------------------------------------------------------------------- +/** Returns the stored value. */ +void CachedCharacteristic::process(CharacteristicType type, Value value, + bool *is_set) const +{ + void *v = m_values[type].content; + if (v) + { + switch (getType(type)) + { + case TYPE_FLOAT: + *value.f = *static_cast(v); + break; + case TYPE_FLOAT_VECTOR: + *value.fv = *static_cast*>(v); + break; + case TYPE_INTERPOLATION_ARRAY: + *value.ia = *static_cast(v); + break; + case TYPE_BOOL: + *value.b = *static_cast(v); + break; + } + *is_set = true; + } +} // process + diff --git a/src/karts/cached_characteristic.hpp b/src/karts/cached_characteristic.hpp new file mode 100644 index 000000000..71cdebcaa --- /dev/null +++ b/src/karts/cached_characteristic.hpp @@ -0,0 +1,54 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#ifndef HEADER_CACHED_CHARACTERISTICS_HPP +#define HEADER_CACHED_CHARACTERISTICS_HPP + +#include "karts/abstract_characteristic.hpp" + +class CachedCharacteristic : public AbstractCharacteristic +{ +private: + /** Used to store a value. */ + struct SaveValue + { + void *content; + + SaveValue() : content(nullptr) {} + SaveValue(void *content) : content(content) {} + }; + + /** All values for a characteristic. A nullptr means it is not set. */ + std::vector m_values; + + /** The characteristics that hold the original values. */ + const AbstractCharacteristic *m_origin; + +public: + CachedCharacteristic(const AbstractCharacteristic *origin); + CachedCharacteristic(const CachedCharacteristic &characteristics) = delete; + virtual ~CachedCharacteristic(); + + /** Fetches all cached values from the original source. */ + void updateSource(); + + virtual void process(CharacteristicType type, Value value, bool *is_set) const; +}; + +#endif + diff --git a/src/karts/cannon_animation.cpp b/src/karts/cannon_animation.cpp index e89478af6..39ce1a933 100644 --- a/src/karts/cannon_animation.cpp +++ b/src/karts/cannon_animation.cpp @@ -69,7 +69,7 @@ CannonAnimation::~CannonAnimation() m_kart->getHeading() )); m_kart->getBody()->setCenterOfMassTransform(pos); - Vec3 v(0, 0, m_kart->getKartProperties()->getMaxSpeed()); + Vec3 v(0, 0, m_kart->getKartProperties()->getEngineMaxSpeed()); m_kart->setVelocity(pos.getBasis()*v); } // ~CannonAnimation diff --git a/src/karts/combined_characteristic.cpp b/src/karts/combined_characteristic.cpp new file mode 100644 index 000000000..ea6ff77a8 --- /dev/null +++ b/src/karts/combined_characteristic.cpp @@ -0,0 +1,35 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#include "karts/combined_characteristic.hpp" + +void CombinedCharacteristic::addCharacteristic( + const AbstractCharacteristic *characteristic) +{ + m_childs.push_back(characteristic); +} // addCharacteristic + +// ---------------------------------------------------------------------------- +/** Combines all contained source characteristics. */ +void CombinedCharacteristic::process(CharacteristicType type, Value value, + bool *is_set) const +{ + for (const AbstractCharacteristic *characteristic : m_childs) + characteristic->process(type, value, is_set); +} // process + diff --git a/src/karts/combined_characteristic.hpp b/src/karts/combined_characteristic.hpp new file mode 100644 index 000000000..72f89c33b --- /dev/null +++ b/src/karts/combined_characteristic.hpp @@ -0,0 +1,36 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#ifndef HEADER_COMBINDED_CHARACTERISTICS_HPP +#define HEADER_COMBINDED_CHARACTERISTICS_HPP + +#include "karts/abstract_characteristic.hpp" + +class CombinedCharacteristic : public AbstractCharacteristic +{ +private: + std::vector m_childs; + +public: + void addCharacteristic(const AbstractCharacteristic *characteristic); + + virtual void process(CharacteristicType type, Value value, bool *is_set) const; +}; + +#endif + diff --git a/src/karts/controller/ai_base_controller.cpp b/src/karts/controller/ai_base_controller.cpp index 5a495cd53..5afb6595e 100644 --- a/src/karts/controller/ai_base_controller.cpp +++ b/src/karts/controller/ai_base_controller.cpp @@ -22,7 +22,6 @@ #include "config/user_config.hpp" #include "karts/abstract_kart.hpp" #include "karts/kart_properties.hpp" -#include "karts/skidding_properties.hpp" #include "karts/controller/ai_properties.hpp" #include "modes/world.hpp" #include "tracks/track.hpp" @@ -241,8 +240,7 @@ bool AIBaseController::doSkid(float steer_fraction) // FIXME: Disable skidding for now if the new skidding // code is activated, since the AI can not handle this // properly. - if(m_kart->getKartProperties()->getSkiddingProperties() - ->getSkidVisualTime()>0) + if(m_kart->getKartProperties()->getSkidVisualTime() > 0) return false; // Otherwise return if we need a sharp turn (which is diff --git a/src/karts/controller/network_player_controller.cpp b/src/karts/controller/network_player_controller.cpp index b7616c5c3..61ae75113 100644 --- a/src/karts/controller/network_player_controller.cpp +++ b/src/karts/controller/network_player_controller.cpp @@ -197,7 +197,7 @@ void NetworkPlayerController::steer(float dt, int steer_val) // change speed is used. const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) || (steer_val>=0 && m_controls->m_steer>0) ) - ? dt/m_kart->getKartProperties()->getTimeResetSteer() + ? dt/m_kart->getKartProperties()->getTurnTimeResetSteer() : dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer)); if (steer_val < 0) { diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index 249a36908..8272f4cc0 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -256,7 +256,7 @@ void PlayerController::steer(float dt, int steer_val) // change speed is used. const float STEER_CHANGE = ( (steer_val<=0 && m_controls->m_steer<0) || (steer_val>=0 && m_controls->m_steer>0) ) - ? dt/m_kart->getKartProperties()->getTimeResetSteer() + ? dt/m_kart->getKartProperties()->getTurnTimeResetSteer() : dt/m_kart->getTimeFullSteer(fabsf(m_controls->m_steer)); if (steer_val < 0) { diff --git a/src/karts/controller/skidding_ai.cpp b/src/karts/controller/skidding_ai.cpp index b69499e0e..16fd0aefb 100644 --- a/src/karts/controller/skidding_ai.cpp +++ b/src/karts/controller/skidding_ai.cpp @@ -38,7 +38,6 @@ #include "karts/max_speed.hpp" #include "karts/rescue_animation.hpp" #include "karts/skidding.hpp" -#include "karts/skidding_properties.hpp" #include "modes/linear_world.hpp" #include "modes/profile_world.hpp" #include "race/race_manager.hpp" @@ -430,8 +429,7 @@ void SkiddingAI::handleBraking() m_current_track_direction==GraphNode::DIR_RIGHT ) { float max_turn_speed = - m_kart->getKartProperties() - ->getSpeedForTurnRadius(m_current_curve_radius); + m_kart->getSpeedForTurnRadius(m_current_curve_radius); if(m_kart->getSpeed() > 1.5f*max_turn_speed && m_kart->getSpeed()>MIN_SPEED && @@ -1032,6 +1030,8 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle, std::vector *items_to_avoid, std::vector *items_to_collect) { + const KartProperties *kp = m_kart->getKartProperties(); + // Ignore items that are currently disabled if(item->getDisableTime()>0) return; @@ -1052,18 +1052,16 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle, // Positive items: try to collect case Item::ITEM_NITRO_BIG: // Only collect nitro, if it can actually be stored. - if(m_kart->getEnergy() + - m_kart->getKartProperties()->getNitroBigContainer() - > m_kart->getKartProperties()->getNitroMax()) + if (m_kart->getEnergy() + kp->getNitroBigContainer() + > kp->getNitroMax()) return; // fall through: if we have enough space to store a big // container, we can also store a small container, and // finally fall through to the bonus box code. case Item::ITEM_NITRO_SMALL: avoid = false; // Only collect nitro, if it can actually be stored. - if (m_kart->getEnergy() + - m_kart->getKartProperties()->getNitroSmallContainer() - > m_kart->getKartProperties()->getNitroMax()) + if (m_kart->getEnergy() + kp->getNitroSmallContainer() + > kp->getNitroMax()) return; case Item::ITEM_BONUS_BOX: break; @@ -1093,7 +1091,7 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle, // be if the kart would need to turn sharper, therefore stops // skidding, and will get the bonus speed. bool high_speed = (m_kart->getCurrentMaxSpeed() > - m_kart->getKartProperties()->getMaxSpeed() ) || + kp->getEngineMaxSpeed() ) || m_kart->getSkidding()->getSkidBonusReady(); float max_angle = high_speed ? m_ai_properties->m_max_item_angle_high_speed @@ -1355,13 +1353,13 @@ void SkiddingAI::handleItems(const float dt) case PowerupManager::POWERUP_PARACHUTE: // Wait one second more than a previous parachute - if(m_time_since_last_shot > stk_config->m_parachute_time_other+1.0f) + if(m_time_since_last_shot > m_kart->getKartProperties()->getParachuteDurationOther() + 1.0f) m_controls->m_fire = true; break; // POWERUP_PARACHUTE case PowerupManager::POWERUP_ANVIL: // Wait one second more than a previous anvil - if(m_time_since_last_shot < stk_config->m_anvil_time+1.0f) break; + if(m_time_since_last_shot < m_kart->getKartProperties()->getAnvilDuration() + 1.0f) break; if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER) { @@ -1378,7 +1376,7 @@ void SkiddingAI::handleItems(const float dt) case PowerupManager::POWERUP_SWATTER: { // Squared distance for which the swatter works - float d2 = m_kart->getKartProperties()->getSwatterDistance2(); + 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; @@ -2260,7 +2258,6 @@ bool SkiddingAI::doSkid(float steer_fraction) // the actual path is adjusted during the turn. So apply an // experimentally found factor in to get better estimates. duration *= 1.5f; - const Skidding *skidding = m_kart->getSkidding(); // If the remaining estimated time for skidding is too short, stop // it. This code will mostly trigger the bonus at the end of a skid. @@ -2289,8 +2286,8 @@ bool SkiddingAI::doSkid(float steer_fraction) return false; } // If there is a skidding bonus, try to get it. - else if(skidding->getNumberOfBonusTimes()>0 && - skidding->getTimeTillBonus(0) < duration) + else if (m_kart->getKartProperties()->getSkidBonusSpeed().size() > 0 && + m_kart->getKartProperties()->getSkidTimeTillBonus()[0] < duration) { #ifdef DEBUG if(!m_controls->m_skid && m_ai_debug) diff --git a/src/karts/explosion_animation.cpp b/src/karts/explosion_animation.cpp index 8105b2eba..a0c622cce 100644 --- a/src/karts/explosion_animation.cpp +++ b/src/karts/explosion_animation.cpp @@ -78,8 +78,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart, m_xyz = m_kart->getXYZ(); m_orig_y = m_xyz.getY(); m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE); - m_timer = m_kart->getKartProperties()->getExplosionTime() * - m_kart->getPlayerDifficulty()->getExplosionTime(); + m_timer = m_kart->getKartProperties()->getExplosionDuration(); // Non-direct hits will be only affected half as much. if(!direct_hit) m_timer*=0.5f; @@ -106,8 +105,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart, m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f ); // Set invulnerable time, and graphical effects - float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime() * - m_kart->getPlayerDifficulty()->getExplosionInvulnerabilityTime(); + float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime(); m_kart->setInvulnerableTime(t); m_kart->showStarEffect(t); diff --git a/src/karts/ghost_kart.cpp b/src/karts/ghost_kart.cpp index 099116399..885e3dd73 100644 --- a/src/karts/ghost_kart.cpp +++ b/src/karts/ghost_kart.cpp @@ -24,8 +24,7 @@ GhostKart::GhostKart(const std::string& ident) : Kart(ident, /*world kart id*/99999, - /*position*/-1, btTransform(), stk_config->getPlayerDifficulty( - PLAYER_DIFFICULTY_NORMAL)) + /*position*/-1, btTransform(), PLAYER_DIFFICULTY_NORMAL) { m_current_transform = 0; m_next_event = 0; diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index f227c74da..dc3713ad0 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -38,6 +38,8 @@ #include "graphics/stk_text_billboard.hpp" #include "graphics/stars.hpp" #include "guiengine/scalable_font.hpp" +#include "karts/abstract_characteristic.hpp" +#include "karts/cached_characteristic.hpp" #include "karts/explosion_animation.hpp" #include "karts/kart_gfx.hpp" #include "karts/rescue_animation.hpp" @@ -95,7 +97,7 @@ */ Kart::Kart (const std::string& ident, unsigned int world_kart_id, int position, const btTransform& init_transform, - const PlayerDifficulty *difficulty) + PerPlayerDifficulty difficulty) : AbstractKart(ident, world_kart_id, position, init_transform, difficulty) @@ -223,8 +225,7 @@ void Kart::init(RaceManager::KartType type) loadData(type, animations); m_kart_gfx = new KartGFX(this); - m_skidding = new Skidding(this, - m_kart_properties->getSkiddingProperties()); + m_skidding = new Skidding(this); // Create the stars effect m_stars_effect = new Stars(getNode(), @@ -363,8 +364,8 @@ void Kart::reset() // In case that the kart was in the air, in which case its // linear damping is 0 if(m_body) - m_body->setDamping(m_kart_properties->getChassisLinearDamping(), - m_kart_properties->getChassisAngularDamping() ); + m_body->setDamping(m_kart_properties->getStabilityChassisLinearDamping(), + m_kart_properties->getStabilityChassisAngularDamping()); if(m_terrain_sound) { @@ -521,8 +522,7 @@ void Kart::blockViewWithPlunger() { // Avoid that a plunger extends the plunger time if(m_view_blocked_by_plunger<=0 && !isShielded()) - m_view_blocked_by_plunger = - m_kart_properties->getPlungerInFaceTime() * m_difficulty->getPlungerInFaceTime(); + m_view_blocked_by_plunger = m_kart_properties->getPlungerInFaceTime(); if(isShielded()) { decreaseShieldTime(); @@ -553,6 +553,12 @@ btTransform Kart::getAlignedTransform(const float custom_pitch) return trans; } // getAlignedTransform +// ---------------------------------------------------------------------------- +float Kart::getTimeFullSteer(float steer) const +{ + return m_kart_properties->getTurnTimeFullSteer().get(steer); +} // getTimeFullSteer + // ---------------------------------------------------------------------------- /** Creates the physical representation of this kart. Atm it uses the actual * extention of the kart model to determine the size of the collision body. @@ -595,7 +601,7 @@ void Kart::createPhysics() if (y == -1) { int index = (x + 1) / 2 + 1 - z; // get index of wheel - float f = getKartProperties()->getPhysicalWheelPosition(); + float f = m_kart_properties->getPhysicalWheelPosition(); // f < 0 indicates to use the old physics position, i.e. // to place the wheels outside of the chassis if(f<0) @@ -642,8 +648,8 @@ void Kart::createPhysics() createBody(mass, trans, &m_kart_chassis, m_kart_properties->getRestitution()); m_user_pointer.set(this); - m_body->setDamping(m_kart_properties->getChassisLinearDamping(), - m_kart_properties->getChassisAngularDamping() ); + m_body->setDamping(m_kart_properties->getStabilityChassisLinearDamping(), + m_kart_properties->getStabilityChassisAngularDamping() ); // Reset velocities // ---------------- @@ -672,9 +678,9 @@ void Kart::createPhysics() tuning.m_maxSuspensionTravel = m_kart_properties->getSuspensionTravel(); tuning.m_maxSuspensionForce = - m_kart_properties->getMaxSuspensionForce(); + m_kart_properties->getSuspensionMaxForce(); - const Vec3 &cs = getKartProperties()->getGravityCenterShift(); + const Vec3 &cs = m_kart_properties->getGravityCenterShift(); for(unsigned int i=0; i<4; i++) { bool is_front_wheel = i<2; @@ -684,10 +690,10 @@ void Kart::createPhysics() m_kart_model->getWheelGraphicsRadius(i), tuning, is_front_wheel); wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness(); - wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelDampingRelaxation(); - wheel.m_wheelsDampingCompression = m_kart_properties->getWheelDampingCompression(); + wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelsDampingRelaxation(); + wheel.m_wheelsDampingCompression = m_kart_properties->getWheelsDampingCompression(); wheel.m_frictionSlip = m_kart_properties->getFrictionSlip(); - wheel.m_rollInfluence = m_kart_properties->getRollInfluence(); + wheel.m_rollInfluence = m_kart_properties->getStabilityRollInfluence(); } // Obviously these allocs have to be properly managed/freed btTransform t; @@ -780,6 +786,34 @@ void Kart::updateWeight() m_body->setMassProps(mass, inertia); } // updateWeight +// ------------------------------------------------------------------------ +/** Returns the (maximum) speed for a given turn radius. + * \param radius The radius for which the speed needs to be computed. */ +float Kart::getSpeedForTurnRadius(float radius) const +{ + InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius(); + // Convert the turn radius into turn angle + for(std::size_t i = 0; i < turn_angle_at_speed.size(); i++) + turn_angle_at_speed.setY(i, sin(m_kart_properties->getWheelBase() / + turn_angle_at_speed.getY(i))); + + float angle = sin(m_kart_properties->getWheelBase() / radius); + return turn_angle_at_speed.getReverse(angle); +} // getSpeedForTurnRadius + +// ------------------------------------------------------------------------ +/** Returns the maximum steering angle (depending on speed). */ +float Kart::getMaxSteerAngle(float speed) const +{ + InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius(); + // Convert the turn radius into turn angle + for(std::size_t i = 0; i < turn_angle_at_speed.size(); i++) + turn_angle_at_speed.setY(i, sin(m_kart_properties->getWheelBase() / + turn_angle_at_speed.getY(i))); + + return turn_angle_at_speed.get(speed); +} // getMaxSteerAngle + //----------------------------------------------------------------------------- /** Sets that this kart has finished the race and finishing time. It also * notifies the race_manager about the race completion for this kart. @@ -902,16 +936,13 @@ void Kart::collectedItem(Item *item, int add_info) item->getEmitter()->getIdent() == "nolok"); // slow down - m_bubblegum_time = m_kart_properties->getBubblegumTime() * m_difficulty->getBubblegumTime(); + m_bubblegum_time = m_kart_properties->getBubblegumDuration(); m_bubblegum_torque = ((rand()%2) ? m_kart_properties->getBubblegumTorque() - : -m_kart_properties->getBubblegumTorque()) * - m_difficulty->getBubblegumTorque(); + : -m_kart_properties->getBubblegumTorque()); m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE, - m_kart_properties->getBubblegumSpeedFraction() * - m_difficulty->getBubblegumSpeedFraction(), - m_kart_properties->getBubblegumFadeInTime() * - m_difficulty->getBubblegumFadeInTime(), + m_kart_properties->getBubblegumSpeedFraction() , + m_kart_properties->getBubblegumFadeInTime(), m_bubblegum_time); m_goo_sound->setPosition(getXYZ()); m_goo_sound->play(); @@ -927,6 +958,25 @@ void Kart::collectedItem(Item *item, int add_info) } // collectedItem +//----------------------------------------------------------------------------- +/** Called the first time a kart accelerates after 'ready-set-go'. It searches + * through the startup times to find the appropriate slot, and returns the + * speed-boost from the corresponding entry. + * If the kart started too slow (i.e. slower than the longest time in the + * startup times list), it returns 0. + */ +float Kart::getStartupBoost() const +{ + float t = World::getWorld()->getTime(); + std::vector startup_times = m_kart_properties->getStartupTime(); + for (unsigned int i = 0; i < startup_times.size(); i++) + { + if (t <= startup_times[i]) + return m_kart_properties->getStartupBoost()[i]; + } + return 0; +} // getStartupBoost + //----------------------------------------------------------------------------- /** Simulates gears by adjusting the force of the engine. It also takes the * effect of the zipper into account. @@ -938,21 +988,17 @@ float Kart::getActualWheelForce() const std::vector& gear_ratio=m_kart_properties->getGearSwitchRatio(); for(unsigned int i=0; igetMaxSpeed() * - m_difficulty->getMaxSpeed() * gear_ratio[i]) + if(m_speed <= m_kart_properties->getEngineMaxSpeed() * gear_ratio[i]) { - assert(!isnan(m_kart_properties->getMaxPower() * - m_difficulty->getMaxPower())); + assert(!isnan(m_kart_properties->getEnginePower())); assert(!isnan(m_kart_properties->getGearPowerIncrease()[i])); - return m_kart_properties->getMaxPower() * - m_difficulty->getMaxPower() - *m_kart_properties->getGearPowerIncrease()[i] - +add_force; + return m_kart_properties->getEnginePower() + * m_kart_properties->getGearPowerIncrease()[i] + + add_force; } } - assert(!isnan(m_kart_properties->getMaxPower() * m_difficulty->getMaxPower())); - return m_kart_properties->getMaxPower() * m_difficulty->getMaxPower() - +add_force * 2; + assert(!isnan(m_kart_properties->getEnginePower())); + return m_kart_properties->getEnginePower() + add_force * 2; } // getActualWheelForce @@ -1149,12 +1195,12 @@ void Kart::update(float dt) // When the kart is jumping, linear damping reduces the falling speed // of a kart so much that it can appear to be in slow motion. So // disable linear damping if a kart is in the air - m_body->setDamping(0, m_kart_properties->getChassisAngularDamping()); + m_body->setDamping(0, m_kart_properties->getStabilityChassisAngularDamping()); } else { - m_body->setDamping(m_kart_properties->getChassisLinearDamping(), - m_kart_properties->getChassisAngularDamping()); + m_body->setDamping(m_kart_properties->getStabilityChassisLinearDamping(), + m_kart_properties->getStabilityChassisAngularDamping()); } if(m_kart_animation) @@ -1322,7 +1368,7 @@ void Kart::update(float dt) static video::SColor green(255, 61, 87, 23); // draw skidmarks if relevant (we force pink skidmarks on when hitting a bubblegum) - if(m_kart_properties->getSkiddingProperties()->hasSkidmarks()) + if(m_kart_properties->getSkidEnabled()) { m_skidmarks->update(dt, m_bubblegum_time > 0, @@ -1365,7 +1411,7 @@ void Kart::update(float dt) // Jump if either the jump is estimated to be long enough, or // the texture has the jump property set. - if (t > getKartProperties()->getJumpAnimationTime() || + if (t > m_kart_properties->getJumpAnimationTime() || last_m->isJumpTexture()) { m_kart_model->setAnimation(KartModel::AF_JUMP_START); @@ -1660,33 +1706,23 @@ void Kart::handleZipper(const Material *material, bool play_sound) material->getZipperParameter(&max_speed_increase, &duration, &speed_gain, &fade_out_time, &engine_force); if(max_speed_increase<0) - max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease() * - m_difficulty->getZipperMaxSpeedIncrease(); + max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease(); if(duration<0) - duration = m_kart_properties->getZipperTime() * - m_difficulty->getZipperTime(); + duration = m_kart_properties->getZipperDuration(); if(speed_gain<0) - speed_gain = m_kart_properties->getZipperSpeedGain() * - m_difficulty->getZipperSpeedGain(); + speed_gain = m_kart_properties->getZipperSpeedGain(); if(fade_out_time<0) - fade_out_time = m_kart_properties->getZipperFadeOutTime() * - m_difficulty->getZipperFadeOutTime(); + fade_out_time = m_kart_properties->getZipperFadeOutTime(); if(engine_force<0) - engine_force = m_kart_properties->getZipperForce() * - m_difficulty->getZipperForce(); + engine_force = m_kart_properties->getZipperForce(); } else { - max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease() * - m_difficulty->getZipperMaxSpeedIncrease(); - duration = m_kart_properties->getZipperTime() * - m_difficulty->getZipperTime(); - speed_gain = m_kart_properties->getZipperSpeedGain() * - m_difficulty->getZipperSpeedGain(); - fade_out_time = m_kart_properties->getZipperFadeOutTime() * - m_difficulty->getZipperFadeOutTime(); - engine_force = m_kart_properties->getZipperForce() * - m_difficulty->getZipperForce(); + max_speed_increase = m_kart_properties->getZipperMaxSpeedIncrease(); + duration = m_kart_properties->getZipperDuration(); + speed_gain = m_kart_properties->getZipperSpeedGain(); + fade_out_time = m_kart_properties->getZipperFadeOutTime(); + engine_force = m_kart_properties->getZipperForce(); } // Ignore a zipper that's activated while braking if(m_controls.m_brake || m_speed<0) return; @@ -1727,8 +1763,7 @@ void Kart::updateNitro(float dt) return; } - m_collected_energy -= dt * m_kart_properties->getNitroConsumption() * - m_difficulty->getNitroConsumption(); + m_collected_energy -= dt * m_kart_properties->getNitroConsumption(); if (m_collected_energy < 0) { if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING) @@ -1742,14 +1777,10 @@ void Kart::updateNitro(float dt) if(m_nitro_sound->getStatus() != SFXBase::SFX_PLAYING) m_nitro_sound->play(); m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO, - m_kart_properties->getNitroMaxSpeedIncrease() * - m_difficulty->getNitroMaxSpeedIncrease(), - m_kart_properties->getNitroEngineForce() * - m_difficulty->getNitroEngineForce(), - m_kart_properties->getNitroDuration() * - m_difficulty->getNitroDuration(), - m_kart_properties->getNitroFadeOutTime() * - m_difficulty->getNitroFadeOutTime()); + m_kart_properties->getNitroMaxSpeedIncrease(), + m_kart_properties->getNitroEngineForce(), + m_kart_properties->getNitroDuration(), + m_kart_properties->getNitroFadeOutTime()); } else { @@ -1808,7 +1839,7 @@ void Kart::crashed(const Material *m, const Vec3 &normal) #endif const LinearWorld *lw = dynamic_cast(World::getWorld()); - if(getKartProperties()->getTerrainImpulseType() + if(m_kart_properties->getTerrainImpulseType() ==KartProperties::IMPULSE_NORMAL && m_vehicle->getCentralImpulseTime()<=0 ) { @@ -1835,7 +1866,7 @@ void Kart::crashed(const Material *m, const Vec3 &normal) // graph node center (we have to use the previous point since the // kart might have only now reached the new quad, meaning the kart // would be pushed forward). - else if(getKartProperties()->getTerrainImpulseType() + else if(m_kart_properties->getTerrainImpulseType() ==KartProperties::IMPULSE_TO_DRIVELINE && lw && m_vehicle->getCentralImpulseTime()<=0 && World::getWorld()->getTrack()->isPushBackEnabled()) @@ -2038,8 +2069,7 @@ void Kart::updatePhysics(float dt) if(!m_has_started && m_controls.m_accel) { m_has_started = true; - float f = m_kart_properties->getStartupBoost() * - m_difficulty->getStartupBoost(); + float f = getStartupBoost(); m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER, 0.9f*f, f, /*engine_force*/200.0f, @@ -2107,11 +2137,11 @@ void Kart::updatePhysics(float dt) // Only apply if near ground instead of purely based on speed avoiding // the "parachute on top" look. const Vec3 &v = m_body->getLinearVelocity(); - if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravel()*60) + if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravel() * 60) { Vec3 v_clamped = v; // clamp the speed to 99% of the maxium falling speed. - v_clamped.setY(-m_kart_properties->getSuspensionTravel()*60 * 0.99f); + v_clamped.setY(-m_kart_properties->getSuspensionTravel() * 60 * 0.99f); //m_body->setLinearVelocity(v_clamped); } @@ -2213,8 +2243,8 @@ void Kart::updateEnginePowerAndBrakes(float dt) engine_power *= 5.0f; // Lose some traction when skidding, to balance the advantage - if(m_controls.m_skid && - m_kart_properties->getSkiddingProperties()->getSkidVisualTime()==0) + if (m_controls.m_skid && + m_kart_properties->getSkidVisualTime() == 0) engine_power *= 0.5f; applyEngineForce(engine_power*m_controls.m_accel); @@ -2237,10 +2267,8 @@ void Kart::updateEnginePowerAndBrakes(float dt) m_brake_time += dt; // Apply the brakes - include the time dependent brake increase float f = 1 + m_brake_time - * m_kart_properties->getBrakeTimeIncrease() * - m_difficulty->getBrakeTimeIncrease(); - m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor() * - m_difficulty->getBrakeFactor() * f); + * m_kart_properties->getEngineBrakeTimeIncrease(); + m_vehicle->setAllBrakes(m_kart_properties->getEngineBrakeFactor() * f); } else // m_speed < 0 { @@ -2248,8 +2276,7 @@ void Kart::updateEnginePowerAndBrakes(float dt) // going backward, apply reverse gear ratio (unless he goes // too fast backwards) if ( -m_speed < m_max_speed->getCurrentMaxSpeed() - *m_kart_properties->getMaxSpeedReverseRatio() * - m_difficulty->getMaxSpeedReverseRatio()) + *m_kart_properties->getEngineMaxSpeedReverseRatio()) { // The backwards acceleration is artificially increased to // allow players to get "unstuck" quicker if they hit e.g. @@ -2418,7 +2445,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model) m_slipstream = new SlipStream(this); - if(m_kart_properties->getSkiddingProperties()->hasSkidmarks()) + if (m_kart_properties->getSkidEnabled()) { m_skidmarks = new SkidMarks(*this); m_skidmarks->adjustFog( @@ -2428,7 +2455,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model) if (!CVS->supportsShadows()) { - m_shadow = new Shadow(m_kart_properties, m_node, + m_shadow = new Shadow(m_kart_properties.get(), m_node, -m_kart_model->getLowestPoint()); } World::getWorld()->kartAdded(this, m_node); @@ -2602,8 +2629,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz, { // fabs(speed) is important, otherwise the negative number will // become a huge unsigned number in the particle scene node! - nitro_frac = fabsf(getSpeed())/(m_kart_properties->getMaxSpeed() * - m_difficulty->getMaxSpeed() ); + nitro_frac = fabsf(getSpeed()) / (m_kart_properties->getEngineMaxSpeed()); // The speed of the kart can be higher (due to powerups) than // the normal maximum speed of the kart. if(nitro_frac>1.0f) nitro_frac = 1.0f; @@ -2617,8 +2643,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz, // leaning might get less if a kart gets a special that increases // its maximum speed, but not the current speed (by much). On the // other hand, that ratio can often be greater than 1. - float speed_frac = m_speed / m_kart_properties->getMaxSpeed() * - m_difficulty->getMaxSpeed(); + float speed_frac = m_speed / m_kart_properties->getEngineMaxSpeed(); if(speed_frac>1.0f) speed_frac = 1.0f; else if (speed_frac < 0.0f) // no leaning when backwards driving @@ -2626,14 +2651,14 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz, const float steer_frac = m_skidding->getSteeringFraction(); - const float roll_speed = m_kart_properties->getLeanSpeed(); + const float roll_speed = m_kart_properties->getLeanSpeed() * DEGREE_TO_RAD; if(speed_frac > 0.8f && fabsf(steer_frac)>0.5f) { // Use steering ^ 7, which means less effect at lower // steering const float f = m_skidding->getSteeringFraction(); const float f2 = f*f; - const float max_lean = -m_kart_properties->getMaxLean() + const float max_lean = -m_kart_properties->getLeanMax() * DEGREE_TO_RAD * f2*f2*f2*f * speed_frac; if(max_lean>0) diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index d65cdf617..8e53a7ac4 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -31,7 +31,6 @@ #include "items/powerup.hpp" #include "karts/abstract_kart.hpp" #include "karts/kart_properties.hpp" -#include "karts/player_difficulty.hpp" #include "utils/no_copy.hpp" class btKart; @@ -228,7 +227,7 @@ private: public: Kart(const std::string& ident, unsigned int world_kart_id, int position, const btTransform& init_transform, - const PlayerDifficulty *difficulty); + PerPlayerDifficulty difficulty); virtual ~Kart(); virtual void init(RaceManager::KartType type); virtual void kartIsInRestNow(); @@ -236,6 +235,8 @@ public: const btQuaternion& off_rotation); virtual void createPhysics (); virtual void updateWeight (); + virtual float getSpeedForTurnRadius(float radius) const; + virtual float getMaxSteerAngle(float speed) const; virtual bool isInRest () const; virtual void applyEngineForce (float force); @@ -251,6 +252,8 @@ public: float fade_in_time); virtual float getSpeedIncreaseTimeLeft(unsigned int category) const; virtual void collectedItem(Item *item, int random_attachment); + virtual float getStartupBoost() const; + virtual const Material *getMaterial() const; virtual const Material *getLastMaterial() const; /** Returns the pitch of the terrain depending on the heading. */ @@ -331,15 +334,12 @@ public: /** Returns the time till full steering is reached for this kart. * \param steer Current steer value (must be >=0), on which the time till * full steer depends. */ - virtual float getTimeFullSteer(float steer) const - { - return m_kart_properties->getTimeFullSteer(steer); - } // getTimeFullSteer + virtual float getTimeFullSteer(float steer) const; // ------------------------------------------------------------------------ /** Returns the maximum steering angle for this kart, which depends on the * speed. */ virtual float getMaxSteerAngle () const - { return m_kart_properties->getMaxSteerAngle(getSpeed()); } + { return getMaxSteerAngle(getSpeed()); } // ------------------------------------------------------------------------ /** Returns the skidding object for this kart (which can be used to query * skidding related values). */ diff --git a/src/karts/kart_gfx.cpp b/src/karts/kart_gfx.cpp index e1ead98e6..28cf36e8e 100644 --- a/src/karts/kart_gfx.cpp +++ b/src/karts/kart_gfx.cpp @@ -326,8 +326,7 @@ void KartGFX::updateTerrain(const ParticleKind *pk) if (skidding > 1.0f && on_ground) rate = fabsf(m_kart->getControls().m_steer) > 0.8 ? skidding - 1 : 0; else if (speed >= 0.5f && on_ground) - rate = speed/m_kart->getKartProperties()->getMaxSpeed() * - m_kart->getPlayerDifficulty()->getMaxSpeed(); + rate = speed/m_kart->getKartProperties()->getEngineMaxSpeed(); else { pe->setCreationRateAbsolute(0); diff --git a/src/karts/kart_properties.cpp b/src/karts/kart_properties.cpp index b2fb9d376..55a36a297 100644 --- a/src/karts/kart_properties.cpp +++ b/src/karts/kart_properties.cpp @@ -25,9 +25,12 @@ #include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "io/file_manager.hpp" +#include "karts/cached_characteristic.hpp" +#include "karts/combined_characteristic.hpp" #include "karts/controller/ai_properties.hpp" #include "karts/kart_model.hpp" -#include "karts/skidding_properties.hpp" +#include "karts/kart_properties_manager.hpp" +#include "karts/xml_characteristic.hpp" #include "modes/world.hpp" #include "io/xml_node.hpp" #include "utils/constants.hpp" @@ -42,6 +45,17 @@ float KartProperties::UNDEFINED = -99.9f; +std::string KartProperties::getPerPlayerDifficultyAsString(PerPlayerDifficulty d) +{ + switch(d) + { + case PLAYER_DIFFICULTY_NORMAL: return "normal"; break; + case PLAYER_DIFFICULTY_HANDICAP: return "handicap"; break; + default: assert(false); + } + return ""; +} + /** The constructor initialises all values with invalid values. It can later * then be checked (for STKConfig) that all values are indeed defined. * Otherwise the defaults are taken from STKConfig (and since they are all @@ -64,65 +78,27 @@ KartProperties::KartProperties(const std::string &filename) // Set all other values to undefined, so that it can later be tested // if everything is defined properly. - m_mass = m_brake_factor = m_brake_time_increase = - m_time_reset_steer = m_nitro_consumption = m_nitro_engine_force = - m_nitro_small_container = m_nitro_big_container = m_nitro_max = - m_nitro_max_speed_increase = m_nitro_duration = m_nitro_fade_out_time = - m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_base = - m_wheel_damping_compression = m_friction_slip = m_roll_influence = - m_chassis_linear_damping = m_max_suspension_force = - m_chassis_angular_damping = m_suspension_rest = - m_max_speed_reverse_ratio = m_rescue_vert_offset = - m_collision_terrain_impulse = m_collision_impulse = m_restitution = - m_collision_impulse_time = m_suspension_travel = - m_track_connection_accel = m_rubber_band_max_length = - m_rubber_band_force = m_rubber_band_duration = - m_rubber_band_speed_increase = m_rubber_band_fade_out_time = - m_zipper_time = m_zipper_force = m_zipper_speed_gain = - m_zipper_max_speed_increase = m_zipper_fade_out_time = - m_slipstream_length = m_slipstream_width = m_slipstream_collect_time = - m_slipstream_use_time = m_slipstream_add_power = - m_slipstream_min_speed = m_slipstream_max_speed_increase = - m_slipstream_duration = m_slipstream_fade_out_time = - m_camera_distance = m_camera_forward_up_angle = - m_camera_backward_up_angle = m_explosion_invulnerability_time = - m_rescue_time = m_rescue_height = m_explosion_time = - m_explosion_radius = m_max_lean = m_lean_speed = - m_swatter_distance2 = m_swatter_duration = m_squash_slowdown = - m_squash_duration = m_downward_impulse_factor = - m_bubblegum_fade_in_time = m_bubblegum_speed_fraction = - m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time = - m_smooth_flying_impulse = m_physical_wheel_position = - UNDEFINED; - - m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED); - m_max_speed.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED); - m_plunger_in_face_duration.resize(RaceManager::DIFFICULTY_COUNT, - UNDEFINED); + m_wheel_base = m_friction_slip = m_collision_terrain_impulse = + m_collision_impulse = m_restitution = m_collision_impulse_time = + m_max_lean = m_lean_speed = m_physical_wheel_position = UNDEFINED; m_terrain_impulse_type = IMPULSE_NONE; m_gravity_center_shift = Vec3(UNDEFINED); m_bevel_factor = Vec3(UNDEFINED); - m_exp_spring_response = false; m_version = 0; m_color = video::SColor(255, 0, 0, 0); m_shape = 32; // close enough to a circle. m_engine_sfx_type = "engine_small"; - m_kart_model = NULL; m_nitro_min_consumption = 0.53f; // The default constructor for stk_config uses filename="" if (filename != "") { - m_skidding_properties = NULL; - for(unsigned int i=0; im_characteristic) + { + m_characteristic.reset(new XmlCharacteristic()); + *m_characteristic = *source->m_characteristic; + // Combine the characteristics for this object. We can't copy it because + // this object has other pointers (to m_characteristic). + combineCharacteristics(); + } +} // copyForPlayer + +//----------------------------------------------------------------------------- +/** Copies this KartProperties to another one. Important: if you add any * pointers to kart_properties, the data structure they are pointing to * need to be copied here explicitely! * \param source The source kart properties from which to copy this objects' @@ -147,17 +142,13 @@ KartProperties::~KartProperties() */ void KartProperties::copyFrom(const KartProperties *source) { - *this = *source; + copyForPlayer(source); - // After the memcpy any pointers will be shared. - // So all pointer variables need to be separately allocated and assigned. - m_skidding_properties = new SkiddingProperties(); - assert(m_skidding_properties); - *m_skidding_properties = *source->m_skidding_properties; - - for(unsigned int i=0; im_ai_properties[i]; } @@ -194,7 +185,7 @@ void KartProperties::load(const std::string &filename, const std::string &node) // m_kart_model must be initialised after assigning the default // values from stk_config (otherwise all kart_properties will // share the same KartModel - m_kart_model = new KartModel(/*is_master*/true); + m_kart_model.reset(new KartModel(/*is_master*/true)); m_root = StringUtils::getPath(filename)+"/"; m_ident = StringUtils::getBasename(StringUtils::getPath(filename)); @@ -211,10 +202,11 @@ void KartProperties::load(const std::string &filename, const std::string &node) msg << "Couldn't load kart properties '" << filename << "': no kart node."; - delete m_kart_model; throw std::runtime_error(msg.str()); } getAllData(root); + m_characteristic.reset(new XmlCharacteristic(root)); + combineCharacteristics(); } catch(std::exception& err) { @@ -267,7 +259,6 @@ void KartProperties::load(const std::string &filename, const std::string &node) const bool success = m_kart_model->loadModels(*this); if (!success) { - delete m_kart_model; file_manager->popTextureSearchPath(); file_manager->popModelSearchPath(); throw std::runtime_error("Cannot load kart models"); @@ -300,13 +291,6 @@ void KartProperties::load(const std::string &filename, const std::string &node) // used. m_wheel_base = fabsf(m_kart_model->getLength() - 2*0.25f); - // Now convert the turn radius into turn angle: - for(unsigned int i=0; igetTexture(m_shadow_file); irr_driver->unsetTextureErrorMessage(); @@ -315,6 +299,30 @@ void KartProperties::load(const std::string &filename, const std::string &node) } // load +//----------------------------------------------------------------------------- +void KartProperties::combineCharacteristics() +{ + m_combined_characteristic.reset(new CombinedCharacteristic()); + m_combined_characteristic->addCharacteristic(kart_properties_manager-> + getBaseCharacteristic()); + m_combined_characteristic->addCharacteristic(kart_properties_manager-> + getDifficultyCharacteristic(race_manager->getDifficultyAsString( + race_manager->getDifficulty()))); + + // Try to get the kart type + const AbstractCharacteristic *characteristic = kart_properties_manager-> + getKartTypeCharacteristic(m_kart_type); + if (!characteristic) + Log::warn("KartProperties", "Can't find kart type '%s' for kart '%s'", + m_kart_type.c_str(), m_name.c_str()); + else + // Kart type found + m_combined_characteristic->addCharacteristic(characteristic); + + m_combined_characteristic->addCharacteristic(m_characteristic.get()); + m_cached_characteristic.reset(new CachedCharacteristic(m_combined_characteristic.get())); +} // combineCharacteristics + //----------------------------------------------------------------------------- /** Actually reads in the data from the xml file. * \param root Root of the xml tree. @@ -340,7 +348,7 @@ void KartProperties::getAllData(const XMLNode * root) root->get("shadow-x-offset", &m_shadow_x_offset ); root->get("shadow-z-offset", &m_shadow_z_offset ); - root->get("type", &m_kart_type ); + root->get("type", &m_kart_type ); if(const XMLNode *dimensions_node = root->getNode("center")) dimensions_node->get("gravity-shift", &m_gravity_center_shift); @@ -357,21 +365,6 @@ void KartProperties::getAllData(const XMLNode * root) m_ai_properties[RaceManager::DIFFICULTY_BEST]->load(best); } - if(const XMLNode *suspension_node = root->getNode("suspension")) - { - suspension_node->get("stiffness", &m_suspension_stiffness); - suspension_node->get("rest", &m_suspension_rest ); - suspension_node->get("travel", &m_suspension_travel ); - suspension_node->get("exp-spring-response", &m_exp_spring_response ); - suspension_node->get("max-force", &m_max_suspension_force); - } - - if(const XMLNode *wheels_node = root->getNode("wheels")) - { - wheels_node->get("damping-relaxation", &m_wheel_damping_relaxation ); - wheels_node->get("damping-compression", &m_wheel_damping_compression); - } - if(const XMLNode *speed_weighted_objects_node = root->getNode("speed-weighted-objects")) { m_speed_weighted_object_properties.loadFromXMLNode(speed_weighted_objects_node); @@ -380,21 +373,6 @@ void KartProperties::getAllData(const XMLNode * root) if(const XMLNode *friction_node = root->getNode("friction")) friction_node->get("slip", &m_friction_slip); - if(const XMLNode *stability_node = root->getNode("stability")) - { - stability_node->get("roll-influence", - &m_roll_influence ); - stability_node->get("chassis-linear-damping", - &m_chassis_linear_damping ); - stability_node->get("chassis-angular-damping", - &m_chassis_angular_damping); - stability_node->get("downward-impulse-factor", - &m_downward_impulse_factor); - stability_node->get("track-connection-accel", - &m_track_connection_accel ); - stability_node->get("smooth-flying-impulse", &m_smooth_flying_impulse); - } - if(const XMLNode *collision_node = root->getNode("collision")) { collision_node->get("impulse", &m_collision_impulse ); @@ -425,20 +403,6 @@ void KartProperties::getAllData(const XMLNode * root) //TODO: same goes for their rear equivalents - if(const XMLNode *jump_node= root->getNode("jump")) - { - jump_node->get("animation-time", &m_jump_animation_time); - } - - if(const XMLNode *camera_node= root->getNode("camera")) - { - camera_node->get("distance", &m_camera_distance); - camera_node->get("forward-up-angle", &m_camera_forward_up_angle); - m_camera_forward_up_angle *= DEGREE_TO_RAD; - camera_node->get("backward-up-angle", &m_camera_backward_up_angle); - m_camera_backward_up_angle *= DEGREE_TO_RAD; - } - if(const XMLNode *sounds_node= root->getNode("sounds")) { std::string s; @@ -484,152 +448,6 @@ void KartProperties::getAllData(const XMLNode * root) #endif } // if sounds-node exist - if(const XMLNode *nitro_node = root->getNode("nitro")) - { - nitro_node->get("consumption", &m_nitro_consumption ); - nitro_node->get("small-container", &m_nitro_small_container ); - nitro_node->get("big-container", &m_nitro_big_container ); - nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase); - nitro_node->get("engine-force", &m_nitro_engine_force ); - nitro_node->get("duration", &m_nitro_duration ); - nitro_node->get("fade-out-time", &m_nitro_fade_out_time ); - nitro_node->get("max", &m_nitro_max ); - nitro_node->get("min-consumption-time", &m_nitro_min_consumption ); - } - - if(const XMLNode *bubble_node = root->getNode("bubblegum")) - { - bubble_node->get("time", &m_bubblegum_time ); - bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction); - bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time ); - bubble_node->get("torque", &m_bubblegum_torque ); - } - - if(const XMLNode *rescue_node = root->getNode("rescue")) - { - rescue_node->get("vert-offset", &m_rescue_vert_offset); - rescue_node->get("time", &m_rescue_time ); - rescue_node->get("height", &m_rescue_height ); - } - - if(const XMLNode *explosion_node = root->getNode("explosion")) - { - explosion_node->get("time", &m_explosion_time ); - explosion_node->get("radius", &m_explosion_radius); - explosion_node->get("invulnerability-time", - &m_explosion_invulnerability_time); - } - - if(const XMLNode *skid_node = root->getNode("skid")) - { - m_skidding_properties->load(skid_node); - } - - - if(const XMLNode *slipstream_node = root->getNode("slipstream")) - { - slipstream_node->get("length", &m_slipstream_length ); - slipstream_node->get("width", &m_slipstream_width ); - slipstream_node->get("collect-time", &m_slipstream_collect_time ); - slipstream_node->get("use-time", &m_slipstream_use_time ); - slipstream_node->get("add-power", &m_slipstream_add_power ); - slipstream_node->get("min-speed", &m_slipstream_min_speed ); - slipstream_node->get("max-speed-increase", - &m_slipstream_max_speed_increase); - slipstream_node->get("duration", &m_slipstream_duration ); - slipstream_node->get("fade-out-time",&m_slipstream_fade_out_time ); - } - - if(const XMLNode *turn_node = root->getNode("turn")) - { - turn_node->get("time-full-steer", &m_time_full_steer ); - turn_node->get("time-reset-steer", &m_time_reset_steer ); - turn_node->get("turn-radius", &m_turn_angle_at_speed ); - // For now store the turn radius in turn angle, the correct - // value can only be determined later in ::load - } - - if(const XMLNode *engine_node = root->getNode("engine")) - { - engine_node->get("brake-factor", &m_brake_factor); - engine_node->get("brake-time-increase", &m_brake_time_increase); - engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio); - engine_node->get("power", &m_engine_power); - if(m_engine_power.size()!=RaceManager::DIFFICULTY_COUNT) - { - Log::fatal("[KartProperties]", - "Incorrect engine-power specifications for kart '%s'", - getIdent().c_str()); - } - engine_node->get("max-speed", &m_max_speed); - if(m_max_speed.size()!=RaceManager::DIFFICULTY_COUNT) - { - Log::fatal("[KartProperties]", - "Incorrect max-speed specifications for kart '%s'", - getIdent().c_str()); - } - } // if getNode("engine") - - if(const XMLNode *gear_node = root->getNode("gear")) - { - gear_node->get("switch-ratio", &m_gear_switch_ratio ); - gear_node->get("power-increase", &m_gear_power_increase); - } - - if(const XMLNode *mass_node = root->getNode("mass")) - mass_node->get("value", &m_mass); - - if(const XMLNode *plunger_node= root->getNode("plunger")) - { - plunger_node->get("band-max-length", &m_rubber_band_max_length ); - plunger_node->get("band-force", &m_rubber_band_force ); - plunger_node->get("band-duration", &m_rubber_band_duration ); - plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase); - plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time ); - plunger_node->get("in-face-time", &m_plunger_in_face_duration); - if(m_plunger_in_face_duration.size()!=RaceManager::DIFFICULTY_COUNT) - { - Log::fatal("KartProperties", - "Invalid plunger in-face-time specification."); - } - } - - if(const XMLNode *zipper_node= root->getNode("zipper")) - { - zipper_node->get("time", &m_zipper_time ); - zipper_node->get("fade-out-time", &m_zipper_fade_out_time ); - zipper_node->get("force", &m_zipper_force ); - zipper_node->get("speed-gain", &m_zipper_speed_gain ); - zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase); - } - - if(const XMLNode *swatter_node= root->getNode("swatter")) - { - swatter_node->get("duration", &m_swatter_duration ); - swatter_node->get("squash-duration", &m_squash_duration ); - swatter_node->get("squash-slowdown", &m_squash_slowdown ); - if(swatter_node->get("distance", &m_swatter_distance2) ) - { - // Avoid squaring if distance is not defined, so that - // distance2 remains UNDEFINED (which is a negative value) - m_swatter_distance2 *= m_swatter_distance2; - } - } - - if(const XMLNode *lean_node= root->getNode("lean")) - { - lean_node->get("max", &m_max_lean ); - lean_node->get("speed", &m_lean_speed); - m_max_lean *= DEGREE_TO_RAD; - m_lean_speed *= DEGREE_TO_RAD; - } - - if(const XMLNode *startup_node= root->getNode("startup")) - { - startup_node->get("time", &m_startup_times); - startup_node->get("boost", &m_startup_boost); - } - if(m_kart_model) m_kart_model->loadInfo(*root); } // getAllData @@ -642,125 +460,21 @@ void KartProperties::getAllData(const XMLNode * root) */ void KartProperties::checkAllSet(const std::string &filename) { - if(m_gear_switch_ratio.size()==0) - { - Log::fatal("[KartProperties]", - "Missing default value for 'gear-switch-ratio' in '%s'.", - filename.c_str()); - } - if(m_gear_power_increase.size()==0) - { - Log::fatal("[KartProperties]", - "Missing default value for 'gear-power-increase' in '%s'.", - filename.c_str()); - } - if(m_gear_switch_ratio.size()!=m_gear_power_increase.size()) { - Log::error("KartProperties", - "Number of entries for 'gear-switch-ratio' and " - "'gear-power-increase"); - Log::fatal("KartProperties", "in '%s' must be equal.", - filename.c_str()); - } - if(m_startup_boost.size()!=m_startup_times.size()) - { - Log::error("[KartProperties]", - "Number of entried for 'startup times' and 'startup-boost"); - Log::fatal("KartProperties", "must be identical."); - } #define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \ Log::fatal("[KartProperties]", \ "Missing default value for '%s' in '%s'.", \ strA,filename.c_str()); \ } - CHECK_NEG(m_mass, "mass" ); - CHECK_NEG(m_time_reset_steer, "turn time-reset-steer" ); - CHECK_NEG(m_wheel_damping_relaxation, "wheels damping-relaxation" ); - CHECK_NEG(m_wheel_damping_compression, "wheels damping-compression" ); CHECK_NEG(m_friction_slip, "friction slip" ); - CHECK_NEG(m_roll_influence, "stability roll-influence" ); - CHECK_NEG(m_chassis_linear_damping, "stability chassis-linear-damping" ); - CHECK_NEG(m_chassis_angular_damping, "stability chassis-angular-damping"); - CHECK_NEG(m_downward_impulse_factor, "stability downward-impulse-factor"); - CHECK_NEG(m_track_connection_accel, "stability track-connection-accel" ); - CHECK_NEG(m_smooth_flying_impulse, "smooth-flying-impulse" ); - CHECK_NEG(m_max_speed_reverse_ratio, "engine max-speed-reverse-ratio"); - CHECK_NEG(m_brake_factor, "engine brake-factor" ); - CHECK_NEG(m_brake_time_increase, "engine brake-time-increase" ); - CHECK_NEG(m_suspension_stiffness, "suspension stiffness" ); - CHECK_NEG(m_suspension_rest, "suspension rest" ); - CHECK_NEG(m_suspension_travel, "suspension travel" ); - CHECK_NEG(m_max_suspension_force, "suspension max-force" ); + CHECK_NEG(m_collision_terrain_impulse, "collision terrain-impulse" ); CHECK_NEG(m_collision_impulse, "collision impulse" ); CHECK_NEG(m_collision_impulse_time, "collision impulse-time" ); CHECK_NEG(m_restitution, "collision restitution" ); - CHECK_NEG(m_collision_terrain_impulse, "collision terrain-impulse" ); - CHECK_NEG(m_bevel_factor.getX(), "collision bevel-factor" ); - CHECK_NEG(m_bevel_factor.getY(), "collision bevel-factor" ); - CHECK_NEG(m_bevel_factor.getZ(), "collision bevel-factor" ); CHECK_NEG(m_physical_wheel_position, "collision physical-wheel-position"); - CHECK_NEG(m_rubber_band_max_length, "plunger band-max-length" ); - CHECK_NEG(m_rubber_band_force, "plunger band-force" ); - CHECK_NEG(m_rubber_band_duration, "plunger band-duration" ); - CHECK_NEG(m_rubber_band_speed_increase, "plunger band-speed-increase" ); - CHECK_NEG(m_rubber_band_fade_out_time, "plunger band-fade-out-time" ); - CHECK_NEG(m_zipper_time, "zipper-time" ); - CHECK_NEG(m_zipper_fade_out_time, "zipper-fade-out-time" ); - CHECK_NEG(m_zipper_force, "zipper-force" ); - CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" ); - CHECK_NEG(m_zipper_max_speed_increase, "zipper-max-speed-increase" ); - CHECK_NEG(m_slipstream_length, "slipstream length" ); - CHECK_NEG(m_slipstream_width, "slipstream width" ); - CHECK_NEG(m_slipstream_collect_time, "slipstream collect-time" ); - CHECK_NEG(m_slipstream_use_time, "slipstream use-time" ); - CHECK_NEG(m_slipstream_add_power, "slipstream add-power" ); - CHECK_NEG(m_slipstream_min_speed, "slipstream min-speed" ); - CHECK_NEG(m_slipstream_max_speed_increase, - "slipstream max-speed-increase" ); - CHECK_NEG(m_slipstream_duration, "slipstream duration" ); - CHECK_NEG(m_slipstream_fade_out_time, "slipstream fade-out-time" ); - CHECK_NEG(m_camera_distance, "camera distance" ); - CHECK_NEG(m_camera_forward_up_angle, "camera forward-up-angle" ); - CHECK_NEG(m_camera_backward_up_angle, "camera forward-up-angle" ); - CHECK_NEG(m_nitro_consumption, "nitro consumption" ); - CHECK_NEG(m_nitro_big_container, "nitro big-container" ); - CHECK_NEG(m_nitro_small_container, "nitro small-container" ); - CHECK_NEG(m_nitro_max_speed_increase, "nitro max-speed-increase" ); - CHECK_NEG(m_nitro_engine_force, "nitro engine-force" ); - CHECK_NEG(m_nitro_duration, "nitro duration" ); - CHECK_NEG(m_nitro_fade_out_time, "nitro fade-out-time" ); - CHECK_NEG(m_nitro_max, "nitro max" ); - CHECK_NEG(m_bubblegum_time, "bubblegum time" ); - CHECK_NEG(m_bubblegum_speed_fraction, "bubblegum speed-fraction" ); - CHECK_NEG(m_bubblegum_fade_in_time , "bubblegum fade-in-time" ); - CHECK_NEG(m_bubblegum_torque, "bubblegum torque" ); - - CHECK_NEG(m_swatter_distance2, "swatter distance" ); - CHECK_NEG(m_swatter_duration, "swatter duration" ); - CHECK_NEG(m_squash_duration, "swatter squash-duration" ); - CHECK_NEG(m_squash_slowdown, "swatter squash-slowdown" ); - CHECK_NEG(m_max_lean, "lean max" ); - CHECK_NEG(m_lean_speed, "lean speed" ); - - CHECK_NEG(m_rescue_height, "rescue height" ); - CHECK_NEG(m_rescue_time, "rescue time" ); - CHECK_NEG(m_rescue_vert_offset, "rescue vert-offset" ); - CHECK_NEG(m_explosion_time, "explosion time" ); - CHECK_NEG(m_explosion_invulnerability_time, - "explosion invulnerability-time"); - CHECK_NEG(m_explosion_radius, "explosion radius" ); - - for(unsigned int i=RaceManager::DIFFICULTY_FIRST; - i<=RaceManager::DIFFICULTY_LAST; i++) - { - CHECK_NEG(m_max_speed[i], "engine maximum-speed[0]"); - CHECK_NEG(m_engine_power[i], "engine power" ); - CHECK_NEG(m_plunger_in_face_duration[i],"plunger in-face-time"); - } m_speed_weighted_object_properties.checkAllSet(); - m_skidding_properties->checkAllSet(filename); for(unsigned int i=0; icheckAllSet(filename); } // checkAllSet @@ -781,39 +495,653 @@ bool KartProperties::operator<(const KartProperties &other) const return true; } // operator< +// ---------------------------------------------------------------------------- +const AbstractCharacteristic* KartProperties::getCharacteristic() const +{ + return m_characteristic.get(); +} // getCharacteristic + +// ---------------------------------------------------------------------------- +const AbstractCharacteristic* KartProperties::getCombinedCharacteristic() const +{ + return m_combined_characteristic.get(); +} // getCombinedCharacteristic + // ---------------------------------------------------------------------------- bool KartProperties::isInGroup(const std::string &group) const { return std::find(m_groups.begin(), m_groups.end(), group) != m_groups.end(); } // isInGroups - // ---------------------------------------------------------------------------- -/** Called the first time a kart accelerates after 'ready-set-go'. It searches - * through m_startup_times to find the appropriate slot, and returns the - * speed-boost from the corresponding entry in m_startup_boost. - * If the kart started too slow (i.e. slower than the longest time in - * m_startup_times, it returns 0. - */ -float KartProperties::getStartupBoost() const +float KartProperties::getAvgPower() const { - float t = World::getWorld()->getTime(); - for(unsigned int i=0; i gear_power_increase = m_combined_characteristic->getGearPowerIncrease(); + float power = m_combined_characteristic->getEnginePower(); + for (unsigned int i = 0; i < gear_power_increase.size(); ++i) + sum += gear_power_increase[i] * power; + return sum / gear_power_increase.size(); } // getAvgPower -/* EOF */ +// ---------------------------------------------------------------------------- +// Script-generated content generated by tools/create_kart_properties.py getter +// Please don't change the following tag. It will be automatically detected +// by the script and replace the contained content. +// To update the code, use tools/update_characteristics.py +/* */ +// ---------------------------------------------------------------------------- +float KartProperties::getSuspensionStiffness() const +{ + return m_cached_characteristic->getSuspensionStiffness(); +} // getSuspensionStiffness + +// ---------------------------------------------------------------------------- +float KartProperties::getSuspensionRest() const +{ + return m_cached_characteristic->getSuspensionRest(); +} // getSuspensionRest + +// ---------------------------------------------------------------------------- +float KartProperties::getSuspensionTravel() const +{ + return m_cached_characteristic->getSuspensionTravel(); +} // getSuspensionTravel + +// ---------------------------------------------------------------------------- +bool KartProperties::getSuspensionExpSpringResponse() const +{ + return m_cached_characteristic->getSuspensionExpSpringResponse(); +} // getSuspensionExpSpringResponse + +// ---------------------------------------------------------------------------- +float KartProperties::getSuspensionMaxForce() const +{ + return m_cached_characteristic->getSuspensionMaxForce(); +} // getSuspensionMaxForce + +// ---------------------------------------------------------------------------- +float KartProperties::getStabilityRollInfluence() const +{ + return m_cached_characteristic->getStabilityRollInfluence(); +} // getStabilityRollInfluence + +// ---------------------------------------------------------------------------- +float KartProperties::getStabilityChassisLinearDamping() const +{ + return m_cached_characteristic->getStabilityChassisLinearDamping(); +} // getStabilityChassisLinearDamping + +// ---------------------------------------------------------------------------- +float KartProperties::getStabilityChassisAngularDamping() const +{ + return m_cached_characteristic->getStabilityChassisAngularDamping(); +} // getStabilityChassisAngularDamping + +// ---------------------------------------------------------------------------- +float KartProperties::getStabilityDownwardImpulseFactor() const +{ + return m_cached_characteristic->getStabilityDownwardImpulseFactor(); +} // getStabilityDownwardImpulseFactor + +// ---------------------------------------------------------------------------- +float KartProperties::getStabilityTrackConnectionAccel() const +{ + return m_cached_characteristic->getStabilityTrackConnectionAccel(); +} // getStabilityTrackConnectionAccel + +// ---------------------------------------------------------------------------- +float KartProperties::getStabilitySmoothFlyingImpulse() const +{ + return m_cached_characteristic->getStabilitySmoothFlyingImpulse(); +} // getStabilitySmoothFlyingImpulse + +// ---------------------------------------------------------------------------- +InterpolationArray KartProperties::getTurnRadius() const +{ + return m_cached_characteristic->getTurnRadius(); +} // getTurnRadius + +// ---------------------------------------------------------------------------- +float KartProperties::getTurnTimeResetSteer() const +{ + return m_cached_characteristic->getTurnTimeResetSteer(); +} // getTurnTimeResetSteer + +// ---------------------------------------------------------------------------- +InterpolationArray KartProperties::getTurnTimeFullSteer() const +{ + return m_cached_characteristic->getTurnTimeFullSteer(); +} // getTurnTimeFullSteer + +// ---------------------------------------------------------------------------- +float KartProperties::getEnginePower() const +{ + return m_cached_characteristic->getEnginePower(); +} // getEnginePower + +// ---------------------------------------------------------------------------- +float KartProperties::getEngineMaxSpeed() const +{ + return m_cached_characteristic->getEngineMaxSpeed(); +} // getEngineMaxSpeed + +// ---------------------------------------------------------------------------- +float KartProperties::getEngineBrakeFactor() const +{ + return m_cached_characteristic->getEngineBrakeFactor(); +} // getEngineBrakeFactor + +// ---------------------------------------------------------------------------- +float KartProperties::getEngineBrakeTimeIncrease() const +{ + return m_cached_characteristic->getEngineBrakeTimeIncrease(); +} // getEngineBrakeTimeIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getEngineMaxSpeedReverseRatio() const +{ + return m_cached_characteristic->getEngineMaxSpeedReverseRatio(); +} // getEngineMaxSpeedReverseRatio + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getGearSwitchRatio() const +{ + return m_cached_characteristic->getGearSwitchRatio(); +} // getGearSwitchRatio + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getGearPowerIncrease() const +{ + return m_cached_characteristic->getGearPowerIncrease(); +} // getGearPowerIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getMass() const +{ + return m_cached_characteristic->getMass(); +} // getMass + +// ---------------------------------------------------------------------------- +float KartProperties::getWheelsDampingRelaxation() const +{ + return m_cached_characteristic->getWheelsDampingRelaxation(); +} // getWheelsDampingRelaxation + +// ---------------------------------------------------------------------------- +float KartProperties::getWheelsDampingCompression() const +{ + return m_cached_characteristic->getWheelsDampingCompression(); +} // getWheelsDampingCompression + +// ---------------------------------------------------------------------------- +float KartProperties::getCameraDistance() const +{ + return m_cached_characteristic->getCameraDistance(); +} // getCameraDistance + +// ---------------------------------------------------------------------------- +float KartProperties::getCameraForwardUpAngle() const +{ + return m_cached_characteristic->getCameraForwardUpAngle(); +} // getCameraForwardUpAngle + +// ---------------------------------------------------------------------------- +float KartProperties::getCameraBackwardUpAngle() const +{ + return m_cached_characteristic->getCameraBackwardUpAngle(); +} // getCameraBackwardUpAngle + +// ---------------------------------------------------------------------------- +float KartProperties::getJumpAnimationTime() const +{ + return m_cached_characteristic->getJumpAnimationTime(); +} // getJumpAnimationTime + +// ---------------------------------------------------------------------------- +float KartProperties::getLeanMax() const +{ + return m_cached_characteristic->getLeanMax(); +} // getLeanMax + +// ---------------------------------------------------------------------------- +float KartProperties::getLeanSpeed() const +{ + return m_cached_characteristic->getLeanSpeed(); +} // getLeanSpeed + +// ---------------------------------------------------------------------------- +float KartProperties::getAnvilDuration() const +{ + return m_cached_characteristic->getAnvilDuration(); +} // getAnvilDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getAnvilWeight() const +{ + return m_cached_characteristic->getAnvilWeight(); +} // getAnvilWeight + +// ---------------------------------------------------------------------------- +float KartProperties::getAnvilSpeedFactor() const +{ + return m_cached_characteristic->getAnvilSpeedFactor(); +} // getAnvilSpeedFactor + +// ---------------------------------------------------------------------------- +float KartProperties::getParachuteFriction() const +{ + return m_cached_characteristic->getParachuteFriction(); +} // getParachuteFriction + +// ---------------------------------------------------------------------------- +float KartProperties::getParachuteDuration() const +{ + return m_cached_characteristic->getParachuteDuration(); +} // getParachuteDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getParachuteDurationOther() const +{ + return m_cached_characteristic->getParachuteDurationOther(); +} // getParachuteDurationOther + +// ---------------------------------------------------------------------------- +float KartProperties::getParachuteLboundFraction() const +{ + return m_cached_characteristic->getParachuteLboundFraction(); +} // getParachuteLboundFraction + +// ---------------------------------------------------------------------------- +float KartProperties::getParachuteUboundFraction() const +{ + return m_cached_characteristic->getParachuteUboundFraction(); +} // getParachuteUboundFraction + +// ---------------------------------------------------------------------------- +float KartProperties::getParachuteMaxSpeed() const +{ + return m_cached_characteristic->getParachuteMaxSpeed(); +} // getParachuteMaxSpeed + +// ---------------------------------------------------------------------------- +float KartProperties::getBubblegumDuration() const +{ + return m_cached_characteristic->getBubblegumDuration(); +} // getBubblegumDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getBubblegumSpeedFraction() const +{ + return m_cached_characteristic->getBubblegumSpeedFraction(); +} // getBubblegumSpeedFraction + +// ---------------------------------------------------------------------------- +float KartProperties::getBubblegumTorque() const +{ + return m_cached_characteristic->getBubblegumTorque(); +} // getBubblegumTorque + +// ---------------------------------------------------------------------------- +float KartProperties::getBubblegumFadeInTime() const +{ + return m_cached_characteristic->getBubblegumFadeInTime(); +} // getBubblegumFadeInTime + +// ---------------------------------------------------------------------------- +float KartProperties::getBubblegumShieldDuration() const +{ + return m_cached_characteristic->getBubblegumShieldDuration(); +} // getBubblegumShieldDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getZipperDuration() const +{ + return m_cached_characteristic->getZipperDuration(); +} // getZipperDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getZipperForce() const +{ + return m_cached_characteristic->getZipperForce(); +} // getZipperForce + +// ---------------------------------------------------------------------------- +float KartProperties::getZipperSpeedGain() const +{ + return m_cached_characteristic->getZipperSpeedGain(); +} // getZipperSpeedGain + +// ---------------------------------------------------------------------------- +float KartProperties::getZipperMaxSpeedIncrease() const +{ + return m_cached_characteristic->getZipperMaxSpeedIncrease(); +} // getZipperMaxSpeedIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getZipperFadeOutTime() const +{ + return m_cached_characteristic->getZipperFadeOutTime(); +} // getZipperFadeOutTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSwatterDuration() const +{ + return m_cached_characteristic->getSwatterDuration(); +} // getSwatterDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getSwatterDistance() const +{ + return m_cached_characteristic->getSwatterDistance(); +} // getSwatterDistance + +// ---------------------------------------------------------------------------- +float KartProperties::getSwatterSquashDuration() const +{ + return m_cached_characteristic->getSwatterSquashDuration(); +} // getSwatterSquashDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getSwatterSquashSlowdown() const +{ + return m_cached_characteristic->getSwatterSquashSlowdown(); +} // getSwatterSquashSlowdown + +// ---------------------------------------------------------------------------- +float KartProperties::getPlungerBandMaxLength() const +{ + return m_cached_characteristic->getPlungerBandMaxLength(); +} // getPlungerBandMaxLength + +// ---------------------------------------------------------------------------- +float KartProperties::getPlungerBandForce() const +{ + return m_cached_characteristic->getPlungerBandForce(); +} // getPlungerBandForce + +// ---------------------------------------------------------------------------- +float KartProperties::getPlungerBandDuration() const +{ + return m_cached_characteristic->getPlungerBandDuration(); +} // getPlungerBandDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getPlungerBandSpeedIncrease() const +{ + return m_cached_characteristic->getPlungerBandSpeedIncrease(); +} // getPlungerBandSpeedIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getPlungerBandFadeOutTime() const +{ + return m_cached_characteristic->getPlungerBandFadeOutTime(); +} // getPlungerBandFadeOutTime + +// ---------------------------------------------------------------------------- +float KartProperties::getPlungerInFaceTime() const +{ + return m_cached_characteristic->getPlungerInFaceTime(); +} // getPlungerInFaceTime + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getStartupTime() const +{ + return m_cached_characteristic->getStartupTime(); +} // getStartupTime + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getStartupBoost() const +{ + return m_cached_characteristic->getStartupBoost(); +} // getStartupBoost + +// ---------------------------------------------------------------------------- +float KartProperties::getRescueDuration() const +{ + return m_cached_characteristic->getRescueDuration(); +} // getRescueDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getRescueVertOffset() const +{ + return m_cached_characteristic->getRescueVertOffset(); +} // getRescueVertOffset + +// ---------------------------------------------------------------------------- +float KartProperties::getRescueHeight() const +{ + return m_cached_characteristic->getRescueHeight(); +} // getRescueHeight + +// ---------------------------------------------------------------------------- +float KartProperties::getExplosionDuration() const +{ + return m_cached_characteristic->getExplosionDuration(); +} // getExplosionDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getExplosionRadius() const +{ + return m_cached_characteristic->getExplosionRadius(); +} // getExplosionRadius + +// ---------------------------------------------------------------------------- +float KartProperties::getExplosionInvulnerabilityTime() const +{ + return m_cached_characteristic->getExplosionInvulnerabilityTime(); +} // getExplosionInvulnerabilityTime + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroDuration() const +{ + return m_cached_characteristic->getNitroDuration(); +} // getNitroDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroEngineForce() const +{ + return m_cached_characteristic->getNitroEngineForce(); +} // getNitroEngineForce + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroConsumption() const +{ + return m_cached_characteristic->getNitroConsumption(); +} // getNitroConsumption + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroSmallContainer() const +{ + return m_cached_characteristic->getNitroSmallContainer(); +} // getNitroSmallContainer + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroBigContainer() const +{ + return m_cached_characteristic->getNitroBigContainer(); +} // getNitroBigContainer + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroMaxSpeedIncrease() const +{ + return m_cached_characteristic->getNitroMaxSpeedIncrease(); +} // getNitroMaxSpeedIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroFadeOutTime() const +{ + return m_cached_characteristic->getNitroFadeOutTime(); +} // getNitroFadeOutTime + +// ---------------------------------------------------------------------------- +float KartProperties::getNitroMax() const +{ + return m_cached_characteristic->getNitroMax(); +} // getNitroMax + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamDuration() const +{ + return m_cached_characteristic->getSlipstreamDuration(); +} // getSlipstreamDuration + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamLength() const +{ + return m_cached_characteristic->getSlipstreamLength(); +} // getSlipstreamLength + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamWidth() const +{ + return m_cached_characteristic->getSlipstreamWidth(); +} // getSlipstreamWidth + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamCollectTime() const +{ + return m_cached_characteristic->getSlipstreamCollectTime(); +} // getSlipstreamCollectTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamUseTime() const +{ + return m_cached_characteristic->getSlipstreamUseTime(); +} // getSlipstreamUseTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamAddPower() const +{ + return m_cached_characteristic->getSlipstreamAddPower(); +} // getSlipstreamAddPower + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamMinSpeed() const +{ + return m_cached_characteristic->getSlipstreamMinSpeed(); +} // getSlipstreamMinSpeed + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamMaxSpeedIncrease() const +{ + return m_cached_characteristic->getSlipstreamMaxSpeedIncrease(); +} // getSlipstreamMaxSpeedIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getSlipstreamFadeOutTime() const +{ + return m_cached_characteristic->getSlipstreamFadeOutTime(); +} // getSlipstreamFadeOutTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidIncrease() const +{ + return m_cached_characteristic->getSkidIncrease(); +} // getSkidIncrease + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidDecrease() const +{ + return m_cached_characteristic->getSkidDecrease(); +} // getSkidDecrease + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidMax() const +{ + return m_cached_characteristic->getSkidMax(); +} // getSkidMax + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidTimeTillMax() const +{ + return m_cached_characteristic->getSkidTimeTillMax(); +} // getSkidTimeTillMax + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidVisual() const +{ + return m_cached_characteristic->getSkidVisual(); +} // getSkidVisual + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidVisualTime() const +{ + return m_cached_characteristic->getSkidVisualTime(); +} // getSkidVisualTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidRevertVisualTime() const +{ + return m_cached_characteristic->getSkidRevertVisualTime(); +} // getSkidRevertVisualTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidMinSpeed() const +{ + return m_cached_characteristic->getSkidMinSpeed(); +} // getSkidMinSpeed + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getSkidTimeTillBonus() const +{ + return m_cached_characteristic->getSkidTimeTillBonus(); +} // getSkidTimeTillBonus + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getSkidBonusSpeed() const +{ + return m_cached_characteristic->getSkidBonusSpeed(); +} // getSkidBonusSpeed + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getSkidBonusTime() const +{ + return m_cached_characteristic->getSkidBonusTime(); +} // getSkidBonusTime + +// ---------------------------------------------------------------------------- +std::vector KartProperties::getSkidBonusForce() const +{ + return m_cached_characteristic->getSkidBonusForce(); +} // getSkidBonusForce + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidPhysicalJumpTime() const +{ + return m_cached_characteristic->getSkidPhysicalJumpTime(); +} // getSkidPhysicalJumpTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidGraphicalJumpTime() const +{ + return m_cached_characteristic->getSkidGraphicalJumpTime(); +} // getSkidGraphicalJumpTime + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidPostSkidRotateFactor() const +{ + return m_cached_characteristic->getSkidPostSkidRotateFactor(); +} // getSkidPostSkidRotateFactor + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidReduceTurnMin() const +{ + return m_cached_characteristic->getSkidReduceTurnMin(); +} // getSkidReduceTurnMin + +// ---------------------------------------------------------------------------- +float KartProperties::getSkidReduceTurnMax() const +{ + return m_cached_characteristic->getSkidReduceTurnMax(); +} // getSkidReduceTurnMax + +// ---------------------------------------------------------------------------- +bool KartProperties::getSkidEnabled() const +{ + return m_cached_characteristic->getSkidEnabled(); +} // getSkidEnabled + + +/* */ + diff --git a/src/karts/kart_properties.hpp b/src/karts/kart_properties.hpp index aa8eac802..b8f81438a 100644 --- a/src/karts/kart_properties.hpp +++ b/src/karts/kart_properties.hpp @@ -19,6 +19,7 @@ #ifndef HEADER_KART_PROPERTIES_HPP #define HEADER_KART_PROPERTIES_HPP +#include #include #include @@ -37,9 +38,11 @@ using namespace irr; #include "utils/interpolation_array.hpp" #include "utils/vec3.hpp" +class AbstractCharacteristic; class AIProperties; +class CachedCharacteristic; +class CombinedCharacteristic; class Material; -class SkiddingProperties; class XMLNode; /** @@ -47,7 +50,7 @@ class XMLNode; * This includes size, name, identifier, physical properties etc. * It is atm also the base class for STKConfig, which stores the default values * for all physics constants. - * Note that KartProperies is copied (when setting the default values from + * Note that KartProperties is copied (when setting the default values from * stk_config. * * \ingroup karts @@ -58,16 +61,11 @@ private: /** Base directory for this kart. */ std::string m_root; - /** The skididing properties for this kart, as a separate object in order - * to reduce dependencies (and therefore compile time) when changing - * any skidding property. */ - SkiddingProperties *m_skidding_properties; - /** AI Properties for this kart, as a separate object in order to * reduce dependencies (and therefore compile time) when changing * any AI property. There is one separate object for each * difficulty. */ - AIProperties *m_ai_properties[RaceManager::DIFFICULTY_COUNT]; + std::shared_ptr m_ai_properties[RaceManager::DIFFICULTY_COUNT]; /** The absolute path of the icon texture to use. */ Material *m_icon_material; @@ -82,7 +80,7 @@ private: /** The kart model and wheels. It is mutable since the wheels of the * KartModel can rotate and turn, and animations are played, but otherwise * the kart_properties object is const. */ - mutable KartModel *m_kart_model; + mutable std::shared_ptr m_kart_model; /** List of all groups the kart belongs to. */ std::vector m_groups; @@ -119,33 +117,18 @@ private: * status bar and on the track-view. */ int m_shape; /**< Number of vertices in polygon when * drawing the dot on the mini map. */ + + /** The physical, item, etc. characteristics of this kart that are loaded + * from the xml file. + */ + std::shared_ptr m_characteristic; + /** The base characteristics combined with the characteristics of this kart. */ + std::shared_ptr m_combined_characteristic; + /** The cached combined characteristics. */ + std::shared_ptr m_cached_characteristic; + // Physic properties // ----------------- - /** Weight of kart. */ - float m_mass; - - /** Maximum force from engine for each difficulty. */ - std::vector m_engine_power; - - /** Braking factor * engine_power braking force. */ - float m_brake_factor; - - /** Brake_time * m_brake_time_increase will increase the break time - * over time. */ - float m_brake_time_increase; - - /** Time for player karts to reach full steer angle. */ - InterpolationArray m_time_full_steer; - - /** Time for steering to go back to zero from full steer. */ - float m_time_reset_steer; - - /** A torque impulse applied to keep the kart parallel to the ground. */ - float m_smooth_flying_impulse;; - - /** The turn angle depending on speed. */ - InterpolationArray m_turn_angle_at_speed; - /** If != 0 a bevelled box shape is used by using a point cloud as a * collision shape. */ Vec3 m_bevel_factor; @@ -159,39 +142,6 @@ private: */ float m_physical_wheel_position; - /** Time a kart is moved upwards after when it is rescued. */ - float m_rescue_time; - - /** Distance the kart is raised before dropped. */ - float m_rescue_height; - - /** Time an animated explosion is shown. Longer = more delay for kart. */ - float m_explosion_time; - - /** How far away from an explosion karts will still be affected. */ - float m_explosion_radius; - - /** How long a kart is invulnerable after it is hit by an explosion. */ - float m_explosion_invulnerability_time; - - /** Duration a zipper is active. */ - float m_zipper_time; - - /** Fade out time for a zipper. */ - float m_zipper_fade_out_time; - - /** Additional force added to the acceleration. */ - float m_zipper_force; - - /** Initial one time speed gain. */ - float m_zipper_speed_gain; - - /** Absolute increase of the kart's maximum speed (in m/s). */ - float m_zipper_max_speed_increase; - - /** Vertical offset after rescue. */ - float m_rescue_vert_offset; - /** Minimum time during which nitro is consumed when pressing * the nitro key (to prevent using in very small bursts) */ @@ -202,64 +152,12 @@ private: /** Filename of the wheel models. */ std::string m_wheel_filename[4]; - /** Radius of the graphical wheels. */ - float m_wheel_graphics_radius[4]; /** An additional Y offset added to the y position of the graphical * chassis. Useful for karts that don't have enough space for suspension * compression. */ float m_graphical_y_offset; - /** Max. length of plunger rubber band. */ - float m_rubber_band_max_length; - /** Force of an attached rubber band. */ - /** Duration a rubber band works. */ - float m_rubber_band_force; - /** How long the rubber band will fly. */ - float m_rubber_band_duration; - /** Increase of maximum speed of the kart when the rubber band pulls. */ - float m_rubber_band_speed_increase; - /** Fade out time when the rubber band is removed. */ - float m_rubber_band_fade_out_time; - /**Duration of plunger in face depending on difficulty. */ - std::vector m_plunger_in_face_duration; /** Wheel base of the kart. */ float m_wheel_base; - /** Nitro consumption. */ - float m_nitro_consumption; - /** Nitro amount for small bottle. */ - float m_nitro_small_container; - /** Nitro amount for big bittle. */ - float m_nitro_big_container; - /** How much the speed of a kart might exceed its maximum speed (in m/s). */ - float m_nitro_max_speed_increase; - /** Additional engine force to affect the kart. */ - float m_nitro_engine_force; - /** How long the increased nitro max speed will be valid after - * the kart stops using nitro (and the fade-out-time starts). */ - float m_nitro_duration; - /** Duration during which the increased maximum speed - * due to nitro fades out. */ - float m_nitro_fade_out_time; - /** Maximum nitro a kart can collect. */ - float m_nitro_max; - /** Bubble gum diration. */ - float m_bubblegum_time; - /** Torque to add when a bubble gum was hit in order to make the kart go - * sideways a bit. */ - float m_bubblegum_torque; - /** Fraction of top speed that can be reached maximum after hitting a - * bubble gum. */ - float m_bubblegum_speed_fraction; - /** How long to fade in the slowdown for a bubble gum. */ - float m_bubblegum_fade_in_time; - /** Square of the maximum distance a swatter can operate. */ - float m_swatter_distance2; - /** How long the swatter lasts. */ - float m_swatter_duration; - /** How long a kart will remain squashed. */ - float m_squash_duration; - /** The slowdown to apply while a kart is squashed. The new maxspeed - * is max_speed*m_squash_slowdown. */ - float m_squash_slowdown; /** The maximum roll a kart graphics should show when driving in a fast * curve. This is read in as degrees, but stored in radians. */ @@ -269,57 +167,19 @@ private: * (in radians/second). */ float m_lean_speed; - /** How long a jump must be in order to trigger the jump animation. */ - float m_jump_animation_time; - /** Engine sound effect. */ std::string m_engine_sfx_type; // bullet physics data // ------------------- - float m_suspension_stiffness; - float m_wheel_damping_relaxation; - float m_wheel_damping_compression; - float m_max_suspension_force; float m_friction_slip; - float m_roll_influence; /** Parameters for the speed-weighted objects */ SpeedWeightedObject::Properties m_speed_weighted_object_properties; - /** An impulse pushing the kart down which is proportional to speed. So - * the actual impulse is speed * m_downward_impulse_factor. Set it to - * 0 to disable completely. Based on - * http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=6059\ - * &p=21240&hilit=vehicle#p21240 */ - float m_downward_impulse_factor; - - /** Artifical acceleration that pulls a kart down onto the track if one - * axis loses contact with the track. */ - float m_track_connection_accel; - - /** Linear damping of the chassis to prevent it from toppling over. */ - float m_chassis_linear_damping; - - /** Angular damping to prevent it from turning too easily. */ - float m_chassis_angular_damping; - - /** The maximum speed at each difficulty. */ - std::vector m_max_speed; - - float m_max_speed_reverse_ratio; - /** Shift of center of gravity. */ Vec3 m_gravity_center_shift; - /** The suspension reaction is dampened to reach an exponential behaviour. - * See http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=7369\ - * &p=25236&hilit=vehicle#p25236 for details. */ - bool m_exp_spring_response; - - float m_suspension_rest; - float m_suspension_travel; - public: /** STK can add an impulse to push karts away from the track in case * of a kart-track collision. This can be done in two ways: either @@ -345,80 +205,33 @@ private: /** The restitution factor to be used in collsions for this kart. */ float m_restitution; - /** How far behind a kart slipstreaming is effective. */ - float m_slipstream_length; - /** How wide the slipstream area is at the end. */ - float m_slipstream_width; - /** Time after which sstream gives a bonus. */ - float m_slipstream_collect_time; - /** Time slip-stream bonus is effective. */ - float m_slipstream_use_time; - /** Additional power due to sstreaming. */ - float m_slipstream_add_power; - /** Minimum speed for slipstream to take effect. */ - float m_slipstream_min_speed; - /** How much the speed of the kart might exceed its - * normal maximum speed. */ - float m_slipstream_max_speed_increase; - /** How long the higher speed lasts after slipstream stopped working. */ - float m_slipstream_duration; - /** How long the slip stream speed increase will gradually be reduced. */ - float m_slipstream_fade_out_time; - - /** Distance of normal camera from kart. */ - float m_camera_distance; - - /** Up angle of the camera in relation to the pitch of the kart when - * driving forwards. */ - float m_camera_forward_up_angle; - - /** Up angle of the camera in relation to the pitch of the kart when - * driving backwards. */ - float m_camera_backward_up_angle; - - /** The following two vectors define at what ratio of the maximum speed what - * gear is selected. E.g. 0.25 means: if speed <=0.25*maxSpeed --> gear 1, - * 0.5 means: if speed <=0.5 *maxSpeed --> gear 2 */ - std::vector m_gear_switch_ratio; - /** This vector contains the increase in max power (to simulate different - * gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1. See - m_gear_switch_ratio). */ - std::vector m_gear_power_increase; - - /** If the kart starts within the specified time at index I after 'go', - * it receives the speed boost from m_startup_boost[I]. */ - std::vector m_startup_times; - - /** The startup boost is the kart starts fast enough. */ - std::vector m_startup_boost; - void load (const std::string &filename, const std::string &node); - + void combineCharacteristics(); public: + /** Returns the string representation of a per-player difficulty. */ + static std::string getPerPlayerDifficultyAsString(PerPlayerDifficulty d); + KartProperties (const std::string &filename=""); ~KartProperties (); + void copyForPlayer (const KartProperties *source); void copyFrom (const KartProperties *source); void getAllData (const XMLNode * root); void checkAllSet (const std::string &filename); - float getStartupBoost () const; bool isInGroup (const std::string &group) const; bool operator<(const KartProperties &other) const; // ------------------------------------------------------------------------ - /** Returns the (maximum) speed for a given turn radius. - * \param radius The radius for which the speed needs to be computed. */ - float getSpeedForTurnRadius(float radius) const { - float angle = sin(m_wheel_base / radius); - return m_turn_angle_at_speed.getReverse(angle); - } // getSpeedForTurnRadius + /** Returns the characteristics for this kart. */ + const AbstractCharacteristic* getCharacteristic() const; // ------------------------------------------------------------------------ - /** Returns the maximum steering angle (depending on speed). */ - float getMaxSteerAngle(float speed) const { - return m_turn_angle_at_speed.get(speed); - } // getMaxSteerAngle + /** Returns the characteristics for this kart combined with the base + * characteristic. This value isn't used for the race, because the + * difficulty is missing, but it can be used e.g. for the kart stats widget. + */ + const AbstractCharacteristic* getCombinedCharacteristic() const; // ------------------------------------------------------------------------ /** Returns the material for the kart icons. */ @@ -462,6 +275,10 @@ public: /** Returns the internal identifier of this kart. */ const std::string& getIdent () const {return m_ident; } + // ------------------------------------------------------------------------ + /** Returns the type of this kart. */ + const std::string& getKartType () const { return m_kart_type; } + // ------------------------------------------------------------------------ /** Returns the shadow texture to use. */ video::ITexture *getShadowTexture() const {return m_shadow_texture; } @@ -492,47 +309,6 @@ public: /** Returns the list of groups this kart belongs to. */ const std::vector& getGroups () const {return m_groups; } - // ------------------------------------------------------------------------ - /** Returns the mass of this kart. */ - float getMass () const {return m_mass; } - // ------------------------------------------------------------------------ - /** Returns the maximum engine power depending on difficulty. */ - float getMaxPower () const - {return m_engine_power[race_manager->getDifficulty()];} - - // ------------------------------------------------------------------------ - /** Returns the time the kart needs to fully steer in one direction from - * steering straight depending on the current steering value. - * \param steer Current steering value, must be >=0. */ - float getTimeFullSteer(float steer) const - { - assert(steer>=0); - return m_time_full_steer.get(steer); - } // getTimeFullSteer - - // ------------------------------------------------------------------------ - /** Returns the time the kart needs to go back to steering straight from - * full steer. */ - float getTimeResetSteer () const { return m_time_reset_steer; } - // ------------------------------------------------------------------------ - /** Get braking information. */ - float getBrakeFactor () const {return m_brake_factor; } - - // ------------------------------------------------------------------------ - /** Returns the additional brake factor which depends on time. */ - float getBrakeTimeIncrease() const { return m_brake_time_increase; } - - // ------------------------------------------------------------------------ - /** Returns the torque scaling factor used to keep the karts parallel to - * the ground when flying. */ - float getSmoothFlyingImpulse() const - { - return m_smooth_flying_impulse; - } // getSmoothFlyingImpulse - - // ------------------------------------------------------------------------ - /** Get maximum reverse speed ratio. */ - float getMaxSpeedReverseRatio() const {return m_max_speed_reverse_ratio; } // ------------------------------------------------------------------------ /** Returns the engine type (used to change sfx depending on kart size). */ @@ -540,31 +316,9 @@ public: // Bullet physics get functions //----------------------------- - /** Returns the suspension stiffness. */ - float getSuspensionStiffness () const {return m_suspension_stiffness; } - - // ------------------------------------------------------------------------ - /** Returns damping relaxation. */ - float getWheelDampingRelaxation () const - {return m_wheel_damping_relaxation; } - - // ------------------------------------------------------------------------ - /** Returns the wheel damping compression. */ - float getWheelDampingCompression() const - {return m_wheel_damping_compression;} - - // ------------------------------------------------------------------------ - /** Returns maximum suspension force. */ - float getMaxSuspensionForce() const {return m_max_suspension_force; } - - // ------------------------------------------------------------------------ /** Returns friction slip. */ float getFrictionSlip () const {return m_friction_slip; } - // ------------------------------------------------------------------------ - /** Returns roll influence. */ - float getRollInfluence () const {return m_roll_influence; } - // ------------------------------------------------------------------------ /** Returns parameters for the speed-weighted objects */ const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const @@ -576,99 +330,11 @@ public: /** Returns the wheel base (distance front to rear axis). */ float getWheelBase () const {return m_wheel_base; } - // ------------------------------------------------------------------------ - /** Returns linear damping of chassis. */ - float getChassisLinearDamping () const {return m_chassis_linear_damping;} - - // ------------------------------------------------------------------------ - /** Returns angular damping of chassis. */ - float getChassisAngularDamping () const - {return m_chassis_angular_damping; } - - // ------------------------------------------------------------------------ - /** Artifical downward impulse every frame. */ - float getDownwardImpulseFactor() const { return m_downward_impulse_factor;} - - // ------------------------------------------------------------------------ - /** Returns artificial acceleration to keep wheels on track. */ - float getTrackConnectionAccel () const {return m_track_connection_accel;} - - // ------------------------------------------------------------------------ - /** Returns the maximum speed dependent on the difficult level. */ - float getMaxSpeed () const - { - return m_max_speed[race_manager->getDifficulty()]; - } - - // ------------------------------------------------------------------------ - /** Return the absolute maximum speed, independent on the difficulty. */ - float getAbsMaxSpeed () const - { - return m_max_speed[m_max_speed.size()-1]; - } - - // ------------------------------------------------------------------------ - /** Returns the nitro consumption. */ - float getNitroConsumption () const {return m_nitro_consumption; } - - // ------------------------------------------------------------------------ - /** Returns the amount of nitro for a small container. */ - float getNitroSmallContainer () const {return m_nitro_small_container; } - - // ------------------------------------------------------------------------ - /** Returns the amount of nitro for a big container. */ - float getNitroBigContainer () const {return m_nitro_big_container; } - - // ------------------------------------------------------------------------ - /** Returns the increase of maximum speed due to nitro. */ - float getNitroMaxSpeedIncrease () const - {return m_nitro_max_speed_increase; } - - // ------------------------------------------------------------------------ - float getNitroEngineForce () const {return m_nitro_engine_force; } - // ------------------------------------------------------------------------ - /** Returns how long the increased nitro max speed will be valid after - * the kart stops using nitro (and the fade-out-time starts). */ - float getNitroDuration () const {return m_nitro_duration; } - - // ------------------------------------------------------------------------ - /** Returns the duration during which the increased maximum speed - * due to nitro fades out. */ - float getNitroFadeOutTime () const {return m_nitro_fade_out_time; } - - // ------------------------------------------------------------------------ - /** Returns the maximum amount of nitro a kart can store. */ - float getNitroMax () const {return m_nitro_max; } - // ------------------------------------------------------------------------ - /** Returns how long a bubble gum is active. */ - float getBubblegumTime() const { return m_bubblegum_time; } - // ------------------------------------------------------------------------ - /** Returns the torque to add when a bubble gum was hit . */ - float getBubblegumTorque() const { return m_bubblegum_torque; } - // ------------------------------------------------------------------------ - /** Returns the fraction of top speed that can be reached maximum after - * hitting a bubble gum. */ - float getBubblegumSpeedFraction() const {return m_bubblegum_speed_fraction;} - // ------------------------------------------------------------------------ - /** Returns how long to fade in the slowdown for a bubble gum. */ - float getBubblegumFadeInTime() const { return m_bubblegum_fade_in_time; } // ------------------------------------------------------------------------ /** Returns a shift of the center of mass (lowering the center of mass * makes the karts more stable. */ const Vec3&getGravityCenterShift() const {return m_gravity_center_shift; } - // ------------------------------------------------------------------------ - /** Retusn suspension rest length. */ - float getSuspensionRest () const {return m_suspension_rest; } - - // ------------------------------------------------------------------------ - /** Returns the amount the suspension can extend. */ - float getSuspensionTravel () const {return m_suspension_travel; } - - // ------------------------------------------------------------------------ - /** Returns if the spring should be exponentially dampened. */ - bool getExpSpringResponse() const {return m_exp_spring_response; } - // ------------------------------------------------------------------------ /** Returns an artificial impulse to push karts away from the terrain * it hits. */ @@ -693,128 +359,6 @@ public: /** Returns the restitution factor for this kart. */ float getRestitution () const { return m_restitution; } - // ------------------------------------------------------------------------ - /** Returns the vertical offset when rescuing karts to avoid karts being - * rescued in (or under) the track. */ - float getVertRescueOffset () const {return m_rescue_vert_offset; } - - // ------------------------------------------------------------------------ - /** Returns the time a kart is rised during a rescue. */ - float getRescueTime () const {return m_rescue_time; } - - // ------------------------------------------------------------------------ - /** Returns the height a kart is moved to during a rescue. */ - float getRescueHeight () const {return m_rescue_height; } - - // ------------------------------------------------------------------------ - /** Returns the time an explosion animation is shown. */ - float getExplosionTime () const {return m_explosion_time; } - - // ------------------------------------------------------------------------ - /** Returns the height of the explosion animation. */ - float getExplosionRadius () const {return m_explosion_radius; } - - // ------------------------------------------------------------------------ - /** Returns how long a kart is invulnerable after being hit by an - explosion. */ - float getExplosionInvulnerabilityTime() const - { return m_explosion_invulnerability_time; } - - // ------------------------------------------------------------------------ - /** Returns the maximum length of a rubber band before it breaks. */ - float getRubberBandMaxLength () const {return m_rubber_band_max_length;} - - // ------------------------------------------------------------------------ - /** Returns force a rubber band has when attached to a kart. */ - float getRubberBandForce () const {return m_rubber_band_force; } - - // ------------------------------------------------------------------------ - /** Returns the duration a rubber band is active for. */ - float getRubberBandDuration () const {return m_rubber_band_duration; } - - // ------------------------------------------------------------------------ - /** Returns the increase of maximum speed while a rubber band is - * pulling. */ - float getRubberBandSpeedIncrease() const - { - return m_rubber_band_speed_increase; - } - - // ------------------------------------------------------------------------ - /** Return the fade out time once a rubber band is removed. */ - float getRubberBandFadeOutTime() const - { - return m_rubber_band_fade_out_time; - } - - // ------------------------------------------------------------------------ - /** Returns duration of a plunger in your face. */ - float getPlungerInFaceTime () const - {return m_plunger_in_face_duration[race_manager->getDifficulty()];} - - // ------------------------------------------------------------------------ - /** Returns the time a zipper is active. */ - float getZipperTime () const {return m_zipper_time; } - - // ------------------------------------------------------------------------ - /** Returns the time a zipper is active. */ - float getZipperFadeOutTime () const {return m_zipper_fade_out_time; } - - // ------------------------------------------------------------------------ - /** Returns the additional force added applied to the kart. */ - float getZipperForce () const { return m_zipper_force; } - - // ------------------------------------------------------------------------ - /** Returns the initial zipper speed gain. */ - float getZipperSpeedGain () const { return m_zipper_speed_gain; } - - // ------------------------------------------------------------------------ - /** Returns the increase of the maximum speed of the kart - * if a zipper is active. */ - float getZipperMaxSpeedIncrease () const - { return m_zipper_max_speed_increase;} - - // ------------------------------------------------------------------------ - /** Returns how far behind a kart slipstreaming works. */ - float getSlipstreamLength () const {return m_slipstream_length; } - - // ------------------------------------------------------------------------ - /** Returns how wide the slipstream area is at the end. */ - float getSlipstreamWidth () const {return m_slipstream_width; } - - // ------------------------------------------------------------------------ - /** Returns time after which slipstream has maximum effect. */ - float getSlipstreamCollectTime () const - {return m_slipstream_collect_time; } - - // ------------------------------------------------------------------------ - /** Returns time after which slipstream has maximum effect. */ - float getSlipstreamUseTime () const {return m_slipstream_use_time; } - - // ------------------------------------------------------------------------ - /** Returns additional power due to slipstreaming. */ - float getSlipstreamAddPower () const {return m_slipstream_add_power; } - - // ------------------------------------------------------------------------ - /** Returns the minimum slipstream speed. */ - float getSlipstreamMinSpeed () const {return m_slipstream_min_speed; } - - // ------------------------------------------------------------------------ - /** Returns the increase of the maximum speed of a kart - * due to slipstream. */ - float getSlipstreamMaxSpeedIncrease() const - { return m_slipstream_max_speed_increase; } - // ------------------------------------------------------------------------ - /** Returns how long the higher speed lasts after slipstream - * stopped working. */ - float getSlipstreamDuration () const { return m_slipstream_duration; } - - // ------------------------------------------------------------------------ - /** Returns how long the slip stream speed increase will gradually - * be reduced. */ - float getSlipstreamFadeOutTime () const - { return m_slipstream_fade_out_time; } - // ------------------------------------------------------------------------ /** Returns the scale factor by which the shadow plane * had to be set. */ @@ -830,79 +374,18 @@ public: * had to be set. */ float getShadowZOffset () const {return m_shadow_z_offset; } - // ------------------------------------------------------------------------ - /** Returns a pointer to the skidding properties. */ - const SkiddingProperties *getSkiddingProperties() const - { return m_skidding_properties; } - // ------------------------------------------------------------------------ /** Returns a pointer to the AI properties. */ const AIProperties *getAIPropertiesForDifficulty() const { - return m_ai_properties[race_manager->getDifficulty()]; + return m_ai_properties[race_manager->getDifficulty()].get(); } // getAIProperties - // ------------------------------------------------------------------------ - /** Returns ratio of current speed to max speed at which the gear will - * change (for our simualated gears = simple change of engine power). */ - const std::vector& - getGearSwitchRatio () const {return m_gear_switch_ratio; } - - // ------------------------------------------------------------------------ - /** Returns the power increase depending on gear. */ - const std::vector& - getGearPowerIncrease () const {return m_gear_power_increase; } - - // ------------------------------------------------------------------------ - /** Returns the average power of the kart (in all gears). */ - const float getAvgPower () const; - - // ------------------------------------------------------------------------ - /** Returns distance between kart and camera. */ - float getCameraDistance () const {return m_camera_distance; } - - // ------------------------------------------------------------------------ - /** Returns the angle the camera has relative to the pitch of the kart. */ - float getCameraForwardUpAngle () const - {return m_camera_forward_up_angle; } - - // ------------------------------------------------------------------------ - /** Returns the angle the camera has relative to the pitch of the kart. */ - float getCameraBackwardUpAngle () const - {return m_camera_backward_up_angle; } - // ------------------------------------------------------------------------ /** Returns the full path where the files for this kart are stored. */ const std::string& getKartDir () const {return m_root; } // ------------------------------------------------------------------------ - /** Returns the square of the maximum distance at which a swatter - * can hit karts. */ - float getSwatterDistance2() const { return m_swatter_distance2; } - - // ------------------------------------------------------------------------ - /** Returns how long a swatter will stay attached/ready to be used. */ - float getSwatterDuration() const { return m_swatter_duration; } - - // ------------------------------------------------------------------------ - /** Returns how long a kart remains squashed. */ - float getSquashDuration() const {return m_squash_duration; } - - // ------------------------------------------------------------------------ - /** Returns the slowdown of a kart that is squashed. */ - float getSquashSlowdown() const {return m_squash_slowdown; } - - // ------------------------------------------------------------------------ - /** The maximum leaning a kart should show (In radians). */ - float getMaxLean() const { return m_max_lean; } - - // ------------------------------------------------------------------------ - /** The speed with which a kart should lean (in radians/s). */ - float getLeanSpeed() const { return m_lean_speed; } - // ------------------------------------------------------------------------ - /** Return show long a jump must last in order to play the jump - * animation. */ - float getJumpAnimationTime() const { return m_jump_animation_time; } // ------------------------------------------------------------------------ /** Returns minimum time during which nitro is consumed when pressing nitro * key, to prevent using nitro in very short bursts @@ -921,8 +404,142 @@ public: { return m_physical_wheel_position; } // getPhysicalWheelPosition + + // ------------------------------------------------------------------------ + float getAvgPower() const; + + + // Script-generated content generated by tools/create_kart_properties.py defs + // Please don't change the following tag. It will be automatically detected + // by the script and replace the contained content. + // To update the code, use tools/update_characteristics.py + /* */ + + float getSuspensionStiffness() const; + float getSuspensionRest() const; + float getSuspensionTravel() const; + bool getSuspensionExpSpringResponse() const; + float getSuspensionMaxForce() const; + + float getStabilityRollInfluence() const; + float getStabilityChassisLinearDamping() const; + float getStabilityChassisAngularDamping() const; + float getStabilityDownwardImpulseFactor() const; + float getStabilityTrackConnectionAccel() const; + float getStabilitySmoothFlyingImpulse() const; + + InterpolationArray getTurnRadius() const; + float getTurnTimeResetSteer() const; + InterpolationArray getTurnTimeFullSteer() const; + + float getEnginePower() const; + float getEngineMaxSpeed() const; + float getEngineBrakeFactor() const; + float getEngineBrakeTimeIncrease() const; + float getEngineMaxSpeedReverseRatio() const; + + std::vector getGearSwitchRatio() const; + std::vector getGearPowerIncrease() const; + + float getMass() const; + + float getWheelsDampingRelaxation() const; + float getWheelsDampingCompression() const; + + float getCameraDistance() const; + float getCameraForwardUpAngle() const; + float getCameraBackwardUpAngle() const; + + float getJumpAnimationTime() const; + + float getLeanMax() const; + float getLeanSpeed() const; + + float getAnvilDuration() const; + float getAnvilWeight() const; + float getAnvilSpeedFactor() const; + + float getParachuteFriction() const; + float getParachuteDuration() const; + float getParachuteDurationOther() const; + float getParachuteLboundFraction() const; + float getParachuteUboundFraction() const; + float getParachuteMaxSpeed() const; + + float getBubblegumDuration() const; + float getBubblegumSpeedFraction() const; + float getBubblegumTorque() const; + float getBubblegumFadeInTime() const; + float getBubblegumShieldDuration() const; + + float getZipperDuration() const; + float getZipperForce() const; + float getZipperSpeedGain() const; + float getZipperMaxSpeedIncrease() const; + float getZipperFadeOutTime() const; + + float getSwatterDuration() const; + float getSwatterDistance() const; + float getSwatterSquashDuration() const; + float getSwatterSquashSlowdown() const; + + float getPlungerBandMaxLength() const; + float getPlungerBandForce() const; + float getPlungerBandDuration() const; + float getPlungerBandSpeedIncrease() const; + float getPlungerBandFadeOutTime() const; + float getPlungerInFaceTime() const; + + std::vector getStartupTime() const; + std::vector getStartupBoost() const; + + float getRescueDuration() const; + float getRescueVertOffset() const; + float getRescueHeight() const; + + float getExplosionDuration() const; + float getExplosionRadius() const; + float getExplosionInvulnerabilityTime() const; + + float getNitroDuration() const; + float getNitroEngineForce() const; + float getNitroConsumption() const; + float getNitroSmallContainer() const; + float getNitroBigContainer() const; + float getNitroMaxSpeedIncrease() const; + float getNitroFadeOutTime() const; + float getNitroMax() const; + + float getSlipstreamDuration() const; + float getSlipstreamLength() const; + float getSlipstreamWidth() const; + float getSlipstreamCollectTime() const; + float getSlipstreamUseTime() const; + float getSlipstreamAddPower() const; + float getSlipstreamMinSpeed() const; + float getSlipstreamMaxSpeedIncrease() const; + float getSlipstreamFadeOutTime() const; + + float getSkidIncrease() const; + float getSkidDecrease() const; + float getSkidMax() const; + float getSkidTimeTillMax() const; + float getSkidVisual() const; + float getSkidVisualTime() const; + float getSkidRevertVisualTime() const; + float getSkidMinSpeed() const; + std::vector getSkidTimeTillBonus() const; + std::vector getSkidBonusSpeed() const; + std::vector getSkidBonusTime() const; + std::vector getSkidBonusForce() const; + float getSkidPhysicalJumpTime() const; + float getSkidGraphicalJumpTime() const; + float getSkidPostSkidRotateFactor() const; + float getSkidReduceTurnMin() const; + float getSkidReduceTurnMax() const; + bool getSkidEnabled() const; + + /* */ }; // KartProperties #endif - -/* EOF */ diff --git a/src/karts/kart_properties_manager.cpp b/src/karts/kart_properties_manager.cpp index f8d2554d7..a9f58429c 100644 --- a/src/karts/kart_properties_manager.cpp +++ b/src/karts/kart_properties_manager.cpp @@ -28,6 +28,7 @@ #include "guiengine/engine.hpp" #include "io/file_manager.hpp" #include "karts/kart_properties.hpp" +#include "karts/xml_characteristic.hpp" #include "utils/log.hpp" #include "utils/string_utils.hpp" @@ -175,12 +176,68 @@ void KartPropertiesManager::loadAllKarts(bool loading_icon) } // loadAllKarts //----------------------------------------------------------------------------- -/** Loads a single kart and (if not disabled) the oorresponding 3d model. +/** Loads the characteristics from the characteristics config file. + * \param root The xml node where the characteristics are stored. + */ +void KartPropertiesManager::loadCharacteristics(const XMLNode *root) +{ + // Load base characteristics + std::vector nodes; + root->getNodes("characteristic", nodes); + bool found = false; + std::string name; + for (const XMLNode *baseNode : nodes) + { + baseNode->get("name", &name); + if (name == "base") + { + found = true; + m_base_characteristic.reset(new XmlCharacteristic(baseNode)); + break; + } + } + if (!found) + Log::fatal("KartPropertiesManager", "Base characteristics not found"); + + // Load difficulties + nodes.clear(); + root->getNode("difficulties")->getNodes("characteristic", nodes); + for (const XMLNode *type : nodes) + { + type->get("name", &name); + m_difficulty_characteristics.insert(std::pair >(name, + std::unique_ptr(new XmlCharacteristic(type)))); + } + // Load kart type characteristics + nodes.clear(); + root->getNode("kart-types")->getNodes("characteristic", nodes); + for (const XMLNode *type : nodes) + { + type->get("name", &name); + m_kart_type_characteristics.insert(std::pair >(name, + std::unique_ptr(new XmlCharacteristic(type)))); + } + // Load player difficulties + nodes.clear(); + root->getNode("player-characteristics")->getNodes("characteristic", nodes); + for (const XMLNode *type : nodes) + { + type->get("name", &name); + m_player_characteristics.insert(std::pair >(name, + std::unique_ptr(new XmlCharacteristic(type)))); + } +} + +//----------------------------------------------------------------------------- +/** Loads a single kart and (if not disabled) the corresponding 3d model. * \param filename Full path to the kart config file. */ bool KartPropertiesManager::loadKart(const std::string &dir) { - std::string config_filename=dir+"/kart.xml"; + std::string config_filename = dir + "/kart.xml"; if(!file_manager->fileExists(config_filename)) return false; @@ -191,7 +248,7 @@ bool KartPropertiesManager::loadKart(const std::string &dir) } catch (std::runtime_error& err) { - Log::error("[Kart_Properties_Manager]","Giving up loading '%s': %s", + Log::error("[KartPropertiesManager]", "Giving up loading '%s': %s", config_filename.c_str(), err.what()); return false; } @@ -201,7 +258,7 @@ bool KartPropertiesManager::loadKart(const std::string &dir) if (kart_properties->getVersion() < stk_config->m_min_kart_version || kart_properties->getVersion() > stk_config->m_max_kart_version) { - Log::warn("[Kart_Properties_Manager]", "Warning: kart '%s' is not " + Log::warn("[KartPropertiesManager]", "Warning: kart '%s' is not " "supported by this binary, ignored.", kart_properties->getIdent().c_str()); delete kart_properties; @@ -221,7 +278,7 @@ bool KartPropertiesManager::loadKart(const std::string &dir) } m_all_kart_dirs.push_back(dir); return true; -} // loadKartData +} // loadKart //----------------------------------------------------------------------------- /** Sets the name of a mesh to use as a hat for all karts. @@ -235,6 +292,36 @@ void KartPropertiesManager::setHatMeshName(const std::string &hat_name) } } // setHatMeshName +//----------------------------------------------------------------------------- +const AbstractCharacteristic* KartPropertiesManager::getDifficultyCharacteristic(const std::string &type) const +{ + std::map >::const_iterator + it = m_difficulty_characteristics.find(type); + if (it == m_difficulty_characteristics.cend()) + return nullptr; + return it->second.get(); +} // getDifficultyCharacteristic + +//----------------------------------------------------------------------------- +const AbstractCharacteristic* KartPropertiesManager::getKartTypeCharacteristic(const std::string &type) const +{ + std::map >::const_iterator + it = m_kart_type_characteristics.find(type); + if (it == m_kart_type_characteristics.cend()) + return nullptr; + return it->second.get(); +} // getKartTypeCharacteristic + +//----------------------------------------------------------------------------- +const AbstractCharacteristic* KartPropertiesManager::getPlayerCharacteristic(const std::string &type) const +{ + std::map >::const_iterator + it = m_player_characteristics.find(type); + if (it == m_player_characteristics.cend()) + return nullptr; + return it->second.get(); +} // getPlayerCharacteristic + //----------------------------------------------------------------------------- /** Returns index of the kart properties with the given ident. * \return Index of kart (between 0 and number of karts - 1). diff --git a/src/karts/kart_properties_manager.hpp b/src/karts/kart_properties_manager.hpp index bcaedf8e6..af621b4e7 100644 --- a/src/karts/kart_properties_manager.hpp +++ b/src/karts/kart_properties_manager.hpp @@ -22,13 +22,16 @@ #include "utils/ptr_vector.hpp" #include +#include #include "network/remote_kart_info.hpp" #include "utils/no_copy.hpp" #define ALL_KART_GROUPS_ID "all" +class AbstractCharacteristic; class KartProperties; +class XMLNode; /** * \ingroup karts @@ -58,6 +61,11 @@ private: * all clients or not. */ std::vector m_kart_available; + std::unique_ptr m_base_characteristic; + std::map > m_difficulty_characteristics; + std::map > m_kart_type_characteristics; + std::map > m_player_characteristics; + protected: typedef PtrVector KartPropertiesVector; @@ -74,6 +82,7 @@ public: int getKartByGroup(const std::string& group, int i) const; + void loadCharacteristics (const XMLNode *root); bool loadKart (const std::string &dir); void loadAllKarts (bool loading_icon = true); void unloadAllKarts (); @@ -89,6 +98,18 @@ public: std::vector *ai_list); void setHatMeshName(const std::string &hat_name); // ------------------------------------------------------------------------ + /** Get the characteristic that holds the base values. */ + const AbstractCharacteristic* getBaseCharacteristic() const { return m_base_characteristic.get(); } + // ------------------------------------------------------------------------ + /** Get a characteristic that holds the values for a certain difficulty. */ + const AbstractCharacteristic* getDifficultyCharacteristic(const std::string &type) const; + // ------------------------------------------------------------------------ + /** Get a characteristic that holds the values for a kart type. */ + const AbstractCharacteristic* getKartTypeCharacteristic(const std::string &type) const; + // ------------------------------------------------------------------------ + /** Get a characteristic that holds the values for a player difficulty. */ + const AbstractCharacteristic* getPlayerCharacteristic(const std::string &type) const; + // ------------------------------------------------------------------------ /** Returns a list of all groups. */ const std::vector& getAllGroups() const {return m_all_groups;} // ------------------------------------------------------------------------ diff --git a/src/karts/kart_with_stats.cpp b/src/karts/kart_with_stats.cpp index 22f9a39b4..15851c9b7 100644 --- a/src/karts/kart_with_stats.cpp +++ b/src/karts/kart_with_stats.cpp @@ -26,7 +26,7 @@ KartWithStats::KartWithStats(const std::string& ident, unsigned int world_kart_id, int position, const btTransform& init_transform, - const PlayerDifficulty *difficulty) + PerPlayerDifficulty difficulty) : Kart(ident, world_kart_id, position, init_transform, difficulty) { diff --git a/src/karts/kart_with_stats.hpp b/src/karts/kart_with_stats.hpp index a85870a84..906d174a6 100644 --- a/src/karts/kart_with_stats.hpp +++ b/src/karts/kart_with_stats.hpp @@ -75,7 +75,7 @@ public: unsigned int world_kart_id, int position, const btTransform& init_transform, - const PlayerDifficulty *difficulty); + PerPlayerDifficulty difficulty); virtual void update(float dt); virtual void reset(); virtual void collectedItem(Item *item, int add_info); diff --git a/src/karts/max_speed.cpp b/src/karts/max_speed.cpp index c044f77d4..377720d81 100644 --- a/src/karts/max_speed.cpp +++ b/src/karts/max_speed.cpp @@ -62,8 +62,7 @@ MaxSpeed::MaxSpeed(AbstractKart *kart) */ void MaxSpeed::reset() { - m_current_max_speed = m_kart->getKartProperties()->getMaxSpeed() * - m_kart->getPlayerDifficulty()->getMaxSpeed(); + m_current_max_speed = m_kart->getKartProperties()->getEngineMaxSpeed(); m_min_speed = -1.0f; for(unsigned int i=MS_DECREASE_MIN; igetKartProperties()->getMaxSpeed() * - m_kart->getPlayerDifficulty()->getMaxSpeed(); + m_current_max_speed = m_kart->getKartProperties()->getEngineMaxSpeed(); // Then add the speed increase from each category // ---------------------------------------------- diff --git a/src/karts/player_difficulty.cpp b/src/karts/player_difficulty.cpp deleted file mode 100644 index d674b7e41..000000000 --- a/src/karts/player_difficulty.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2006-2015 SuperTuxKart-Team -// -// 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. - -#include "karts/player_difficulty.hpp" - -#include "config/stk_config.hpp" -#include "io/xml_node.hpp" -#include "karts/skidding_properties.hpp" -#include "race/race_manager.hpp" -#include "modes/world.hpp" -#include "utils/log.hpp" - -/** - * The constructor initialises all values with default values. - */ -PlayerDifficulty::PlayerDifficulty(const std::string &filename) -{ - // Set all other values to undefined, so that it can later be tested - // if everything is defined properly. - m_mass = m_brake_factor = m_brake_time_increase = m_rescue_time = - m_explosion_time = m_explosion_invulnerability_time = m_zipper_time = - m_zipper_fade_out_time = m_zipper_force = m_zipper_speed_gain = - m_zipper_max_speed_increase = m_rubber_band_max_length = - m_rubber_band_force = m_rubber_band_duration = - m_rubber_band_speed_increase = m_rubber_band_fade_out_time = - m_nitro_consumption = m_nitro_max_speed_increase = - m_nitro_engine_force = m_nitro_duration = m_nitro_fade_out_time = - m_bubblegum_time = m_bubblegum_torque = m_bubblegum_speed_fraction = - m_bubblegum_fade_in_time = m_swatter_duration = m_squash_duration = - m_squash_slowdown = m_max_speed_reverse_ratio = m_slipstream_length = - m_slipstream_width = m_slipstream_collect_time = - m_slipstream_use_time = m_slipstream_add_power = - m_slipstream_min_speed = m_slipstream_max_speed_increase = - m_slipstream_duration = m_slipstream_fade_out_time = 1; - - m_startup_times.resize(RaceManager::DIFFICULTY_COUNT, 1); - m_startup_boost.resize(RaceManager::DIFFICULTY_COUNT, 1); - - // The default constructor for stk_config uses filename="" - if (filename != "") - load(filename, "normal"); -} // PlayerDifficulty - -//----------------------------------------------------------------------------- -/** Destructor, dereferences the kart model. */ -PlayerDifficulty::~PlayerDifficulty() -{ -} // ~PlayerDifficulty - -//----------------------------------------------------------------------------- -/** */ -std::string PlayerDifficulty::getIdent() const -{ - switch(m_difficulty) - { - case PLAYER_DIFFICULTY_NORMAL: return "normal"; break; - case PLAYER_DIFFICULTY_HANDICAP: return "handicap"; break; - default: assert(false); - } - return ""; -} - -//----------------------------------------------------------------------------- -/** Loads the difficulty properties from a file. - * \param filename Filename to load. - * \param node Name of the xml node to load the data from - */ -void PlayerDifficulty::load(const std::string &filename, const std::string &node) -{ - const XMLNode* root = new XMLNode(filename); - getAllData(root->getNode(node)); - if(root) - delete root; -} // load - -//----------------------------------------------------------------------------- -/** Actually reads in the data from the xml file. - * \param root Root of the xml tree. - */ -void PlayerDifficulty::getAllData(const XMLNode * root) -{ - if(const XMLNode *mass_node = root->getNode("mass")) - mass_node->get("value", &m_mass); - - if(const XMLNode *engine_node = root->getNode("engine")) - { - engine_node->get("brake-factor", &m_brake_factor); - engine_node->get("brake-time-increase", &m_brake_time_increase); - engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio); - engine_node->get("power", &m_engine_power); - engine_node->get("max-speed", &m_max_speed); - } - - if(const XMLNode *nitro_node = root->getNode("nitro")) - { - nitro_node->get("consumption", &m_nitro_consumption ); - nitro_node->get("max-speed-increase", &m_nitro_max_speed_increase); - nitro_node->get("engine-force", &m_nitro_engine_force ); - nitro_node->get("duration", &m_nitro_duration ); - nitro_node->get("fade-out-time", &m_nitro_fade_out_time ); - } - - if(const XMLNode *bubble_node = root->getNode("bubblegum")) - { - bubble_node->get("time", &m_bubblegum_time ); - bubble_node->get("speed-fraction", &m_bubblegum_speed_fraction); - bubble_node->get("torque", &m_bubblegum_torque ); - bubble_node->get("fade-in-time", &m_bubblegum_fade_in_time ); - } - - if(const XMLNode *rescue_node = root->getNode("rescue")) - rescue_node->get("time", &m_rescue_time); - - if(const XMLNode *explosion_node = root->getNode("explosion")) - { - explosion_node->get("time", &m_explosion_time); - explosion_node->get("invulnerability-time", - &m_explosion_invulnerability_time); - } - - if(const XMLNode *slipstream_node = root->getNode("slipstream")) - { - slipstream_node->get("length", &m_slipstream_length ); - slipstream_node->get("width", &m_slipstream_width ); - slipstream_node->get("collect-time", &m_slipstream_collect_time ); - slipstream_node->get("use-time", &m_slipstream_use_time ); - slipstream_node->get("add-power", &m_slipstream_add_power ); - slipstream_node->get("min-speed", &m_slipstream_min_speed ); - slipstream_node->get("max-speed-increase", - &m_slipstream_max_speed_increase); - slipstream_node->get("duration", &m_slipstream_duration ); - slipstream_node->get("fade-out-time", &m_slipstream_fade_out_time ); - } - - if(const XMLNode *plunger_node= root->getNode("plunger")) - { - plunger_node->get("band-max-length", &m_rubber_band_max_length ); - plunger_node->get("band-force", &m_rubber_band_force ); - plunger_node->get("band-duration", &m_rubber_band_duration ); - plunger_node->get("band-speed-increase",&m_rubber_band_speed_increase); - plunger_node->get("band-fade-out-time", &m_rubber_band_fade_out_time ); - plunger_node->get("in-face-time", &m_plunger_in_face_duration); - } - - if(const XMLNode *zipper_node= root->getNode("zipper")) - { - zipper_node->get("time", &m_zipper_time ); - zipper_node->get("fade-out-time", &m_zipper_fade_out_time ); - zipper_node->get("force", &m_zipper_force ); - zipper_node->get("speed-gain", &m_zipper_speed_gain ); - zipper_node->get("max-speed-increase", &m_zipper_max_speed_increase); - } - - if(const XMLNode *swatter_node= root->getNode("swatter")) - { - swatter_node->get("duration", &m_swatter_duration ); - swatter_node->get("squash-duration", &m_squash_duration ); - swatter_node->get("squash-slowdown", &m_squash_slowdown ); - } - - if(const XMLNode *startup_node= root->getNode("startup")) - { - startup_node->get("time", &m_startup_times); - startup_node->get("boost", &m_startup_boost); - } -} // getAllData - -// ---------------------------------------------------------------------------- -/** Called the first time a kart accelerates after 'ready-set-go'. It searches - * through m_startup_times to find the appropriate slot, and returns the - * speed-boost from the corresponding entry in m_startup_boost. - * If the kart started too slow (i.e. slower than the longest time in - * m_startup_times, it returns 0. - */ -float PlayerDifficulty::getStartupBoost() const -{ - float t = World::getWorld()->getTime(); - for(unsigned int i=0; i -#include - - -class XMLNode; - -/** - * \brief This class stores values that modify the properties of a kart. - * This includes physical properties like speed and the effect of items. - * The values stored in this class get multiplied with the current - * properties of the kart. If all values here are set to 1, nothing changes. - * - * \ingroup karts - */ -class PlayerDifficulty -{ -private: - /** Actual difficulty */ - PerPlayerDifficulty m_difficulty; - - // ----------------- - /** Weight of kart. */ - float m_mass; - - /** Maximum force from engine for each difficulty. */ - float m_engine_power; - - /** Braking factor * engine_power braking force. */ - float m_brake_factor; - - /** Brake_time * m_brake_time_increase will increase the break time - * over time. */ - float m_brake_time_increase; - - /** Time a kart is moved upwards after when it is rescued. */ - float m_rescue_time; - - /** Time an animated explosion is shown. Longer = more delay for kart. */ - float m_explosion_time; - - /** How long a kart is invulnerable after it is hit by an explosion. */ - float m_explosion_invulnerability_time; - - /** Duration a zipper is active. */ - float m_zipper_time; - - /** Fade out time for a zipper. */ - float m_zipper_fade_out_time; - - /** Additional force added to the acceleration. */ - float m_zipper_force; - - /** Initial one time speed gain. */ - float m_zipper_speed_gain; - - /** Absolute increase of the kart's maximum speed (in m/s). */ - float m_zipper_max_speed_increase; - - /** Max. length of plunger rubber band. */ - float m_rubber_band_max_length; - /** Force of an attached rubber band. */ - /** Duration a rubber band works. */ - float m_rubber_band_force; - /** How long the rubber band will fly. */ - float m_rubber_band_duration; - /** Increase of maximum speed of the kart when the rubber band pulls. */ - float m_rubber_band_speed_increase; - /** Fade out time when the rubber band is removed. */ - float m_rubber_band_fade_out_time; - /**Duration of plunger in face depending on difficulty. */ - float m_plunger_in_face_duration; - /** Nitro consumption. */ - float m_nitro_consumption; - /* How much the speed of a kart might exceed its maximum speed (in m/s). */ - float m_nitro_max_speed_increase; - /** Additional engine force to affect the kart. */ - float m_nitro_engine_force; - /** How long the increased nitro max speed will be valid after - * the kart stops using nitro (and the fade-out-time starts). */ - float m_nitro_duration; - /** Duration during which the increased maximum speed - * due to nitro fades out. */ - float m_nitro_fade_out_time; - /** Bubble gum diration. */ - float m_bubblegum_time; - /** Torque to add when a bubble gum was hit in order to make the kart go - * sideways a bit. */ - float m_bubblegum_torque; - /** Fraction of top speed that can be reached maximum after hitting a - * bubble gum. */ - float m_bubblegum_speed_fraction; - /** How long to fade in the slowdown for a bubble gum. */ - float m_bubblegum_fade_in_time; - /** How long the swatter lasts. */ - float m_swatter_duration; - /** How long a kart will remain squashed. */ - float m_squash_duration; - /** The slowdown to apply while a kart is squashed. The new maxspeed - * is max_speed*m_squash_slowdown. */ - float m_squash_slowdown; - - /** The maximum speed at each difficulty. */ - float m_max_speed; - - float m_max_speed_reverse_ratio; - - /** How far behind a kart slipstreaming is effective. */ - float m_slipstream_length; - /** How wide the slipstream area is at the end. */ - float m_slipstream_width; - /** Time after which sstream gives a bonus. */ - float m_slipstream_collect_time; - /** Time slip-stream bonus is effective. */ - float m_slipstream_use_time; - /** Additional power due to sstreaming. */ - float m_slipstream_add_power; - /** Minimum speed for slipstream to take effect. */ - float m_slipstream_min_speed; - /** How much the speed of the kart might exceed its - * normal maximum speed. */ - float m_slipstream_max_speed_increase; - /** How long the higher speed lasts after slipstream stopped working. */ - float m_slipstream_duration; - /** How long the slip stream speed increase will gradually be reduced. */ - float m_slipstream_fade_out_time; - - /** If the kart starts within the specified time at index I after 'go', - * it receives the speed boost from m_startup_boost[I]. */ - std::vector m_startup_times; - - /** The startup boost is the kart starts fast enough. */ - std::vector m_startup_boost; - - - void load (const std::string &filename, - const std::string &node); - - -public: - PlayerDifficulty (const std::string &filename=""); - ~PlayerDifficulty (); - void getAllData (const XMLNode * root); - std::string getIdent() const; - float getStartupBoost () const; - - // ------------------------------------------------------------------------ - /** Returns the maximum engine power depending on difficulty. */ - float getMaxPower () const {return m_engine_power; } - - // ------------------------------------------------------------------------ - /** Get braking information. */ - float getBrakeFactor () const {return m_brake_factor; } - - // ------------------------------------------------------------------------ - /** Returns the additional brake factor which depends on time. */ - float getBrakeTimeIncrease() const { return m_brake_time_increase; } - - // ------------------------------------------------------------------------ - /** Get maximum reverse speed ratio. */ - float getMaxSpeedReverseRatio () const - {return m_max_speed_reverse_ratio; } - - // ------------------------------------------------------------------------ - /** Returns the maximum speed dependent on the difficult level. */ - float getMaxSpeed () const { return m_max_speed; } - - // ------------------------------------------------------------------------ - /** Returns the nitro consumption. */ - float getNitroConsumption () const {return m_nitro_consumption; } - - // ------------------------------------------------------------------------ - /** Returns the increase of maximum speed due to nitro. */ - float getNitroMaxSpeedIncrease () const - {return m_nitro_max_speed_increase; } - - // ------------------------------------------------------------------------ - float getNitroEngineForce () const {return m_nitro_engine_force; } - // ------------------------------------------------------------------------ - /** Returns how long the increased nitro max speed will be valid after - * the kart stops using nitro (and the fade-out-time starts). */ - float getNitroDuration () const {return m_nitro_duration; } - - // ------------------------------------------------------------------------ - /** Returns the duration during which the increased maximum speed - * due to nitro fades out. */ - float getNitroFadeOutTime () const {return m_nitro_fade_out_time; } - // ------------------------------------------------------------------------ - /** Returns how long a bubble gum is active. */ - float getBubblegumTime() const { return m_bubblegum_time; } - // ------------------------------------------------------------------------ - /** Returns the torque to add when a bubble gum was hit . */ - float getBubblegumTorque() const { return m_bubblegum_torque; } - // ------------------------------------------------------------------------ - /** Returns the fraction of top speed that can be reached maximum after - * hitting a bubble gum. */ - float getBubblegumSpeedFraction() const {return m_bubblegum_speed_fraction;} - // ------------------------------------------------------------------------ - /** Returns how long to fade in the slowdown for a bubble gum. */ - float getBubblegumFadeInTime() const { return m_bubblegum_fade_in_time; } - - // ------------------------------------------------------------------------ - /** Returns the time a kart is rised during a rescue. */ - float getRescueTime () const {return m_rescue_time; } - - // ------------------------------------------------------------------------ - /** Returns the time an explosion animation is shown. */ - float getExplosionTime () const {return m_explosion_time; } - - // ------------------------------------------------------------------------ - /** Returns how long a kart is invulnerable after being hit by an - explosion. */ - float getExplosionInvulnerabilityTime() const - { return m_explosion_invulnerability_time; } - - // ------------------------------------------------------------------------ - /** Returns the maximum length of a rubber band before it breaks. */ - float getRubberBandMaxLength () const {return m_rubber_band_max_length;} - - // ------------------------------------------------------------------------ - /** Returns force a rubber band has when attached to a kart. */ - float getRubberBandForce () const {return m_rubber_band_force; } - - // ------------------------------------------------------------------------ - /** Returns the duration a rubber band is active for. */ - float getRubberBandDuration () const {return m_rubber_band_duration; } - - // ------------------------------------------------------------------------ - /** Returns the increase of maximum speed while a rubber band is - * pulling. */ - float getRubberBandSpeedIncrease() const - { - return m_rubber_band_speed_increase; - } - - // ------------------------------------------------------------------------ - /** Return the fade out time once a rubber band is removed. */ - float getRubberBandFadeOutTime() const - { - return m_rubber_band_fade_out_time; - } - - // ------------------------------------------------------------------------ - /** Returns duration of a plunger in your face. */ - float getPlungerInFaceTime () const {return m_plunger_in_face_duration;} - - // ------------------------------------------------------------------------ - /** Returns the time a zipper is active. */ - float getZipperTime () const {return m_zipper_time; } - - // ------------------------------------------------------------------------ - /** Returns the time a zipper is active. */ - float getZipperFadeOutTime () const {return m_zipper_fade_out_time; } - - // ------------------------------------------------------------------------ - /** Returns the additional force added applied to the kart. */ - float getZipperForce () const { return m_zipper_force; } - - // ------------------------------------------------------------------------ - /** Returns the initial zipper speed gain. */ - float getZipperSpeedGain () const { return m_zipper_speed_gain; } - - // ------------------------------------------------------------------------ - /** Returns the increase of the maximum speed of the kart - * if a zipper is active. */ - float getZipperMaxSpeedIncrease () const - { return m_zipper_max_speed_increase;} - - // ------------------------------------------------------------------------ - /** Returns how far behind a kart slipstreaming works. */ - float getSlipstreamLength () const {return m_slipstream_length; } - - // ------------------------------------------------------------------------ - /** Returns how wide the slipstream area is at the end. */ - float getSlipstreamWidth () const {return m_slipstream_width; } - - // ------------------------------------------------------------------------ - /** Returns time after which slipstream has maximum effect. */ - float getSlipstreamCollectTime () const - {return m_slipstream_collect_time; } - - // ------------------------------------------------------------------------ - /** Returns time after which slipstream has maximum effect. */ - float getSlipstreamUseTime () const {return m_slipstream_use_time; } - - // ------------------------------------------------------------------------ - /** Returns additional power due to slipstreaming. */ - float getSlipstreamAddPower () const {return m_slipstream_add_power; } - - // ------------------------------------------------------------------------ - /** Returns the minimum slipstream speed. */ - float getSlipstreamMinSpeed () const {return m_slipstream_min_speed; } - - // ------------------------------------------------------------------------ - /** Returns the increase of the maximum speed of a kart - * due to slipstream. */ - float getSlipstreamMaxSpeedIncrease() const - { return m_slipstream_max_speed_increase; } - // ------------------------------------------------------------------------ - /** Returns how long the higher speed lasts after slipstream - * stopped working. */ - float getSlipstreamDuration () const { return m_slipstream_duration; } - - // ------------------------------------------------------------------------ - /** Returns how long the slip stream speed increase will gradually - * be reduced. */ - float getSlipstreamFadeOutTime () const - { return m_slipstream_fade_out_time; } - - // ------------------------------------------------------------------------ - /** Returns how long a swatter will stay attached/ready to be used. */ - float getSwatterDuration() const { return m_swatter_duration; } - - // ------------------------------------------------------------------------ - /** Returns how long a kart remains squashed. */ - float getSquashDuration() const {return m_squash_duration; } - - // ------------------------------------------------------------------------ - /** Returns the slowdown of a kart that is squashed. */ - float getSquashSlowdown() const {return m_squash_slowdown; } -}; // KartProperties - -#endif - diff --git a/src/karts/rescue_animation.cpp b/src/karts/rescue_animation.cpp index c88273a80..29e2bcee9 100644 --- a/src/karts/rescue_animation.cpp +++ b/src/karts/rescue_animation.cpp @@ -39,8 +39,7 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue) { m_referee = new Referee(*m_kart); m_kart->getNode()->addChild(m_referee->getSceneNode()); - m_timer = m_kart->getKartProperties()->getRescueTime() * - m_kart->getPlayerDifficulty()->getRescueTime(); + m_timer = m_kart->getKartProperties()->getRescueDuration(); m_velocity = m_kart->getKartProperties()->getRescueHeight() / m_timer; m_xyz = m_kart->getXYZ(); diff --git a/src/karts/skidding.cpp b/src/karts/skidding.cpp index 2d006409c..15aafaf25 100644 --- a/src/karts/skidding.cpp +++ b/src/karts/skidding.cpp @@ -36,7 +36,7 @@ /** Constructor of the skidding object. */ -Skidding::Skidding(Kart *kart, const SkiddingProperties *sp) +Skidding::Skidding(Kart *kart) { #ifdef SKID_DEBUG m_predicted_curve = new ShowCurve(0.05f, 0.05f, @@ -47,8 +47,8 @@ Skidding::Skidding(Kart *kart, const SkiddingProperties *sp) m_actual_curve->setVisible(false); #endif m_kart = kart; - copyFrom(sp); - m_skid_reduce_turn_delta = m_skid_reduce_turn_max - m_skid_reduce_turn_min; + m_skid_reduce_turn_delta = m_kart->getKartProperties()->getSkidReduceTurnMax() + - m_kart->getKartProperties()->getSkidReduceTurnMin(); reset(); } // Skidding @@ -95,13 +95,15 @@ void Skidding::reset() */ void Skidding::updateSteering(float steer, float dt) { + const KartProperties *kp = m_kart->getKartProperties(); + switch(m_skid_state) { case SKID_SHOW_GFX_LEFT: case SKID_SHOW_GFX_RIGHT: case SKID_NONE: m_real_steering = steer; - if(m_skid_time0) + if (m_skid_time < kp->getSkidVisualTime() && m_skid_time > 0) { float f = m_visual_rotation - m_visual_rotation*dt/m_skid_time; // Floating point errors when m_skid_time is very close to 0 @@ -125,25 +127,27 @@ void Skidding::updateSteering(float steer, float dt) case SKID_ACCUMULATE_RIGHT: { float f = (1.0f+steer)*0.5f; // map [-1,1] --> [0, 1] - m_real_steering = m_skid_reduce_turn_min+ - m_skid_reduce_turn_delta*f; - if(m_skid_time < m_skid_visual_time) - m_visual_rotation = m_skid_visual*m_real_steering*m_skid_time - / m_skid_visual_time; + m_real_steering = kp->getSkidReduceTurnMin() + + m_skid_reduce_turn_delta * f; + if(m_skid_time < kp->getSkidVisualTime()) + m_visual_rotation = kp->getSkidVisual() + * m_real_steering * m_skid_time + / kp->getSkidVisualTime(); else - m_visual_rotation = m_skid_visual * m_real_steering; + m_visual_rotation = kp->getSkidVisual() * m_real_steering; break; } case SKID_ACCUMULATE_LEFT: { float f = (-1.0f+steer)*0.5f; // map [-1,1] --> [-1, 0] - m_real_steering = -m_skid_reduce_turn_min+ - m_skid_reduce_turn_delta*f; - if(m_skid_time < m_skid_visual_time) - m_visual_rotation = m_skid_visual*m_real_steering*m_skid_time - / m_skid_visual_time; + m_real_steering = -kp->getSkidReduceTurnMin() + + m_skid_reduce_turn_delta * f; + if(m_skid_time < kp->getSkidVisualTime()) + m_visual_rotation = kp->getSkidVisual() + * m_real_steering * m_skid_time + / kp->getSkidVisualTime(); else - m_visual_rotation = m_skid_visual * m_real_steering; + m_visual_rotation = kp->getSkidVisual() * m_real_steering; break; } @@ -173,13 +177,13 @@ float Skidding::getSteeringWhenSkidding(float steering) const break; case SKID_ACCUMULATE_RIGHT: { - float f = (steering - m_skid_reduce_turn_min) + float f = (steering - m_kart->getKartProperties()->getSkidReduceTurnMin()) / m_skid_reduce_turn_delta; return f *2.0f-1.0f; } case SKID_ACCUMULATE_LEFT: { - float f = (steering + m_skid_reduce_turn_min) + float f = (steering + m_kart->getKartProperties()->getSkidReduceTurnMin()) / m_skid_reduce_turn_delta; return 2.0f * f +1.0f; } @@ -198,6 +202,8 @@ float Skidding::getSteeringWhenSkidding(float steering) const void Skidding::update(float dt, bool is_on_ground, float steering, KartControl::SkidControl skidding) { + const KartProperties *kp = m_kart->getKartProperties(); + // If a kart animation is shown, stop all skidding bonuses. if(m_kart->getKartAnimation()) { @@ -212,7 +218,7 @@ void Skidding::update(float dt, bool is_on_ground, #endif // No skidding backwards or while stopped - if(m_kart->getSpeed() < m_min_skid_speed && + if(m_kart->getSpeed() < kp->getSkidMinSpeed() && m_skid_state != SKID_NONE && m_skid_state != SKID_BREAK) { m_skid_state = SKID_BREAK; @@ -223,15 +229,16 @@ void Skidding::update(float dt, bool is_on_ground, m_skid_bonus_ready = false; if (is_on_ground) { - if((fabs(steering) > 0.001f) && - m_kart->getSpeed()>m_min_skid_speed && - (skidding==KartControl::SC_LEFT||skidding==KartControl::SC_RIGHT)) + if ((fabs(steering) > 0.001f) && + m_kart->getSpeed() > kp->getSkidMinSpeed() && + (skidding == KartControl::SC_LEFT || skidding == KartControl::SC_RIGHT)) { - m_skid_factor += m_skid_increase *dt/m_time_till_max_skid; + m_skid_factor += kp->getSkidIncrease() + * dt / kp->getSkidTimeTillMax(); } - else if(m_skid_factor>1.0f) + else if (m_skid_factor > 1.0f) { - m_skid_factor *= m_skid_decrease; + m_skid_factor *= kp->getSkidDecrease(); } } else @@ -239,10 +246,10 @@ void Skidding::update(float dt, bool is_on_ground, m_skid_factor = 1.0f; // Lose any skid factor as soon as we fly } - if(m_skid_factor>m_skid_max) - m_skid_factor = m_skid_max; + if (m_skid_factor > kp->getSkidMax()) + m_skid_factor = kp->getSkidMax(); else - if(m_skid_factor<1.0f) m_skid_factor = 1.0f; + if (m_skid_factor < 1.0f) m_skid_factor = 1.0f; // If skidding was started and a graphical jump should still // be displayed, update the data @@ -288,8 +295,9 @@ void Skidding::update(float dt, bool is_on_ground, break; // Don't allow skidding while the kart is (apparently) // still in the air, or when the kart is too slow - if(m_remaining_jump_time>0 || - m_kart->getSpeed() 0 || + m_kart->getSpeed() < kp->getSkidMinSpeed()) + break; m_skid_state = skidding==KartControl::SC_RIGHT ? SKID_ACCUMULATE_RIGHT @@ -300,14 +308,14 @@ void Skidding::update(float dt, bool is_on_ground, // Then use this speed to determine the impulse necessary to // reach this speed. float v = World::getWorld()->getTrack()->getGravity() - * 0.5f*m_physical_jump_time; + * 0.5f * kp->getSkidPhysicalJumpTime(); btVector3 imp(0, v / m_kart->getBody()->getInvMass(),0); m_kart->getVehicle()->getRigidBody()->applyCentralImpulse(imp); // Some karts might use a graphical-only jump. Set it up: m_jump_speed = World::getWorld()->getTrack()->getGravity() - * 0.5f*m_graphical_jump_time; - m_remaining_jump_time = m_graphical_jump_time; + * 0.5f * kp->getSkidGraphicalJumpTime(); + m_remaining_jump_time = kp->getSkidGraphicalJumpTime(); #ifdef SKID_DEBUG #define SPEED 20.0f @@ -318,13 +326,13 @@ void Skidding::update(float dt, bool is_on_ground, m_predicted_curve->setVisible(true); m_predicted_curve->setPosition(m_kart->getXYZ()); m_predicted_curve->setHeading(m_kart->getHeading()); - float angle = m_kart->getKartProperties() + float angle = kp ->getMaxSteerAngle(m_kart->getSpeed()) * fabsf(getSteeringFraction()); - angle = m_kart->getKartProperties() + angle = kp ->getMaxSteerAngle(SPEED) * fabsf(getSteeringFraction()); - float r = m_kart->getKartProperties()->getWheelBase() + float r = kp->getWheelBase() / asin(angle)*1.0f; const int num_steps = 50; @@ -335,7 +343,7 @@ void Skidding::update(float dt, bool is_on_ground, { float real_x = m_skid_state==SKID_ACCUMULATE_LEFT ? -x : x; Vec3 xyz(real_x, 0.2f, sqrt(r*r-(r-x)*(r-x))*(1.0f+SPEED/150.0f) - *(1+(angle/m_kart->getKartProperties()->getMaxSteerAngle(SPEED)-0.6f)*0.1f)); + *(1+(angle/kp->getMaxSteerAngle(SPEED)-0.6f)*0.1f)); Vec3 xyz1=m_kart->getTrans()(xyz); Log::debug("Skidding", "predict %f %f %f speed %f angle %f", xyz1.getX(), xyz1.getY(), xyz1.getZ(), @@ -368,7 +376,7 @@ void Skidding::update(float dt, bool is_on_ground, Log::debug("Skidding", "actual %f %f %f turn %f speed %f angle %f", m_kart->getXYZ().getX(),m_kart->getXYZ().getY(),m_kart->getXYZ().getZ(), m_real_steering, m_kart->getSpeed(), - m_kart->getKartProperties()->getMaxSteerAngle(m_kart->getSpeed())); + kp->getMaxSteerAngle(m_kart->getSpeed())); #endif m_skid_time += dt; float bonus_time, bonus_speed, bonus_force; @@ -388,11 +396,11 @@ void Skidding::update(float dt, bool is_on_ground, m_skid_state = m_skid_state == SKID_ACCUMULATE_LEFT ? SKID_SHOW_GFX_LEFT : SKID_SHOW_GFX_RIGHT; - float t = std::min(m_skid_time, m_skid_visual_time); - t = std::min(t, m_skid_revert_visual_time); + float t = std::min(m_skid_time, kp->getSkidVisualTime()); + t = std::min(t, kp->getSkidRevertVisualTime()); float vso = getVisualSkidRotation(); - btVector3 rot(0, vso*m_post_skid_rotate_factor, 0); + btVector3 rot(0, vso * kp->getSkidPostSkidRotateFactor(), 0); m_kart->getVehicle()->setTimedRotation(t, rot); // skid_time is used to count backwards for the GFX m_skid_time = t; @@ -452,16 +460,19 @@ unsigned int Skidding::getSkidBonus(float *bonus_time, float *bonus_speed, float *bonus_force) const { + const KartProperties *kp = m_kart->getKartProperties(); + *bonus_time = 0; *bonus_speed = 0; *bonus_force = 0; - for(unsigned int i=0; igetSkidBonusSpeed().size(); i++) { - if(m_skid_time<=m_skid_time_till_bonus[i]) return i; - *bonus_speed = m_skid_bonus_speed[i]; - *bonus_time = m_skid_bonus_time[i]; - *bonus_force = m_skid_bonus_force[i]; + if (m_skid_time <= kp->getSkidTimeTillBonus()[i]) + return i; + *bonus_speed = kp->getSkidBonusSpeed()[i]; + *bonus_time = kp->getSkidBonusTime()[i]; + *bonus_force = kp->getSkidBonusForce()[i]; } - return (unsigned int) m_skid_bonus_speed.size(); + return (unsigned int) kp->getSkidBonusSpeed().size(); } // getSkidBonusForce diff --git a/src/karts/skidding.hpp b/src/karts/skidding.hpp index a53c0d989..4d4d854d8 100644 --- a/src/karts/skidding.hpp +++ b/src/karts/skidding.hpp @@ -19,7 +19,6 @@ #ifndef HEADER_SKIDDING_HPP #define HEADER_SKIDDING_HPP -#include "karts/skidding_properties.hpp" #include "karts/controller/kart_control.hpp" #include "utils/leak_check.hpp" #include "utils/no_copy.hpp" @@ -35,7 +34,7 @@ class ShowCurve; #undef SKID_DEBUG -class Skidding : public SkiddingProperties +class Skidding { public: LEAK_CHECK(); @@ -101,7 +100,7 @@ private: float *bonus_force) const; void updateSteering(float steer, float dt); public: - Skidding(Kart *kart, const SkiddingProperties *sp); + Skidding(Kart *kart); ~Skidding(); void reset(); void update(float dt, bool is_on_ground, float steer, diff --git a/src/karts/skidding_properties.cpp b/src/karts/skidding_properties.cpp deleted file mode 100644 index 0f2f28d6b..000000000 --- a/src/karts/skidding_properties.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2012-2015 Joerg Henrichs -// -// 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. - -#include "karts/skidding_properties.hpp" - -#include "io/xml_node.hpp" -#include "utils/log.hpp" - -#include - -float SkiddingProperties::UNDEFINED = -99.9f; - -SkiddingProperties::SkiddingProperties() -{ - m_skid_increase = UNDEFINED; - m_skid_decrease = UNDEFINED; - m_skid_max = UNDEFINED; - m_time_till_max_skid = UNDEFINED; - m_skid_visual = UNDEFINED; - m_skid_visual_time = UNDEFINED; - m_skid_revert_visual_time = UNDEFINED; - m_post_skid_rotate_factor = UNDEFINED; - m_skid_reduce_turn_min = UNDEFINED; - m_skid_reduce_turn_max = UNDEFINED; - m_physical_jump_time = UNDEFINED; - m_graphical_jump_time = UNDEFINED; - m_min_skid_speed = UNDEFINED; - m_has_skidmarks = true; - - m_skid_bonus_time.clear(); - m_skid_bonus_speed.clear(); - m_skid_time_till_bonus.clear(); - m_skid_bonus_force.clear(); -} // SkiddingProperties - -// ---------------------------------------------------------------------------- -void SkiddingProperties::load(const XMLNode *skid_node) -{ - skid_node->get("increase", &m_skid_increase ); - skid_node->get("decrease", &m_skid_decrease ); - skid_node->get("max", &m_skid_max ); - skid_node->get("time-till-max", &m_time_till_max_skid ); - skid_node->get("visual", &m_skid_visual ); - skid_node->get("visual-time", &m_skid_visual_time ); - skid_node->get("revert-visual-time", &m_skid_revert_visual_time); - skid_node->get("post-skid-rotate-factor",&m_post_skid_rotate_factor); - skid_node->get("reduce-turn-min", &m_skid_reduce_turn_min ); - skid_node->get("reduce-turn-max", &m_skid_reduce_turn_max ); - skid_node->get("enable", &m_has_skidmarks ); - skid_node->get("bonus-time", &m_skid_bonus_time ); - skid_node->get("bonus-speed", &m_skid_bonus_speed ); - skid_node->get("time-till-bonus", &m_skid_time_till_bonus ); - skid_node->get("bonus-force", &m_skid_bonus_force ); - skid_node->get("physical-jump-time", &m_physical_jump_time ); - skid_node->get("graphical-jump-time", &m_graphical_jump_time ); - skid_node->get("min-speed", &m_min_skid_speed ); -} // load - -// ---------------------------------------------------------------------------- -void SkiddingProperties::checkAllSet(const std::string &filename) const -{ -#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \ - Log::fatal("Skidding_Properties", "Missing default value for '%s'"\ - "in '%s'.", \ - strA,filename.c_str()); \ - } - CHECK_NEG(m_skid_increase, "skid increase" ); - CHECK_NEG(m_skid_decrease, "skid decrease" ); - CHECK_NEG(m_skid_max, "skid max" ); - CHECK_NEG(m_time_till_max_skid, "skid time-till-max" ); - CHECK_NEG(m_skid_visual, "skid visual" ); - CHECK_NEG(m_skid_visual_time, "skid visual-time" ); - CHECK_NEG(m_skid_revert_visual_time, "skid revert-visual-time" ); - CHECK_NEG(m_post_skid_rotate_factor, "skid post-skid-rotate-factor" ); - CHECK_NEG(m_skid_reduce_turn_min, "skid reduce-turn-min" ); - CHECK_NEG(m_skid_reduce_turn_max, "skid reduce-turn-max" ); - CHECK_NEG(m_physical_jump_time, "skid physical-jump-time" ); - CHECK_NEG(m_graphical_jump_time, "skid graphical-jump-time" ); - CHECK_NEG(m_min_skid_speed, "skid min-speed" ); - - if(m_skid_time_till_bonus.size()==0) - Log::error("Skidding_Properties", "Warning: no skid time declared," - "can be ignored."); - if(m_skid_time_till_bonus.size()!=m_skid_bonus_speed.size()) - { - Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus" - "and bonus-speed\n must have same number of elements."); - } - if(m_skid_time_till_bonus.size()!=m_skid_bonus_time.size()) - { - Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus" - "and bonus-time must\n have same number of elements."); - } - if(m_skid_time_till_bonus.size()!=m_skid_bonus_force.size()) - { - Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus" - "and bonus-force must\n have same number of elements."); - } - for(unsigned int i=0; i=m_skid_time_till_bonus[i+1]) - { - Log::fatal("Skidding_Properties", "Warning: skid time-till-bonus" - "not sorted."); - } - } // for i - -} // check - -// ---------------------------------------------------------------------------- -void SkiddingProperties::copyFrom(const SkiddingProperties *destination) -{ - *this = *destination; -} // copyFrom - -// ---------------------------------------------------------------------------- - - -/* EOF */ diff --git a/src/karts/skidding_properties.hpp b/src/karts/skidding_properties.hpp deleted file mode 100644 index be9fe790a..000000000 --- a/src/karts/skidding_properties.hpp +++ /dev/null @@ -1,171 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2012-2015 Joerg Henrichs -// -// 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. - -#ifndef HEADER_SKIDDING_PROPERTIES_HPP -#define HEADER_SKIDDING_PROPERTIES_HPP - -#include "utils/leak_check.hpp" -#include "utils/no_copy.hpp" - -class Kart; -class XMLNode; - -#include -#include - -/** A simple class that stores all skidding related properties. It acts as - * interface between kart_properties and Skidding (to avoid either passing - * very many individual variables, or making KartProperties a dependency - * of Skidding). - * \ingroup karts - */ - -class SkiddingProperties -{ -public: - //LEAK_CHECK(); -protected: - /** Skidding is multiplied by this when skidding - * to increase to m_skid_increase. */ - float m_skid_increase; - - /** Skidding is multiplied by this when not skidding to decrease to 1.0. */ - float m_skid_decrease; - - /** How long it takes for visual skid to reach maximum. */ - float m_skid_visual_time; - - /** How long it takes for the physical and graphical bodies to be - * in sync again after a skid. */ - float m_skid_revert_visual_time; - - /** Time till maximum skidding is reached. */ - float m_time_till_max_skid; - - /** Maximal increase of steering when skidding. */ - float m_skid_max; - - /** Additional rotation of 3d model when skidding. */ - float m_skid_visual; - - /** Time for a small physical when skidding starts. */ - float m_physical_jump_time; - - /** Time for a small graphics-only jump when skidding starts. */ - float m_graphical_jump_time; - - /** This factor is used to determine how much the chassis of a kart - * should rotate to match the graphical view. A factor of 1 is - * identical, a smaller factor will rotate the kart less (which might - * feel better). */ - float m_post_skid_rotate_factor; - - /*** Minimum speed a kart must have before it can skid. */ - float m_min_skid_speed; - - /** Time of skidding before you get a bonus boost. It's possible to - * define more than one time, i.e. longer skidding gives more bonus. */ - std::vector m_skid_time_till_bonus; - - /** How much additional speed a kart gets when skidding. It's possible to - * define more than one speed, i.e. longer skidding gives more bonus. */ - std::vector m_skid_bonus_speed; - - /** How long the bonus will last. It's possible to define more than one - * time, i.e. longer skidding gives more bonus. */ - std::vector m_skid_bonus_time; - - /** Additional force accelerating the kart (in addition to the immediate - * speed bonus). Without this force turning to correct the direction - * after skidding will use up nearly all of the additional speed (turning - * reduces the forward engine impulse) */ - std::vector m_skid_bonus_force; - - /** A factor is used to reduce the amount of steering while skidding. This - * is the minimum factor used (i.e. resulting in the largest turn - * radius). */ - float m_skid_reduce_turn_min; - - /** A factor is used to reduce the amount of steering while skidding. This - * is the maximum factor used (i.e. resulting in the smallest turn - * radius). */ - float m_skid_reduce_turn_max; - - - /** Kart leaves skid marks. */ - bool m_has_skidmarks; - - /** Used to check that all values are defined in the xml file. */ - static float UNDEFINED; - -public: - - SkiddingProperties(); - void load(const XMLNode *skid_node); - void copyFrom(const SkiddingProperties *destination); - void checkAllSet(const std::string &filename) const; - // ------------------------------------------------------------------------ - /** Returns if the kart leaves skidmarks or not. */ - bool hasSkidmarks() const { return m_has_skidmarks; } - - // ------------------------------------------------------------------------ - /** Returns the maximum factor by which the steering angle - * can be increased. */ - float getMaxSkid() const {return m_skid_max; } - - // ------------------------------------------------------------------------ - /** Returns additional rotation of 3d model when skidding. */ - float getSkidVisual () const {return m_skid_visual; } - - // ------------------------------------------------------------------------ - /** Returns the time for the visual skid to reach maximum. */ - float getSkidVisualTime () const {return m_skid_visual_time; } - - // ------------------------------------------------------------------------ - /** Returns a factor to be used to determine how much the chassis of a - * kart should rotate to match the graphical view. A factor of 1 is - * identical, a smaller factor will rotate the kart less (which might - * feel better). */ - float getPostSkidRotateFactor () const {return m_post_skid_rotate_factor;} - - // ------------------------------------------------------------------------ - /** Returns the factor by which to recude the amount of steering while - skidding. */ - float getSkidReduceTurnMin () const { return m_skid_reduce_turn_min; } - // ------------------------------------------------------------------------ - float getSkidReduceTurnMax () const { return m_skid_reduce_turn_max; } - // ------------------------------------------------------------------------ - /** Returns how many boni are defined for this kart. */ - int getNumberOfBonusTimes() const { return (int) m_skid_bonus_time.size(); } - // ------------------------------------------------------------------------ - /** Returns how long a kart must skid in order to reach the specified - * bonus level. - * param n Bonus level (0<=n processors = + StringUtils::split(m_values[type], ' '); + // If the array should be completely replaced + // That has to happen when the size is not the same or it is not yet set + bool shouldReplace = false; + if (*is_set) + { + if (processors.size() != value.fv->size()) + shouldReplace = true; + else + { + std::vector::iterator fit = value.fv->begin(); + for (const std::string &processor : processors) + { + processFloat(processor, &*fit, is_set); + if (!*is_set) + { + Log::error("XmlCharacteristic::process", "Can't process %s", + processor.c_str()); + value.fv->clear(); + break; + } + fit++; + } + } + } + else + shouldReplace = true; + + if (shouldReplace) + { + value.fv->resize(processors.size()); + std::vector::iterator fit = value.fv->begin(); + for (const std::string &processor : processors) + { + *is_set = false; + processFloat(processor, &*fit, is_set); + + if (!*is_set) + { + Log::error("XmlCharacteristic::process", "Can't process %s", + getName(type).c_str()); + value.fv->clear(); + break; + } + fit++; + } + } + break; + } + case TYPE_INTERPOLATION_ARRAY: + { + const std::vector processors = + StringUtils::split(m_values[type], ' '); + // If the interpolation array should be completely replaced + // That has to happen when the format is not the same + bool shouldReplace = false; + if (*is_set) + { + if (processors.size() != value.fv->size()) + shouldReplace = true; + else + { + for (const std::string &processor : processors) + { + std::vector pair = StringUtils::split(processor, ':'); + if (pair.size() != 2) + Log::error("XmlCharacteristic::process", + "Can't process %s: Wrong format", getName(type).c_str()); + else + { + float x; + if (!StringUtils::fromString(pair[0], x)) + Log::error("XmlCharacteristic::process", + "Can't process %s: Not a float", getName(type).c_str()); + else + { + // Search the index of this x value + bool found = false; + for (unsigned int i = 0; i < value.ia->size(); i++) + { + if (value.ia->getX(i) == x) + { + float val; + processFloat(pair[1], &val, is_set); + value.ia->setY(i, val); + found = true; + break; + } + } + if (!found) + { + // The searched value was not found so we have + // a different format + shouldReplace = true; + break; + } + } + } + } + } + } + else + // It's not yet set, so we will the current content + shouldReplace = true; + + if (shouldReplace) + { + value.ia->clear(); + // Replace all values + for (const std::string &processor : processors) + { + std::vector pair = StringUtils::split(processor,':'); + if (pair.size() != 2) + Log::error("XmlCharacteristic::process", + "Can't process %s: Wrong format", getName(type).c_str()); + else + { + float x; + if (!StringUtils::fromString(pair[0], x)) + Log::error("XmlCharacteristic::process", + "Can't process %s: Not a float", getName(type).c_str()); + else + { + float val; + *is_set = false; + processFloat(pair[1], &val, is_set); + if (!*is_set) + { + Log::error("XmlCharacteristic::process", "Can't process %s", + getName(type).c_str()); + value.ia->clear(); + break; + } + value.ia->push_back(x, val); + } + } + } + } + break; + } + default: + Log::fatal("XmlCharacteristic::process", "Unknown type for %s", + getName(type).c_str()); + } +} // process + +// ---------------------------------------------------------------------------- +/** Executes an operation on a float value. */ +void XmlCharacteristic::processFloat(const std::string &processor, float *value, + bool *is_set) +{ + // Split the string by operators + static const std::string operators = "*/+-"; + std::vector parts; + std::vector operations; + std::size_t pos = 0; + std::size_t pos2; + while ((pos2 = processor.find_first_of(operators, pos)) != std::string::npos) + { + parts.push_back(processor.substr(pos, pos2)); + operations.push_back(processor.substr(pos2, pos2 + 1)); + pos = pos2 + 1; + } + parts.push_back(processor.substr(pos)); + + // Compute the result + float x = *value; + std::size_t index = 0; + // If nothing preceeds the first operator, insert x + if (parts[index].empty()) + { + if (!*is_set) + { + Log::error("XmlCharacteristic::processFloat", "x is unknown"); + return; + } + // - is a special case: We don't take e.g. "-5" as relative, it + // describes a negative number + else if (operations[index] == "-") + *value = 0; + else + *value = x; + } + else + { + float val; + if (!StringUtils::fromString(parts[index], val)) + { + Log::fatal("XmlCharacteristic::processFloat", + "Can't parse %s: Not a float", parts[index].c_str()); + return; + } + *value = val; + } + index++; + for (; index < parts.size(); index++) + { + float val; + if (parts[index] == "x" || parts[index] == "X") + val = x; + else if (!StringUtils::fromString(parts[index], val)) + { + Log::fatal("XmlCharacteristic::processFloat", + "Can't parse %s: Not a float", parts[index].c_str()); + return; + } + if (operations[index - 1] == "*") + *value *= val; + else if (operations[index - 1] == "/") + *value /= val; + else if (operations[index - 1] == "+") + *value += val; + else if (operations[index - 1] == "-") + *value -= val; + else + Log::fatal("XmlCharacteristic::processFloat", + "Unknown operator (%s)", operations[index - 1].c_str()); + } + *is_set = true; +} // processFloat + +// ---------------------------------------------------------------------------- +/** Executes an operation on a bool value. */ +void XmlCharacteristic::processBool(const std::string &processor, bool *value, + bool *is_set) +{ + if (processor == "true") + { + *value = true; + *is_set = true; + } + else if (processor == "false") + { + *value = false; + *is_set = true; + } + else + Log::error("XmlCharacteristic::processBool", "Can't parse %s: Not a bool", + processor.c_str()); +} // processBool + +// ---------------------------------------------------------------------------- +/** Loads all commands from a given xml file. + * Non-existing tags will be omitted. + */ +void XmlCharacteristic::load(const XMLNode *node) +{ + // Script-generated content generated by tools/create_kart_properties.py getXml + // Please don't change the following tag. It will be automatically detected + // by the script and replace the contained content. + // To update the code, use tools/update_characteristics.py + /* */ + if (const XMLNode *sub_node = node->getNode("suspension")) + { + sub_node->get("stiffness", + &m_values[SUSPENSION_STIFFNESS]); + sub_node->get("rest", + &m_values[SUSPENSION_REST]); + sub_node->get("travel", + &m_values[SUSPENSION_TRAVEL]); + sub_node->get("exp-spring-response", + &m_values[SUSPENSION_EXP_SPRING_RESPONSE]); + sub_node->get("max-force", + &m_values[SUSPENSION_MAX_FORCE]); + } + + if (const XMLNode *sub_node = node->getNode("stability")) + { + sub_node->get("roll-influence", + &m_values[STABILITY_ROLL_INFLUENCE]); + sub_node->get("chassis-linear-damping", + &m_values[STABILITY_CHASSIS_LINEAR_DAMPING]); + sub_node->get("chassis-angular-damping", + &m_values[STABILITY_CHASSIS_ANGULAR_DAMPING]); + sub_node->get("downward-impulse-factor", + &m_values[STABILITY_DOWNWARD_IMPULSE_FACTOR]); + sub_node->get("track-connection-accel", + &m_values[STABILITY_TRACK_CONNECTION_ACCEL]); + sub_node->get("smooth-flying-impulse", + &m_values[STABILITY_SMOOTH_FLYING_IMPULSE]); + } + + if (const XMLNode *sub_node = node->getNode("turn")) + { + sub_node->get("radius", + &m_values[TURN_RADIUS]); + sub_node->get("time-reset-steer", + &m_values[TURN_TIME_RESET_STEER]); + sub_node->get("time-full-steer", + &m_values[TURN_TIME_FULL_STEER]); + } + + if (const XMLNode *sub_node = node->getNode("engine")) + { + sub_node->get("power", + &m_values[ENGINE_POWER]); + sub_node->get("max-speed", + &m_values[ENGINE_MAX_SPEED]); + sub_node->get("brake-factor", + &m_values[ENGINE_BRAKE_FACTOR]); + sub_node->get("brake-time-increase", + &m_values[ENGINE_BRAKE_TIME_INCREASE]); + sub_node->get("max-speed-reverse-ratio", + &m_values[ENGINE_MAX_SPEED_REVERSE_RATIO]); + } + + if (const XMLNode *sub_node = node->getNode("gear")) + { + sub_node->get("switch-ratio", + &m_values[GEAR_SWITCH_RATIO]); + sub_node->get("power-increase", + &m_values[GEAR_POWER_INCREASE]); + } + + if (const XMLNode *sub_node = node->getNode("mass")) + { + sub_node->get("value", + &m_values[MASS]); + } + + if (const XMLNode *sub_node = node->getNode("wheels")) + { + sub_node->get("damping-relaxation", + &m_values[WHEELS_DAMPING_RELAXATION]); + sub_node->get("damping-compression", + &m_values[WHEELS_DAMPING_COMPRESSION]); + } + + if (const XMLNode *sub_node = node->getNode("camera")) + { + sub_node->get("distance", + &m_values[CAMERA_DISTANCE]); + sub_node->get("forward-up-angle", + &m_values[CAMERA_FORWARD_UP_ANGLE]); + sub_node->get("backward-up-angle", + &m_values[CAMERA_BACKWARD_UP_ANGLE]); + } + + if (const XMLNode *sub_node = node->getNode("jump")) + { + sub_node->get("animation-time", + &m_values[JUMP_ANIMATION_TIME]); + } + + if (const XMLNode *sub_node = node->getNode("lean")) + { + sub_node->get("max", + &m_values[LEAN_MAX]); + sub_node->get("speed", + &m_values[LEAN_SPEED]); + } + + if (const XMLNode *sub_node = node->getNode("anvil")) + { + sub_node->get("duration", + &m_values[ANVIL_DURATION]); + sub_node->get("weight", + &m_values[ANVIL_WEIGHT]); + sub_node->get("speed-factor", + &m_values[ANVIL_SPEED_FACTOR]); + } + + if (const XMLNode *sub_node = node->getNode("parachute")) + { + sub_node->get("friction", + &m_values[PARACHUTE_FRICTION]); + sub_node->get("duration", + &m_values[PARACHUTE_DURATION]); + sub_node->get("duration-other", + &m_values[PARACHUTE_DURATION_OTHER]); + sub_node->get("lbound-fraction", + &m_values[PARACHUTE_LBOUND_FRACTION]); + sub_node->get("ubound-fraction", + &m_values[PARACHUTE_UBOUND_FRACTION]); + sub_node->get("max-speed", + &m_values[PARACHUTE_MAX_SPEED]); + } + + if (const XMLNode *sub_node = node->getNode("bubblegum")) + { + sub_node->get("duration", + &m_values[BUBBLEGUM_DURATION]); + sub_node->get("speed-fraction", + &m_values[BUBBLEGUM_SPEED_FRACTION]); + sub_node->get("torque", + &m_values[BUBBLEGUM_TORQUE]); + sub_node->get("fade-in-time", + &m_values[BUBBLEGUM_FADE_IN_TIME]); + sub_node->get("shield-duration", + &m_values[BUBBLEGUM_SHIELD_DURATION]); + } + + if (const XMLNode *sub_node = node->getNode("zipper")) + { + sub_node->get("duration", + &m_values[ZIPPER_DURATION]); + sub_node->get("force", + &m_values[ZIPPER_FORCE]); + sub_node->get("speed-gain", + &m_values[ZIPPER_SPEED_GAIN]); + sub_node->get("max-speed-increase", + &m_values[ZIPPER_MAX_SPEED_INCREASE]); + sub_node->get("fade-out-time", + &m_values[ZIPPER_FADE_OUT_TIME]); + } + + if (const XMLNode *sub_node = node->getNode("swatter")) + { + sub_node->get("duration", + &m_values[SWATTER_DURATION]); + sub_node->get("distance", + &m_values[SWATTER_DISTANCE]); + sub_node->get("squash-duration", + &m_values[SWATTER_SQUASH_DURATION]); + sub_node->get("squash-slowdown", + &m_values[SWATTER_SQUASH_SLOWDOWN]); + } + + if (const XMLNode *sub_node = node->getNode("plunger")) + { + sub_node->get("band-max-length", + &m_values[PLUNGER_BAND_MAX_LENGTH]); + sub_node->get("band-force", + &m_values[PLUNGER_BAND_FORCE]); + sub_node->get("band-duration", + &m_values[PLUNGER_BAND_DURATION]); + sub_node->get("band-speed-increase", + &m_values[PLUNGER_BAND_SPEED_INCREASE]); + sub_node->get("band-fade-out-time", + &m_values[PLUNGER_BAND_FADE_OUT_TIME]); + sub_node->get("in-face-time", + &m_values[PLUNGER_IN_FACE_TIME]); + } + + if (const XMLNode *sub_node = node->getNode("startup")) + { + sub_node->get("time", + &m_values[STARTUP_TIME]); + sub_node->get("boost", + &m_values[STARTUP_BOOST]); + } + + if (const XMLNode *sub_node = node->getNode("rescue")) + { + sub_node->get("duration", + &m_values[RESCUE_DURATION]); + sub_node->get("vert-offset", + &m_values[RESCUE_VERT_OFFSET]); + sub_node->get("height", + &m_values[RESCUE_HEIGHT]); + } + + if (const XMLNode *sub_node = node->getNode("explosion")) + { + sub_node->get("duration", + &m_values[EXPLOSION_DURATION]); + sub_node->get("radius", + &m_values[EXPLOSION_RADIUS]); + sub_node->get("invulnerability-time", + &m_values[EXPLOSION_INVULNERABILITY_TIME]); + } + + if (const XMLNode *sub_node = node->getNode("nitro")) + { + sub_node->get("duration", + &m_values[NITRO_DURATION]); + sub_node->get("engine-force", + &m_values[NITRO_ENGINE_FORCE]); + sub_node->get("consumption", + &m_values[NITRO_CONSUMPTION]); + sub_node->get("small-container", + &m_values[NITRO_SMALL_CONTAINER]); + sub_node->get("big-container", + &m_values[NITRO_BIG_CONTAINER]); + sub_node->get("max-speed-increase", + &m_values[NITRO_MAX_SPEED_INCREASE]); + sub_node->get("fade-out-time", + &m_values[NITRO_FADE_OUT_TIME]); + sub_node->get("max", + &m_values[NITRO_MAX]); + } + + if (const XMLNode *sub_node = node->getNode("slipstream")) + { + sub_node->get("duration", + &m_values[SLIPSTREAM_DURATION]); + sub_node->get("length", + &m_values[SLIPSTREAM_LENGTH]); + sub_node->get("width", + &m_values[SLIPSTREAM_WIDTH]); + sub_node->get("collect-time", + &m_values[SLIPSTREAM_COLLECT_TIME]); + sub_node->get("use-time", + &m_values[SLIPSTREAM_USE_TIME]); + sub_node->get("add-power", + &m_values[SLIPSTREAM_ADD_POWER]); + sub_node->get("min-speed", + &m_values[SLIPSTREAM_MIN_SPEED]); + sub_node->get("max-speed-increase", + &m_values[SLIPSTREAM_MAX_SPEED_INCREASE]); + sub_node->get("fade-out-time", + &m_values[SLIPSTREAM_FADE_OUT_TIME]); + } + + if (const XMLNode *sub_node = node->getNode("skid")) + { + sub_node->get("increase", + &m_values[SKID_INCREASE]); + sub_node->get("decrease", + &m_values[SKID_DECREASE]); + sub_node->get("max", + &m_values[SKID_MAX]); + sub_node->get("time-till-max", + &m_values[SKID_TIME_TILL_MAX]); + sub_node->get("visual", + &m_values[SKID_VISUAL]); + sub_node->get("visual-time", + &m_values[SKID_VISUAL_TIME]); + sub_node->get("revert-visual-time", + &m_values[SKID_REVERT_VISUAL_TIME]); + sub_node->get("min-speed", + &m_values[SKID_MIN_SPEED]); + sub_node->get("time-till-bonus", + &m_values[SKID_TIME_TILL_BONUS]); + sub_node->get("bonus-speed", + &m_values[SKID_BONUS_SPEED]); + sub_node->get("bonus-time", + &m_values[SKID_BONUS_TIME]); + sub_node->get("bonus-force", + &m_values[SKID_BONUS_FORCE]); + sub_node->get("physical-jump-time", + &m_values[SKID_PHYSICAL_JUMP_TIME]); + sub_node->get("graphical-jump-time", + &m_values[SKID_GRAPHICAL_JUMP_TIME]); + sub_node->get("post-skid-rotate-factor", + &m_values[SKID_POST_SKID_ROTATE_FACTOR]); + sub_node->get("reduce-turn-min", + &m_values[SKID_REDUCE_TURN_MIN]); + sub_node->get("reduce-turn-max", + &m_values[SKID_REDUCE_TURN_MAX]); + sub_node->get("enabled", + &m_values[SKID_ENABLED]); + } + + + /* */ +} // load + diff --git a/src/karts/xml_characteristic.hpp b/src/karts/xml_characteristic.hpp new file mode 100644 index 000000000..5daa58c7a --- /dev/null +++ b/src/karts/xml_characteristic.hpp @@ -0,0 +1,47 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2006-2015 SuperTuxKart-Team +// +// 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. + +#ifndef HEADER_XML_CHARACTERISTICS_HPP +#define HEADER_XML_CHARACTERISTICS_HPP + +#include "karts/abstract_characteristic.hpp" + +#include + +class XMLNode; + +class XmlCharacteristic : public AbstractCharacteristic +{ +private: + /** The computation that was read from an xml file */ + std::vector m_values; + +public: + XmlCharacteristic(const XMLNode *node = nullptr); + + virtual void process(CharacteristicType type, Value value, bool *is_set) const; + + void load(const XMLNode *node); + +private: + static void processFloat(const std::string &processor, float *value, bool *is_set); + static void processBool(const std::string &processor, bool *value, bool *is_set); +}; + +#endif + diff --git a/src/main.cpp b/src/main.cpp index f5d30af2f..59d3e88c9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1159,6 +1159,11 @@ void initRest() track_manager->addTrackSearchDir( file_manager->getAddonsFile("tracks/")); + { + XMLNode characteristicsNode(file_manager->getAsset("kart_characteristics.xml")); + kart_properties_manager->loadCharacteristics(&characteristicsNode); + } + track_manager->loadTrackList(); music_manager->addMusicToTracks(); diff --git a/src/modes/profile_world.cpp b/src/modes/profile_world.cpp index 7015a7b13..d39250dd5 100644 --- a/src/modes/profile_world.cpp +++ b/src/modes/profile_world.cpp @@ -106,7 +106,7 @@ void ProfileWorld::setProfileModeLaps(int laps) AbstractKart *ProfileWorld::createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, RaceManager::KartType type, - const PlayerDifficulty *difficulty) + PerPlayerDifficulty difficulty) { btTransform init_pos = getStartTransform(index); diff --git a/src/modes/profile_world.hpp b/src/modes/profile_world.hpp index 6a0977ebc..014ab392c 100644 --- a/src/modes/profile_world.hpp +++ b/src/modes/profile_world.hpp @@ -75,7 +75,7 @@ protected: virtual AbstractKart *createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, RaceManager::KartType type, - const PlayerDifficulty *difficulty); + PerPlayerDifficulty difficulty); public: ProfileWorld(); diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 2b18d14f6..4792491a1 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -385,7 +385,7 @@ int SoccerWorld::getTeamLeader(unsigned int team) AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, RaceManager::KartType kart_type, - const PlayerDifficulty *difficulty) + PerPlayerDifficulty difficulty) { int posIndex = index; int position = index+1; diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index 8d896d47c..5a47f992f 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -106,7 +106,7 @@ protected: virtual AbstractKart *createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, RaceManager::KartType type, - const PlayerDifficulty *difficulty); + PerPlayerDifficulty difficulty); }; // SoccerWorld diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 4b1acbaa3..d8e7f9386 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -185,12 +185,10 @@ void World::init() : race_manager->getKartIdent(i); int local_player_id = race_manager->getKartLocalPlayerId(i); int global_player_id = race_manager->getKartGlobalPlayerId(i); - const PlayerDifficulty *player_difficulty = - stk_config->getPlayerDifficulty(race_manager->getPlayerDifficulty(i)); AbstractKart* newkart = createKart(kart_ident, i, local_player_id, global_player_id, race_manager->getKartType(i), - player_difficulty); + race_manager->getPlayerDifficulty(i)); m_karts.push_back(newkart); m_track->adjustForFog(newkart->getNode()); @@ -301,7 +299,7 @@ void World::createRaceGUI() AbstractKart *World::createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, RaceManager::KartType kart_type, - const PlayerDifficulty *difficulty) + PerPlayerDifficulty difficulty) { int position = index+1; btTransform init_pos = getStartTransform(index); diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 69e5bf538..1d7ed1ce6 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -126,7 +126,7 @@ protected: virtual AbstractKart *createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, RaceManager::KartType type, - const PlayerDifficulty *difficulty); + PerPlayerDifficulty difficulty); /** Pointer to the track. The track is managed by world. */ Track* m_track; diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index ed2b39baf..63037b618 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -461,7 +461,7 @@ void btKart::updateVehicle( btScalar step ) av.setZ(0); m_chassisBody->setAngularVelocity(av); // Give a nicely balanced feeling for rebalancing the kart - m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getSmoothFlyingImpulse()); + m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getStabilitySmoothFlyingImpulse()); } // Work around: make sure that either both wheels on one axis @@ -543,7 +543,7 @@ void btKart::updateVehicle( btScalar step ) // If configured, add a force to keep karts on the track // ----------------------------------------------------- - float dif = m_kart->getKartProperties()->getDownwardImpulseFactor(); + float dif = m_kart->getKartProperties()->getStabilityDownwardImpulseFactor(); if(dif!=0 && m_num_wheels_on_ground==4) { float f = -fabsf(m_kart->getSpeed()) * dif; @@ -655,7 +655,7 @@ void btKart::updateSuspension(btScalar deltaTime) // is already guaranteed that either both or no wheels on one axis // are on the ground, so we have to test only one of the wheels wheel_info.m_wheelsSuspensionForce = - -m_kart->getKartProperties()->getTrackConnectionAccel() + -m_kart->getKartProperties()->getStabilityTrackConnectionAccel() * chassisMass; continue; } @@ -666,7 +666,7 @@ void btKart::updateSuspension(btScalar deltaTime) btScalar susp_length = wheel_info.getSuspensionRestLength(); btScalar current_length = wheel_info.m_raycastInfo.m_suspensionLength; btScalar length_diff = (susp_length - current_length); - if(m_kart->getKartProperties()->getExpSpringResponse()) + if(m_kart->getKartProperties()->getSuspensionExpSpringResponse()) length_diff *= fabsf(length_diff)/susp_length; float f = (1.0f + fabsf(length_diff) / susp_length); // Scale the length diff. This results that in uphill sections, when diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 864010442..48b29b3db 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -218,9 +218,9 @@ void Physics::update(float dt) } else if (obj->isFlattenKartObject()) { - const KartProperties* kp = kart->getKartProperties(); - kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(), - kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown()); + const KartProperties *kp = kart->getKartProperties(); + kart->setSquash(kp->getSwatterSquashDuration(), + kp->getSwatterSquashSlowdown()); } else if(obj->isSoccerBall() && race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) @@ -248,9 +248,9 @@ void Physics::update(float dt) else if (anim->isFlattenKartObject()) { AbstractKart *kart = p->getUserPointer(1)->getPointerKart(); - const KartProperties* kp = kart->getKartProperties(); - kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(), - kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown()); + const KartProperties *kp = kart->getKartProperties(); + kart->setSquash(kp->getSwatterSquashDuration(), + kp->getSwatterSquashSlowdown()); } continue; diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index e1588d7ec..7abaac61e 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -46,6 +46,7 @@ #include "network/protocol_manager.hpp" #include "network/network_world.hpp" #include "network/protocols/start_game_protocol.hpp" +#include "scriptengine/property_animator.hpp" #include "states_screens/grand_prix_cutscene.hpp" #include "states_screens/grand_prix_lose.hpp" #include "states_screens/grand_prix_win.hpp" @@ -520,6 +521,7 @@ void RaceManager::startNextRace() //----------------------------------------------------------------------------- void RaceManager::next() { + PropertyAnimator::get()->clear(); World::deleteWorld(); m_num_finished_karts = 0; m_num_finished_players = 0; @@ -720,7 +722,11 @@ void RaceManager::exitRace(bool delete_world) } } - if (delete_world) World::deleteWorld(); + if (delete_world) + { + PropertyAnimator::get()->clear(); + World::deleteWorld(); + } delete_world = false; StateManager::get()->enterGameState(); @@ -757,7 +763,11 @@ void RaceManager::exitRace(bool delete_world) } } - if (delete_world) World::deleteWorld(); + if (delete_world) + { + PropertyAnimator::get()->clear(); + World::deleteWorld(); + } m_saved_gp = NULL; m_track_number = 0; diff --git a/src/scriptengine/property_animator.cpp b/src/scriptengine/property_animator.cpp new file mode 100644 index 000000000..270bf6428 --- /dev/null +++ b/src/scriptengine/property_animator.cpp @@ -0,0 +1,132 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2014-2015 SuperTuxKart Team +// +// 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. + +#include "scriptengine/property_animator.hpp" +#include "tracks/track.hpp" +#include "tracks/track_object_presentation.hpp" +#include "utils/log.hpp" + +AnimatedProperty::AnimatedProperty(AnimatablePropery property, + int values_count, double* values_from, double* values_to, + double duration, void* data) +{ + m_property = property; + m_remaining_time = m_total_time = duration; + m_data = data; + m_values_count = values_count; + m_values_from = values_from; + m_values_to = values_to; + m_new_values = new double[values_count]; +} + +// ---------------------------------------------------------------------------- + +bool AnimatedProperty::update(double dt) +{ + bool done = false; + m_remaining_time -= dt; + if (m_remaining_time < 0) + { + m_remaining_time = 0; + done = true; + } + + double ratio = 1.0 - m_remaining_time / m_total_time; + + for (int i = 0; i < m_values_count; i++) + { + m_new_values[i] = m_values_from[i] + (m_values_to[i] - m_values_from[i]) * ratio; + } + + switch (m_property) + { + case AnimatablePropery::AP_LIGHT_ENERGY: + { + TrackObjectPresentationLight* light = (TrackObjectPresentationLight*)m_data; + light->setEnergy((float)m_new_values[0]); + break; + } + + case AnimatablePropery::FOG_RANGE: + { + Track* track = (Track*)m_data; + track->setFogStart((float)m_new_values[0]); + track->setFogEnd((float)m_new_values[1]); + break; + } + + case AnimatablePropery::FOG_MAX: + { + Track* track = (Track*)m_data; + track->setFogMax((float)m_new_values[0]); + break; + } + + case AnimatablePropery::FOG_COLOR: + { + Track* track = (Track*)m_data; + video::SColor color(255, (int)m_new_values[0], (int)m_new_values[1], (int)m_new_values[2]); + track->setFogColor(color); + break; + } + + default: + Log::error("PropertyAnimator", "Unknown properry %i", (int)m_property); + break; + } + + return done; +} + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +PropertyAnimator* PropertyAnimator::s_instance = NULL; + +PropertyAnimator* PropertyAnimator::get() +{ + if (s_instance == NULL) + s_instance = new PropertyAnimator(); + + return s_instance; +} + +// ---------------------------------------------------------------------------- + +void PropertyAnimator::add(AnimatedProperty* prop) +{ + m_properties.push_back(prop); +} + +// ---------------------------------------------------------------------------- + +void PropertyAnimator::update(double dt) +{ + for (int i = m_properties.size() - 1; i >= 0; i--) + { + bool done = m_properties[i].update(dt); + if (done) + m_properties.erase(i); + } +} + +// ---------------------------------------------------------------------------- + +void PropertyAnimator::clear() +{ + m_properties.clearAndDeleteAll(); +} diff --git a/src/scriptengine/property_animator.hpp b/src/scriptengine/property_animator.hpp new file mode 100644 index 000000000..f9623ae6a --- /dev/null +++ b/src/scriptengine/property_animator.hpp @@ -0,0 +1,73 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2014-2015 SuperTuxKart Team +// +// 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. + +#ifndef HEADER_PROPERTY_ANIMATOR_HPP +#define HEADER_PROPERTY_ANIMATOR_HPP + +#include "utils/no_copy.hpp" +#include "utils/ptr_vector.hpp" + +enum AnimatablePropery +{ + AP_LIGHT_ENERGY, + FOG_RANGE, + FOG_MAX, + FOG_COLOR +}; + +class AnimatedProperty : NoCopy +{ + AnimatablePropery m_property; + int m_values_count; + double* m_values_from; + double* m_values_to; + double* m_new_values; + double m_total_time; + double m_remaining_time; + void* m_data; + +public: + AnimatedProperty(AnimatablePropery property, int values_count, + double* values_from, double* values_to, + double duration, void* data); + + ~AnimatedProperty() + { + delete[] m_values_from; + delete[] m_values_to; + delete[] m_new_values; + } + + bool update(double dt); +}; + + +class PropertyAnimator +{ + PtrVector m_properties; + static PropertyAnimator* s_instance; +public: + + static PropertyAnimator* get(); + + void add(AnimatedProperty* prop); + void update(double dt); + void clear(); +}; + + +#endif diff --git a/src/scriptengine/script_kart.cpp b/src/scriptengine/script_kart.cpp index 0022deeae..51b2beecb 100644 --- a/src/scriptengine/script_kart.cpp +++ b/src/scriptengine/script_kart.cpp @@ -16,13 +16,14 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#include -#include +#include "script_kart.hpp" + #include "karts/kart.hpp" #include "modes/world.hpp" -#include "script_kart.hpp" #include "scriptvec3.hpp" +#include +#include //debug #include @@ -121,8 +122,7 @@ namespace Scripting float getMaxSpeed(int idKart) { AbstractKart* kart = World::getWorld()->getKart(idKart); - return kart->getKartProperties()->getMaxSpeed() * - kart->getPlayerDifficulty()->getMaxSpeed(); + return kart->getKartProperties()->getEngineMaxSpeed(); } /** @}*/ diff --git a/src/scriptengine/script_track.cpp b/src/scriptengine/script_track.cpp index f87ce8f0b..3b91e30c2 100644 --- a/src/scriptengine/script_track.cpp +++ b/src/scriptengine/script_track.cpp @@ -26,6 +26,7 @@ #include "input/input_device.hpp" #include "input/input_manager.hpp" #include "modes/world.hpp" +#include "scriptengine/property_animator.hpp" #include "states_screens/dialogs/tutorial_message_dialog.hpp" #include "states_screens/dialogs/race_paused_dialog.hpp" #include "tracks/track.hpp" @@ -133,6 +134,38 @@ namespace Scripting { new RacePausedDialog(0.8f, 0.6f); } + + void setFog(float maxDensity, float start, float end, int r, int g, int b, float duration) + { + PropertyAnimator* animator = PropertyAnimator::get(); + ::Track* track = World::getWorld()->getTrack(); + animator->add( + new AnimatedProperty(FOG_MAX, 1, + new double[1] { track->getFogMax() }, + new double[1] { maxDensity }, duration, track) + ); + animator->add( + new AnimatedProperty(FOG_RANGE, 2, + new double[2] { track->getFogStart(), track->getFogEnd() }, + new double[2] { start, end }, duration, track) + ); + + video::SColor color = track->getFogColor(); + animator->add( + new AnimatedProperty(FOG_COLOR, 3, + new double[3] { + (double)color.getRed(), + (double)color.getGreen(), + (double)color.getBlue() + }, + new double[3] { + (double)r, + (double)g, + (double)b + }, + duration, track) + ); + } } /** \cond DOXYGEN_IGNORE */ @@ -230,7 +263,12 @@ namespace Scripting void animateEnergy(float energy, float duration, /** \cond DOXYGEN_IGNORE */void *memory /** \endcond */) { - ((TrackObjectPresentationLight*)memory)->setEnergy(energy, duration); + TrackObjectPresentationLight* light = ((TrackObjectPresentationLight*)memory); + PropertyAnimator::get()->add( + new AnimatedProperty(AP_LIGHT_ENERGY, 1, + new double[1] { light->getEnergy() }, + new double[1] { energy }, duration, light) + ); } /** @} */ @@ -326,6 +364,7 @@ namespace Scripting r = engine->RegisterGlobalFunction("TrackObject@ getTrackObject(const string &in, const string &in)", asFUNCTION(getTrackObject), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void exitRace()", asFUNCTION(exitRace), asCALL_CDECL); assert(r >= 0); r = engine->RegisterGlobalFunction("void pauseRace()", asFUNCTION(pauseRace), asCALL_CDECL); assert(r >= 0); + r = engine->RegisterGlobalFunction("void setFog(float maxDensity, float start, float end, int r, int g, int b, float duration)", asFUNCTION(setFog), asCALL_CDECL); assert(r >= 0); // TrackObject r = engine->RegisterObjectMethod("TrackObject", "void setEnabled(bool status)", asMETHOD(::TrackObject, setEnabled), asCALL_THISCALL); assert(r >= 0); diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 42076802d..248721440 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -31,6 +31,7 @@ #include "input/input_manager.hpp" #include "input/device_manager.hpp" #include "items/item_manager.hpp" +#include "karts/abstract_characteristic.hpp" #include "karts/kart_properties.hpp" #include "karts/kart_properties_manager.hpp" #include "modes/overworld.hpp" @@ -810,9 +811,13 @@ void KartSelectionScreen::updateKartStats(uint8_t widget_id, kart_properties_manager->getKart(selection); if (kp != NULL) { - w->setValue(KartStatsWidget::SKILL_MASS, (int)(kp->getMass()/5)); - w->setValue(KartStatsWidget::SKILL_SPEED, (int)((kp->getAbsMaxSpeed()-20)*9)); - w->setValue(KartStatsWidget::SKILL_POWER, (int)(kp->getAvgPower())); + // Scale the values so they look better + w->setValue(KartStatsWidget::SKILL_MASS, (int) + ((kp->getCombinedCharacteristic()->getMass() - 20) / 4)); + w->setValue(KartStatsWidget::SKILL_SPEED, (int) + ((kp->getCombinedCharacteristic()->getEngineMaxSpeed() - 15) * 6)); + w->setValue(KartStatsWidget::SKILL_POWER, (int) + ((kp->getAvgPower() - 30) / 20)); w->update(0); } } diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index e68bf2098..78d6e2be4 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -43,6 +43,7 @@ #include "modes/soccer_world.hpp" #include "modes/world_with_rank.hpp" #include "race/highscores.hpp" +#include "scriptengine/property_animator.hpp" #include "states_screens/feature_unlocked.hpp" #include "states_screens/main_menu_screen.hpp" #include "states_screens/networking_lobby.hpp" @@ -270,6 +271,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, // kart will no longer be available during cutscene, drop reference StateManager::get()->getActivePlayer(playerID)->setKart(NULL); + PropertyAnimator::get()->clear(); World::deleteWorld(); CutsceneWorld::setUseDuration(true); @@ -287,6 +289,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, else { StateManager::get()->popMenu(); + PropertyAnimator::get()->clear(); World::deleteWorld(); CutsceneWorld::setUseDuration(false); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 20e1990e1..c9b42b84f 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1358,6 +1358,7 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml) // to lower case, for case-insensitive comparison name = StringUtils::toLowerCase(name); + int moving_textures_found = 0; for(unsigned int i=0; igetMaterialCount(); i++) { video::SMaterial &irrMaterial=node->getMaterial(i); @@ -1374,8 +1375,12 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml) if (texture_name != name) continue; core::matrix4 *m = &irrMaterial.getTextureMatrix(j); m_animated_textures.push_back(new MovingTexture(m, *texture_node)); + moving_textures_found++; } // for jgetNumNodes } // handleAnimatedTextures @@ -2377,4 +2382,3 @@ bool Track::findGround(AbstractKart *kart) return true; } // findGround - diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 7415e89bd..cc98d3ea8 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -556,16 +556,24 @@ public: // ------------------------------------------------------------------------ float getFogStart() const { return m_fog_start; } // ------------------------------------------------------------------------ + void setFogStart(float start) { m_fog_start = start; } + // ------------------------------------------------------------------------ float getFogEnd() const { return m_fog_end; } // ------------------------------------------------------------------------ + void setFogEnd(float end) { m_fog_end = end; } + // ------------------------------------------------------------------------ float getFogStartHeight() const { return m_fog_height_start; } // ------------------------------------------------------------------------ float getFogEndHeight() const { return m_fog_height_end; } // ------------------------------------------------------------------------ float getFogMax() const { return m_fog_max; } // ------------------------------------------------------------------------ + void setFogMax(float max) { m_fog_max = max; } + // ------------------------------------------------------------------------ video::SColor getFogColor() const { return m_fog_color; } // ------------------------------------------------------------------------ + void setFogColor(video::SColor& color) { m_fog_color = color; } + // ------------------------------------------------------------------------ video::SColor getSunColor() const { return m_sun_diffuse_color; } // ------------------------------------------------------------------------ /** Whether this is an "internal" track. If so it won't be offered diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 6161f4e47..409deaff9 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -967,11 +967,6 @@ TrackObjectPresentationLight::TrackObjectPresentationLight( { m_node = NULL; // lights require shaders to work } - - m_energy_animation_from = 0.0f; - m_energy_animation_to = 0.0f; - m_energy_animation_total_duration = 0.0f; - m_energy_animation_remaining_duration = 0.0f; } // TrackObjectPresentationLight // ---------------------------------------------------------------------------- @@ -989,29 +984,6 @@ void TrackObjectPresentationLight::setEnergy(float energy) } } // ---------------------------------------------------------------------------- -void TrackObjectPresentationLight::setEnergy(float energy, float duration) -{ - m_energy_animation_from = m_energy; - m_energy_animation_to = energy; - m_energy_animation_total_duration = duration; - m_energy_animation_remaining_duration = duration; -} -// ---------------------------------------------------------------------------- -void TrackObjectPresentationLight::update(float dt) -{ - if (m_energy_animation_remaining_duration > 0.0f) - { - m_energy_animation_remaining_duration -= dt; - if (m_energy_animation_remaining_duration < 0.0f) - m_energy_animation_remaining_duration = 0.0f; - - float ratio = m_energy_animation_remaining_duration / m_energy_animation_total_duration; - - setEnergy(m_energy_animation_from + - (m_energy_animation_to - m_energy_animation_from)*(1.0f - ratio)); - } -} -// ---------------------------------------------------------------------------- TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( const XMLNode& xml_node) : TrackObjectPresentation(xml_node) diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index ca4ba2b0b..1262bb65c 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -354,19 +354,12 @@ private: video::SColor m_color; float m_distance; float m_energy; - - float m_energy_animation_from; - float m_energy_animation_to; - float m_energy_animation_total_duration; - float m_energy_animation_remaining_duration; - public: TrackObjectPresentationLight(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationLight(); + float getEnergy() const { return m_energy; } void setEnergy(float energy); - void setEnergy(float energy, float duration); - virtual void update(float dt) OVERRIDE; }; // TrackObjectPresentationLight // ============================================================================ diff --git a/src/utils/debug.cpp b/src/utils/debug.cpp index c6d2b88c1..6fc029cca 100644 --- a/src/utils/debug.cpp +++ b/src/utils/debug.cpp @@ -26,6 +26,7 @@ #include "items/powerup_manager.hpp" #include "items/attachment.hpp" #include "karts/abstract_kart.hpp" +#include "karts/kart_properties.hpp" #include "karts/controller/controller.hpp" #include "modes/world.hpp" #include "physics/irr_debug_drawer.hpp" @@ -140,14 +141,14 @@ void addAttachment(Attachment::AttachmentType type) if (type == Attachment::ATTACH_ANVIL) { kart->getAttachment() - ->set(type, stk_config->m_anvil_time); - kart->adjustSpeed(stk_config->m_anvil_speed_factor); + ->set(type, kart->getKartProperties()->getAnvilDuration()); + kart->adjustSpeed(kart->getKartProperties()->getAnvilSpeedFactor()); kart->updateWeight(); } else if (type == Attachment::ATTACH_PARACHUTE) { kart->getAttachment() - ->set(type, stk_config->m_parachute_time); + ->set(type, kart->getKartProperties()->getParachuteDuration()); } else if (type == Attachment::ATTACH_BOMB) { diff --git a/src/utils/interpolation_array.hpp b/src/utils/interpolation_array.hpp index e4f0b7893..c66286eae 100644 --- a/src/utils/interpolation_array.hpp +++ b/src/utils/interpolation_array.hpp @@ -43,6 +43,14 @@ private: public: InterpolationArray() {}; + /** Removes all saved values from this object. */ + void clear() + { + m_x.clear(); + m_y.clear(); + m_delta.clear(); + } + /** Adds the value pair x/y to the list of all points. It is tested * that the x values are added in order. * \param x, y The pair to add. diff --git a/tools/create_kart_properties.py b/tools/create_kart_properties.py new file mode 100755 index 000000000..4b00ba3b1 --- /dev/null +++ b/tools/create_kart_properties.py @@ -0,0 +1,285 @@ +#!/usr/bin/env python3 +# +# SuperTuxKart - a fun racing game with go-kart +# Copyright (C) 2006-2015 SuperTuxKart-Team +# +# 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. + +# This script creates code for the characteristics. +# It takes an argument that specifies what the output of the script should be. +# The output options can be seen by running this script without arguments. +# A more convenient version to update the code is to run update_characteristics.py + +import sys + +# Input data +# Each line contains a topic and the attributes of that topic. +# This model is used for the xml file and to access the kart properties in the code. +characteristics = """Suspension: stiffness, rest, travel, expSpringResponse(bool), maxForce +Stability: rollInfluence, chassisLinearDamping, chassisAngularDamping, downwardImpulseFactor, trackConnectionAccel, smoothFlyingImpulse +Turn: radius(InterpolationArray), timeResetSteer, timeFullSteer(InterpolationArray) +Engine: power, maxSpeed, brakeFactor, brakeTimeIncrease, maxSpeedReverseRatio +Gear: switchRatio(std::vector/floatVector), powerIncrease(std::vector/floatVector) +Mass +Wheels: dampingRelaxation, dampingCompression +Camera: distance, forwardUpAngle, backwardUpAngle +Jump: animationTime +Lean: max, speed +Anvil: duration, weight, speedFactor +Parachute: friction, duration, durationOther, lboundFraction, uboundFraction, maxSpeed +Bubblegum: duration, speedFraction, torque, fadeInTime, shieldDuration +Zipper: duration, force, speedGain, maxSpeedIncrease, fadeOutTime +Swatter: duration, distance, squashDuration, squashSlowdown +Plunger: bandMaxLength, bandForce, bandDuration, bandSpeedIncrease, bandFadeOutTime, inFaceTime +Startup: time(std::vector/floatVector), boost(std::vector/floatVector) +Rescue: duration, vertOffset, height +Explosion: duration, radius, invulnerabilityTime +Nitro: duration, engineForce, consumption, smallContainer, bigContainer, maxSpeedIncrease, fadeOutTime, max +Slipstream: duration, length, width, collectTime, useTime, addPower, minSpeed, maxSpeedIncrease, fadeOutTime +Skid: increase, decrease, max, timeTillMax, visual, visualTime, revertVisualTime, minSpeed, timeTillBonus(std::vector/floatVector), bonusSpeed(std::vector/floatVector), bonusTime(std::vector/floatVector), bonusForce(std::vector/floatVector), physicalJumpTime, graphicalJumpTime, postSkidRotateFactor, reduceTurnMin, reduceTurnMax, enabled(bool)""" + +""" A GroupMember is an attribute of a group. + In the xml files, a value will be assigned to it. + If the name of the attribute is 'value', the getter method will only + contain the group name and 'value' will be omitted (e.g. used for mass). """ +class GroupMember: + def __init__(self, name, typeC, typeStr): + self.name = name + if name == "value": + self.getName = "" + else: + self.getName = name + self.typeC = typeC + self.typeStr = typeStr + + """ E.g. power(std::vector/floatVector) + or speed(InterpolationArray) + The default type is float + The name 'value' is special: Only the group name will be used to access + the member but in the xml file it will be still value (because we + need a name). """ + def parse(content): + typeC = "float" + typeStr = typeC + name = content.strip() + pos = content.find("(") + end = content.find(")", pos) + if pos != -1 and end != -1: + name = content[:pos].strip() + pos2 = content.find("/", pos, end) + if pos2 != -1: + typeC = content[pos + 1:pos2].strip() + typeStr = content[pos2 + 1:end].strip() + else: + typeC = content[pos + 1:end].strip() + typeStr = typeC + + return GroupMember(name, typeC, typeStr) + +""" A Group has a base name and can contain GroupMembers. + In the xml files, a group is a tag. """ +class Group: + def __init__(self, baseName): + self.baseName = baseName + self.members = [] + + """ Parses and adds a member to this group """ + def addMember(self, content): + self.members.append(GroupMember.parse(content)) + + def getBaseName(self): + return self.baseName + + """ E.g. engine: power, gears(std::vector/Gears) + or mass(float) or only mass """ + def parse(content): + pos = content.find(":") + if pos == -1: + group = Group(content) + group.addMember("value") + return group + else: + group = Group(content[:pos].strip()) + for m in content[pos + 1:].split(","): + group.addMember(m) + return group + +""" Creates a list of words from a titlecase string """ +def toList(name): + result = [] + cur = "" + for c in name: + if c.isupper() and len(cur) != 0: + result.append(cur) + cur = "" + cur += c.lower() + if len(cur) != 0: + result.append(cur) + return result + +""" titleCase: true = result is titlecase + false = result has underscores """ +def joinSubName(group, member, titleCase): + words = toList(group.baseName) + toList(member.getName) + first = True + if titleCase: + words = [w.title() for w in words] + return "".join(words) + else: + return "_".join(words) + +# Functions to generate code + +def createEnum(groups): + for g in groups: + print() + print(" // {0}".format(g.getBaseName().title())) + for m in g.members: + print(" {0},".format(joinSubName(g, m, False).upper())) + +def createAcDefs(groups): + for g in groups: + print() + for m in g.members: + nameTitle = joinSubName(g, m, True) + nameUnderscore = joinSubName(g, m, False) + typeC = m.typeC + + print(" {0} get{1}() const;". + format(typeC, nameTitle, nameUnderscore)) + +def createAcGetter(groups): + for g in groups: + for m in g.members: + nameTitle = joinSubName(g, m, True) + nameUnderscore = joinSubName(g, m, False) + typeC = m.typeC + result = "result" + + print("""// ---------------------------------------------------------------------------- +{3} AbstractCharacteristic::get{1}() const +{{ + {0} result; + bool is_set = false; + process({2}, &result, &is_set); + if (!is_set) + Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", + getName({2}).c_str()); + return {4}; +}} // get{1} +""".format(m.typeC, nameTitle, nameUnderscore.upper(), typeC, result)) + +def createKpDefs(groups): + for g in groups: + print() + for m in g.members: + nameTitle = joinSubName(g, m, True) + nameUnderscore = joinSubName(g, m, False) + typeC = m.typeC + + print(" {0} get{1}() const;". + format(typeC, nameTitle, nameUnderscore)) + +def createKpGetter(groups): + for g in groups: + for m in g.members: + nameTitle = joinSubName(g, m, True) + nameUnderscore = joinSubName(g, m, False) + typeC = m.typeC + result = "result" + + print("""// ---------------------------------------------------------------------------- +{1} KartProperties::get{0}() const +{{ + return m_cached_characteristic->get{0}(); +}} // get{0} +""".format(nameTitle, typeC)) + +def createGetType(groups): + for g in groups: + for m in g.members: + nameTitle = joinSubName(g, m, True) + nameUnderscore = joinSubName(g, m, False) + print(" case {0}:\n return TYPE_{1};". + format(nameUnderscore.upper(), "_".join(toList(m.typeStr)).upper())) + +def createGetName(groups): + for g in groups: + for m in g.members: + nameTitle = joinSubName(g, m, True) + nameUnderscore = joinSubName(g, m, False).upper() + print(" case {0}:\n return \"{0}\";". + format(nameUnderscore)) + +def createLoadXml(groups): + for g in groups: + print(" if (const XMLNode *sub_node = node->getNode(\"{0}\"))\n {{". + format(g.baseName.lower())) + for m in g.members: + nameUnderscore = joinSubName(g, m, False) + nameMinus = "-".join(toList(m.name)) + print(""" sub_node->get(\"{0}\", + &m_values[{1}]);""". + format(nameMinus, nameUnderscore.upper())) + print(" }\n") + +# Dicionary that maps an argument string to a tupel of +# a generator function, a help string and a filename +functions = { + "enum": (createEnum, "List the enum values for all characteristics", "karts/abstract_characteristic.hpp"), + "acdefs": (createAcDefs, "Create the header function definitions", "karts/abstract_characteristic.hpp"), + "acgetter": (createAcGetter, "Implement the getters", "karts/abstract_characteristic.cpp"), + "getType": (createGetType, "Implement the getType function", "karts/abstract_characteristic.cpp"), + "getName": (createGetName, "Implement the getName function", "karts/abstract_characteristic.cpp"), + "kpdefs": (createKpDefs, "Create the header function definitions for the getters", "karts/kart_properties.hpp"), + "kpgetter": (createKpGetter, "Implement the getters", "karts/kart_properties.cpp"), + "loadXml": (createLoadXml, "Code to load the characteristics from an xml file", "karts/xml_characteristic.hpp"), +} + +def main(): + # Find out what to do + if len(sys.argv) != 2: + print("""Usage: ./create_kart_properties.py +Operations:""") + maxOperationLength = 0 + maxDescriptionLength = 0 + for o, f in functions.items(): + l = len(o) + if l > maxOperationLength: + maxOperationLength = l + l = len(f[1]) + if l > maxDescriptionLength: + maxDescriptionLength = l + + formatString = " {{0:{0}}} {{1:{1}}} in {{2}}".format(maxOperationLength, maxDescriptionLength) + for o, f in functions.items(): + print(formatString.format(o, f[1], f[2])) + return + + task = sys.argv[1] + + if task not in functions: + print("The wanted operation was not found. Please call this script without arguments to list available arguments.") + return + + # Parse properties + groups = [Group.parse(line) for line in characteristics.split("\n")] + + # Create the wanted code + functions[task][0](groups) + +if __name__ == '__main__': + main() + diff --git a/tools/update_characteristics.py b/tools/update_characteristics.py new file mode 100755 index 000000000..5c09adafe --- /dev/null +++ b/tools/update_characteristics.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# +# SuperTuxKart - a fun racing game with go-kart +# Copyright (C) 2006-2015 SuperTuxKart-Team +# +# 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. + +# This script uses create_kart_properties.py to create code and then replaces +# the code in the source files. The parts in the source are marked with tags, that +# contain the argument that has to be passed to create_kart_properties.py. +# The script has to be run from the root directory of this project. + +import os +import re +import subprocess + +from create_kart_properties import functions + +def main(): + # Check, if it runs in the root directory + if not os.path.isfile("tools/update_characteristics.py"): + print("Please run this script in the root directory of the project.") + exit(1) + for operation, function in functions.items(): + result = subprocess.Popen("tools/create_kart_properties.py " + + operation, shell = True, + stdout = subprocess.PIPE).stdout.read().decode('UTF-8') + with open("src/" + function[2], "r") as f: + text = f.read() + # Replace the text by using look behinds and look forwards + text = re.sub("(?<=/\* \ \*/\\n)(.|\n)*(?=\\n\s*/\* \*/)", result, text) + with open("src/" + function[2], "w") as f: + f.write(text) + +if __name__ == '__main__': + main() +