Move startup boost and penalty handling to set phase for local games

This commit is contained in:
Benau 2018-09-14 22:03:02 +08:00
parent 83a456e835
commit 641998be69
11 changed files with 68 additions and 50 deletions

View File

@ -75,7 +75,7 @@
time-per-kart="0" /> time-per-kart="0" />
<!-- Startup information. <!-- Startup information.
Penalty: Penalty time if a kart accelerates before GO. --> Penalty: Penalty time if a kart accelerates before SET. -->
<startup penalty="1" /> <startup penalty="1" />
<!-- How often a news message is going to be displayed before <!-- How often a news message is going to be displayed before

View File

@ -511,7 +511,12 @@ public:
virtual bool isVisible() = 0; virtual bool isVisible() = 0;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void makeKartRest(); virtual void makeKartRest();
// ------------------------------------------------------------------------
virtual void setStartupBoost(float val) = 0;
// ------------------------------------------------------------------------
virtual float getStartupBoost() const = 0;
// ------------------------------------------------------------------------
virtual float getStartupBoostFromStartTicks(int ticks) const = 0;
}; // AbstractKart }; // AbstractKart

View File

@ -38,7 +38,9 @@
#include "karts/rescue_animation.hpp" #include "karts/rescue_animation.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/protocols/game_protocol.hpp" #include "network/protocols/game_protocol.hpp"
#include "network/race_event_manager.hpp"
#include "network/rewind_manager.hpp" #include "network/rewind_manager.hpp"
#include "race/history.hpp" #include "race/history.hpp"
#include "states_screens/race_gui_base.hpp" #include "states_screens/race_gui_base.hpp"
@ -59,6 +61,7 @@ LocalPlayerController::LocalPlayerController(AbstractKart *kart,
PerPlayerDifficulty d) PerPlayerDifficulty d)
: PlayerController(kart), m_sky_particles_emitter(NULL) : PlayerController(kart), m_sky_particles_emitter(NULL)
{ {
m_has_started = false;
m_difficulty = d; m_difficulty = d;
m_player = StateManager::get()->getActivePlayer(local_player_id); m_player = StateManager::get()->getActivePlayer(local_player_id);
if(m_player) if(m_player)
@ -117,6 +120,7 @@ void LocalPlayerController::reset()
{ {
PlayerController::reset(); PlayerController::reset();
m_sound_schedule = false; m_sound_schedule = false;
m_has_started = false;
} // reset } // reset
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -157,6 +161,17 @@ bool LocalPlayerController::action(PlayerAction action, int value,
return true; return true;
} }
if (action == PA_ACCEL && value != 0 && !m_has_started)
{
m_has_started = true;
if (!NetworkConfig::get()->isNetworking())
{
float f = m_kart->getStartupBoostFromStartTicks(
World::getWorld()->getAuxiliaryTicks());
m_kart->setStartupBoost(f);
}
}
// If this event does not change the control state (e.g. // If this event does not change the control state (e.g.
// it's a (auto) repeat event), do nothing. This especially // it's a (auto) repeat event), do nothing. This especially
// optimises traffic to the server and other clients. // optimises traffic to the server and other clients.
@ -167,7 +182,7 @@ bool LocalPlayerController::action(PlayerAction action, int value,
history->addEvent(m_kart->getWorldKartId(), action, value); history->addEvent(m_kart->getWorldKartId(), action, value);
// If this is a client, send the action to networking layer // If this is a client, send the action to networking layer
if (World::getWorld()->isNetworkWorld() && if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient() && NetworkConfig::get()->isClient() &&
!RewindManager::get()->isRewinding()) !RewindManager::get()->isRewinding())
{ {

View File

@ -41,6 +41,8 @@ private:
StateManager::ActivePlayer *m_player; StateManager::ActivePlayer *m_player;
bool m_sound_schedule; bool m_sound_schedule;
bool m_has_started;
bool m_is_above_nitro_target;
ParticleEmitter* m_sky_particles_emitter; ParticleEmitter* m_sky_particles_emitter;
@ -57,7 +59,6 @@ private:
SFXBuffer *m_full_sound; SFXBuffer *m_full_sound;
SFXBuffer *m_unfull_sound; SFXBuffer *m_unfull_sound;
bool m_is_above_nitro_target;
virtual void steer(int, int) OVERRIDE; virtual void steer(int, int) OVERRIDE;
virtual void displayPenaltyWarning() OVERRIDE; virtual void displayPenaltyWarning() OVERRIDE;

View File

@ -108,12 +108,6 @@ void PlayerController::resetInputState()
*/ */
bool PlayerController::action(PlayerAction action, int value, bool dry_run) bool PlayerController::action(PlayerAction action, int value, bool dry_run)
{ {
if (!NetworkConfig::get()->isNetworking() ||
!NetworkConfig::get()->isServer())
{
if (m_penalty_ticks > 0)
return false;
}
/** If dry_run (parameter) is true, this macro tests if this action would /** If dry_run (parameter) is true, this macro tests if this action would
* trigger a state change in the specified variable (without actually * trigger a state change in the specified variable (without actually
* doing it). If it will trigger a state change, the macro will * doing it). If it will trigger a state change, the macro will
@ -330,29 +324,28 @@ void PlayerController::update(int ticks)
if (World::getWorld()->isStartPhase()) if (World::getWorld()->isStartPhase())
{ {
if (m_controls->getAccel() || m_controls->getBrake()|| if ((m_controls->getAccel() || m_controls->getBrake()||
m_controls->getFire() || m_controls->getNitro()) m_controls->getFire() || m_controls->getNitro()) &&
!NetworkConfig::get()->isNetworking())
{ {
// Only give penalty time in SET_PHASE. // Only give penalty time in READY_PHASE.
// Penalty time check makes sure it doesn't get rendered on every // Penalty time check makes sure it doesn't get rendered on every
// update. // update.
if (m_penalty_ticks == 0 && if (m_penalty_ticks == 0 &&
World::getWorld()->getPhase() == WorldStatus::SET_PHASE) World::getWorld()->getPhase() == WorldStatus::READY_PHASE)
{ {
displayPenaltyWarning(); displayPenaltyWarning();
m_penalty_ticks = stk_config->m_penalty_ticks; m_penalty_ticks = stk_config->m_penalty_ticks;
} // if penalty_time = 0 } // if penalty_time = 0
m_controls->setBrake(false); m_controls->setBrake(false);
m_controls->setAccel(0.0f);
} // if key pressed } // if key pressed
return; return;
} // if isStartPhase } // if isStartPhase
if (!RewindManager::get()->isRewinding() && m_penalty_ticks > 0) if (m_penalty_ticks != 0 &&
World::getWorld()->getTicksSinceStart() < m_penalty_ticks)
{ {
m_penalty_ticks -= ticks;
m_controls->setBrake(false); m_controls->setBrake(false);
m_controls->setAccel(0.0f); m_controls->setAccel(0.0f);
return; return;

View File

@ -2098,11 +2098,14 @@ void SkiddingAI::handleRaceStart()
? 0.0f : m_ai_properties->m_false_start_probability; ? 0.0f : m_ai_properties->m_false_start_probability;
// Now check for a false start. If so, add 1 second penalty time. // Now check for a false start. If so, add 1 second penalty time.
if(rand() < RAND_MAX * false_start_probability) if (rand() < RAND_MAX * false_start_probability)
{ {
m_start_delay+=stk_config->m_penalty_ticks; m_start_delay+=stk_config->m_penalty_ticks;
return; return;
} }
m_kart->setStartupBoost(m_kart->getStartupBoostFromStartTicks(
m_start_delay + stk_config->time2Ticks(1.0f)));
m_start_delay = 0;
} }
} // handleRaceStart } // handleRaceStart
@ -2114,7 +2117,7 @@ void SkiddingAI::handleRescue(const float dt)
{ {
// check if kart is stuck // check if kart is stuck
if(m_kart->getSpeed()<2.0f && !m_kart->getKartAnimation() && if(m_kart->getSpeed()<2.0f && !m_kart->getKartAnimation() &&
!m_world->isStartPhase()) !m_world->isStartPhase() && m_start_delay == 0)
{ {
m_time_since_stuck += dt; m_time_since_stuck += dt;
if(m_time_since_stuck > 2.0f) if(m_time_since_stuck > 2.0f)

View File

@ -1560,11 +1560,14 @@ void SkiddingAI::handleRaceStart()
? 0.0f : m_ai_properties->m_false_start_probability; ? 0.0f : m_ai_properties->m_false_start_probability;
// Now check for a false start. If so, add 1 second penalty time. // Now check for a false start. If so, add 1 second penalty time.
if(rand() < RAND_MAX * false_start_probability) if (rand() < RAND_MAX * false_start_probability)
{ {
m_start_delay+=stk_config->m_penalty_ticks; m_start_delay+=stk_config->m_penalty_ticks;
return; return;
} }
m_kart->setStartupBoost(m_kart->getStartupBoostFromStartTicks(
m_start_delay + stk_config->time2Ticks(1.0f)));
m_start_delay = 0;
} }
} // handleRaceStart } // handleRaceStart
@ -1576,7 +1579,7 @@ void SkiddingAI::handleRescue(const float dt)
{ {
// check if kart is stuck // check if kart is stuck
if(m_kart->getSpeed()<2.0f && !m_kart->getKartAnimation() && if(m_kart->getSpeed()<2.0f && !m_kart->getKartAnimation() &&
!m_world->isStartPhase()) !m_world->isStartPhase() && m_start_delay == 0)
{ {
m_time_since_stuck += dt; m_time_since_stuck += dt;
if(m_time_since_stuck > 2.0f) if(m_time_since_stuck > 2.0f)

View File

@ -368,7 +368,6 @@ void Kart::reset()
m_squash_time = std::numeric_limits<float>::max(); m_squash_time = std::numeric_limits<float>::max();
m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f)); m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));
m_collected_energy = 0; m_collected_energy = 0;
m_has_started = false;
m_bounce_back_ticks = 0; m_bounce_back_ticks = 0;
m_brake_ticks = 0; m_brake_ticks = 0;
m_ticks_last_crash = 0; m_ticks_last_crash = 0;
@ -378,7 +377,7 @@ void Kart::reset()
m_view_blocked_by_plunger = 0; m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false; m_has_caught_nolok_bubblegum = false;
m_is_jumping = false; m_is_jumping = false;
m_startup_boost = 0.0f;
for (int i=0;i<m_xyz_history_size;i++) for (int i=0;i<m_xyz_history_size;i++)
{ {
m_previous_xyz[i] = getXYZ(); m_previous_xyz[i] = getXYZ();
@ -1112,23 +1111,26 @@ void Kart::collectedItem(ItemState *item_state)
} // collectedItem } // collectedItem
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Called the first time a kart accelerates after 'ready-set-go'. It searches /** Called the first time a kart accelerates after 'ready'. It searches
* through the startup times to find the appropriate slot, and returns the * through the startup times to find the appropriate slot, and returns the
* speed-boost from the corresponding entry. * speed-boost from the corresponding entry.
* If the kart started too slow (i.e. slower than the longest time in the * If the kart started too slow (i.e. slower than the longest time in the
* startup times list), it returns 0. * startup times list), it returns 0.
*/ */
float Kart::getStartupBoost() const float Kart::getStartupBoostFromStartTicks(int ticks) const
{ {
float t = stk_config->ticks2Time(World::getWorld()->getTicksSinceStart()); int ticks_since_ready = ticks - stk_config->time2Ticks(1.0f);
if (ticks_since_ready < 0)
return 0.0f;
float t = stk_config->ticks2Time(ticks_since_ready);
std::vector<float> startup_times = m_kart_properties->getStartupTime(); std::vector<float> startup_times = m_kart_properties->getStartupTime();
for (unsigned int i = 0; i < startup_times.size(); i++) for (unsigned int i = 0; i < startup_times.size(); i++)
{ {
if (t <= startup_times[i]) if (t <= startup_times[i])
return m_kart_properties->getStartupBoost()[i]; return m_kart_properties->getStartupBoost()[i];
} }
return 0; return 0.0f;
} // getStartupBoost } // getStartupBoostFromStartTicks
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Simulates gears by adjusting the force of the engine. It also takes the /** Simulates gears by adjusting the force of the engine. It also takes the
@ -2432,21 +2434,18 @@ bool Kart::playCustomSFX(unsigned int type)
*/ */
void Kart::updatePhysics(int ticks) void Kart::updatePhysics(int ticks)
{ {
// Check if accel is pressed for the first time. The actual timing if (m_controls.getAccel() > 0.0f &&
// is done in getStartupBoost - it returns 0 if the start was actually World::getWorld()->getTicksSinceStart() == 1)
// too slow to qualify for a boost.
if(!m_has_started && m_controls.getAccel())
{ {
m_has_started = true; if (m_startup_boost > 0.0f)
float f = getStartupBoost();
if(f >= 0.0f)
{ {
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_ZIPPER, 100*f); m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_ZIPPER,
100.0f * m_startup_boost);
m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER, m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER,
0.9f*f, f, 0.9f * m_startup_boost, m_startup_boost,
/*engine_force*/200.0f, /*engine_force*/200.0f,
/*duration*/stk_config->time2Ticks(5.0f), /*duration*/stk_config->time2Ticks(5.0f),
/*fade_out_time*/stk_config->time2Ticks(5.0f)); /*fade_out_time*/stk_config->time2Ticks(5.0f));
} }
} }
if (m_bounce_back_ticks > std::numeric_limits<int16_t>::min()) if (m_bounce_back_ticks > std::numeric_limits<int16_t>::min())

View File

@ -144,10 +144,6 @@ protected:
/** For stars rotating around head effect */ /** For stars rotating around head effect */
Stars *m_stars_effect; Stars *m_stars_effect;
/** True if the kart hasn't moved since 'ready-set-go' - used to
* determine startup boost. */
bool m_has_started;
/** Maximum engine rpm's for the current gear. */ /** Maximum engine rpm's for the current gear. */
float m_max_gear_rpm; float m_max_gear_rpm;
@ -209,6 +205,7 @@ protected:
/** The skidmarks object for this kart. */ /** The skidmarks object for this kart. */
SkidMarks *m_skidmarks; SkidMarks *m_skidmarks;
float m_startup_boost;
float m_finish_time; float m_finish_time;
bool m_finished_race; bool m_finished_race;
@ -297,8 +294,9 @@ public:
virtual void setBoostAI (bool boosted) OVERRIDE; virtual void setBoostAI (bool boosted) OVERRIDE;
virtual bool getBoostAI () const OVERRIDE; virtual bool getBoostAI () const OVERRIDE;
virtual void collectedItem(ItemState *item) OVERRIDE; virtual void collectedItem(ItemState *item) OVERRIDE;
virtual float getStartupBoost() const; virtual float getStartupBoostFromStartTicks(int ticks) const OVERRIDE;
virtual float getStartupBoost() const OVERRIDE { return m_startup_boost; }
virtual void setStartupBoost(float val) OVERRIDE { m_startup_boost = val; }
virtual const Material *getMaterial() const OVERRIDE; virtual const Material *getMaterial() const OVERRIDE;
virtual const Material *getLastMaterial() const OVERRIDE; virtual const Material *getLastMaterial() const OVERRIDE;
/** Returns the pitch of the terrain depending on the heading. */ /** Returns the pitch of the terrain depending on the heading. */

View File

@ -293,7 +293,6 @@ std::function<void()> KartRewinder::getLocalStateRestoreFunction()
// Variable can be saved locally if its adjustment only depends on the kart // Variable can be saved locally if its adjustment only depends on the kart
// itself // itself
bool has_started = m_has_started;
int brake_ticks = m_brake_ticks; int brake_ticks = m_brake_ticks;
int8_t min_nitro_ticks = m_min_nitro_ticks; int8_t min_nitro_ticks = m_min_nitro_ticks;
float bubblegum_torque = m_bubblegum_torque; float bubblegum_torque = m_bubblegum_torque;
@ -320,11 +319,10 @@ std::function<void()> KartRewinder::getLocalStateRestoreFunction()
// Skidding local state // Skidding local state
float remaining_jump_time = m_skidding->m_remaining_jump_time; float remaining_jump_time = m_skidding->m_remaining_jump_time;
return [has_started, brake_ticks, min_nitro_ticks, bubblegum_torque, return [brake_ticks, min_nitro_ticks, bubblegum_torque,
initial_speed, steer_val_l, steer_val_r, current_fraction, initial_speed, steer_val_l, steer_val_r, current_fraction,
max_speed_fraction, remaining_jump_time, this]() max_speed_fraction, remaining_jump_time, this]()
{ {
m_has_started = has_started;
m_brake_ticks = brake_ticks; m_brake_ticks = brake_ticks;
m_min_nitro_ticks = min_nitro_ticks; m_min_nitro_ticks = min_nitro_ticks;
m_bubblegum_torque = bubblegum_torque; m_bubblegum_torque = bubblegum_torque;

View File

@ -204,6 +204,9 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Get the ticks since start regardless of which way the clock counts */ /** Get the ticks since start regardless of which way the clock counts */
int getTicksSinceStart() const { return m_count_up_ticks; } int getTicksSinceStart() const { return m_count_up_ticks; }
// ------------------------------------------------------------------------
int getAuxiliaryTicks() const { return m_auxiliary_ticks; }
}; // WorldStatus }; // WorldStatus