Skip to content
Open
18 changes: 18 additions & 0 deletions data/commands.xml
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,24 @@ here later. For now, please refer to the code for the strings being used. -->
state-scope="SS_LOBBY"
/>
</command>

<command name="itempolicy"
usage="/itempolicy"
description="Shows item policy."
permissions="UP_EVERYONE | PE_ALLOW_ANYONE"
permissions-verbose="everyone; invokable for another player"
state-scope="SS_ALWAYS"
>
<command name="="
usage="/itempolicy ((num) (sections, where each section is (bitstring data1 data2 data3 data4 num_pairs [item1 weight1...]) ))"
omit-name="true"
permissions-verbose="hammers"
description="Sets item policy to the specified one."
permissions="UP_HAMMER"
state-scope="SS_LOBBY"
/>
</command>

<command name="version"
usage="/version"
permissions="UP_EVERYONE | PE_ALLOW_ANYONE"
Expand Down
28 changes: 25 additions & 3 deletions src/items/flyable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,11 +553,33 @@ bool Flyable::hit(AbstractKart *kart_hit, PhysicalObject* object)
if (!m_has_server_state || hasAnimation())
return false;
// the owner of this flyable should not be hit by his own flyable
if(isOwnerImmunity(kart_hit)) return false;
m_has_hit_something=true;
if (isOwnerImmunity(kart_hit))
return false;

return true;
m_has_hit_something=true;
if (kart_hit == NULL)
return true;

// Now, if blue flags are enabled and the leader is in a valid section,
// that's when we start to question if the hit could be forbidden
// (a lapper illegally hitting a lapping or vice versa).
if (World::getWorld()->raceHasLaps()) {
LinearWorld *lin_world = dynamic_cast<LinearWorld*>(World::getWorld());
float track_length = Track::getCurrentTrack()->getTrackLength();
float sender_distance = std::fmod(lin_world->getOverallDistance(m_owner->getWorldKartId()), track_length);
float recv_distance = std::fmod(lin_world->getOverallDistance(kart_hit->getWorldKartId()), track_length);

int sender_lap = lin_world->getFinishedLapsOfKart(m_owner->getWorldKartId());
int recv_lap = lin_world->getFinishedLapsOfKart(kart_hit->getWorldKartId());

// Blue flag settings could make the hit invalid, if it's between a lapper
// and a lapped or vice versa. Let ItemPolicy decide this

ItemPolicy *policy = RaceManager::get()->getItemPolicy();
return policy->isHitValid(sender_distance, sender_lap, m_owner->getPosition(), recv_distance, recv_lap, kart_hit->getPosition(), track_length);
} else {
return true;
}
} // hit

// ----------------------------------------------------------------------------
Expand Down
49 changes: 29 additions & 20 deletions src/items/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,30 @@ void ItemState::initItem(ItemType type, const Vec3& xyz, const Vec3& normal)
setDisappearCounter();
} // initItem

static int getRespawnTicks(ItemState::ItemType type) {
auto& stk_config = STKConfig::get();
switch (type)
{
case ItemState::ITEM_BONUS_BOX:
return stk_config->m_bonusbox_item_return_ticks;
break;
case ItemState::ITEM_NITRO_BIG:
case ItemState::ITEM_NITRO_SMALL:
return stk_config->m_nitro_item_return_ticks;
break;
case ItemState::ITEM_BANANA:
return stk_config->m_banana_item_return_ticks;
break;
case ItemState::ITEM_BUBBLEGUM:
case ItemState::ITEM_BUBBLEGUM_NOLOK:
return stk_config->m_bubblegum_item_return_ticks;
break;
default:
return stk_config->time2Ticks(2.0f);
break;
}
}

// ----------------------------------------------------------------------------
/** Update the state of the item, called once per physics frame.
* \param ticks Number of ticks to simulate. While this value is 1 when
Expand All @@ -127,6 +151,10 @@ void ItemState::update(int ticks)
m_ticks_till_return -= ticks;
} // if collected

ItemPolicy *policy = RaceManager::get()->getItemPolicy();
m_ticks_till_return = policy->computeItemTicksTillReturn(
m_original_type, m_type, getRespawnTicks(m_type), m_ticks_till_return);

} // update

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -154,26 +182,7 @@ void ItemState::collected(const AbstractKart *kart)
}
else
{
switch (m_type)
{
case ITEM_BONUS_BOX:
m_ticks_till_return = stk_config->m_bonusbox_item_return_ticks;
break;
case ITEM_NITRO_BIG:
case ITEM_NITRO_SMALL:
m_ticks_till_return = stk_config->m_nitro_item_return_ticks;
break;
case ITEM_BANANA:
m_ticks_till_return = stk_config->m_banana_item_return_ticks;
break;
case ITEM_BUBBLEGUM:
case ITEM_BUBBLEGUM_NOLOK:
m_ticks_till_return = stk_config->m_bubblegum_item_return_ticks;
break;
default:
m_ticks_till_return = stk_config->time2Ticks(2.0f);
break;
}
m_ticks_till_return = getRespawnTicks(m_type);
}

if (RaceManager::get()->isBattleMode())
Expand Down
35 changes: 25 additions & 10 deletions src/items/powerup_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,43 @@ void PowerupManager::unloadPowerups()
}
} // removeTextures

// Must match the order of PowerupType in powerup_manager.hpp!!
static const std::string powerup_names[] = {
"nothing", /* Nothing */
"bubblegum", "cake", "bowling", "zipper", "plunger", "switch",
"swatter", "rubber-ball", "parachute", "anchor"
};

//-----------------------------------------------------------------------------
/** Determines the powerup type for a given name.
* \param name Name of the powerup to look up.
* \return The type, or POWERUP_NOTHING if the name is not found
*/
PowerupManager::PowerupType
PowerupManager::getPowerupType(const std::string &name) const
PowerupManager::PowerupType PowerupManager::getPowerupType(const std::string &name)
{
// Must match the order of PowerupType in powerup_manager.hpp!!
static const std::string powerup_names[] = {
"", /* Nothing */
"bubblegum", "cake", "bowling", "zipper", "plunger", "switch",
"swatter", "rubber-ball", "parachute", "anchor"
};

for(unsigned int i=POWERUP_FIRST; i<=POWERUP_LAST; i++)
{
if(powerup_names[i]==name) return(PowerupType)i;
if (name == "")
return POWERUP_NOTHING;
if (powerup_names[i] == name)
return (PowerupType)i;
}
return POWERUP_NOTHING;
} // getPowerupType

std::string PowerupManager::getPowerupAsString(PowerupManager::PowerupType type)
{
int size = sizeof(powerup_names) / sizeof(*powerup_names);

if (type == POWERUP_NOTHING)
return "nothing";

if (size < type - POWERUP_FIRST)
return "nothing";

return powerup_names[type - POWERUP_FIRST + 1];
} // getPowerupAsString

//-----------------------------------------------------------------------------
/** Loads powerups models and icons from the powerup.xml file.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/items/powerup_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ class PowerupManager : public NoCopy
/** The weight distribution to be used for the current race. */
WeightsData m_current_item_weights;

PowerupType getPowerupType(const std::string &name) const;

/** Seed for random powerup, for local game it will use a random number,
* for network games it will use the start time from server. */
std::atomic<uint64_t> m_random_seed;

std::string m_config_file;

public:
static PowerupType getPowerupType(const std::string &name);
static std::string getPowerupAsString(PowerupType type);
static void unitTesting();

PowerupManager ();
Expand Down
2 changes: 2 additions & 0 deletions src/karts/abstract_kart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ AbstractKart::AbstractKart(const std::string& ident,
std::shared_ptr<GE::GERenderInfo> ri)
: Moveable()
{
m_item_amount_last_lap = 0;
m_item_type_last_lap = PowerupManager::POWERUP_NOTHING;
m_world_kart_id = world_kart_id;
if (RaceManager::get()->getKartGlobalPlayerId(m_world_kart_id) > -1)
{
Expand Down
7 changes: 6 additions & 1 deletion src/karts/abstract_kart.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ class AbstractKart : public Moveable
std::shared_ptr<GE::GERenderInfo> ri);
virtual ~AbstractKart();
// ------------------------------------------------------------------------

// amount in previous lap
int m_item_amount_last_lap;
PowerupManager::PowerupType m_item_type_last_lap;

/** Returns a name to be displayed for this kart. */
const core::stringw& getName() const { return m_name; }
// ------------------------------------------------------------------------
Expand Down Expand Up @@ -358,7 +363,7 @@ class AbstractKart : public Moveable
* \param max_speed_fraction Fraction of top speed to allow only.
* \param fade_in_time How long till maximum speed is capped. */
virtual void setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time) = 0;
int fade_in_time, int duration = -1) = 0;
// ------------------------------------------------------------------------
/** Returns the remaining collected energy. */
virtual float getEnergy() const = 0;
Expand Down
8 changes: 6 additions & 2 deletions src/karts/kart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,9 +497,9 @@ void Kart::instantSpeedIncrease(unsigned int category, float add_max_speed,

// -----------------------------------------------------------------------------
void Kart::setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time)
int fade_in_time, int duration)
{
m_max_speed->setSlowdown(category, max_speed_fraction, fade_in_time);
m_max_speed->setSlowdown(category, max_speed_fraction, fade_in_time, duration);
} // setSlowdown

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -2671,6 +2671,10 @@ void Kart::updatePhysics(int ticks)

// Cap speed if necessary
const Material *m = getMaterial();
auto& stk_config = STKConfig::get();

ItemPolicy *item_policy = RaceManager::get()->getItemPolicy();
item_policy->enforceVirtualPaceCarRulesForKart(this);

float min_speed = m && m->isZipper() ? m->getZipperMinSpeed() : -1.0f;
m_max_speed->setMinSpeed(min_speed);
Expand Down
7 changes: 4 additions & 3 deletions src/karts/kart.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ class Kart : public AbstractKart
uint8_t m_bounce_back_ticks;

protected:
/** Handles speed increase and capping due to powerup, terrain, ... */
MaxSpeed *m_max_speed;

/** Stores information about the terrain the kart is on. */
TerrainInfo *m_terrain_info;
Expand Down Expand Up @@ -296,6 +294,9 @@ class Kart : public AbstractKart
void updateWeight();
void initSound();
public:
/** Handles speed increase and capping due to powerup, terrain, ... */
MaxSpeed *m_max_speed;

Kart(const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform,
HandicapLevel handicap,
Expand Down Expand Up @@ -360,7 +361,7 @@ class Kart : public AbstractKart
int duration, int fade_out_time) OVERRIDE;
// ----------------------------------------------------------------------------------------
virtual void setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time) OVERRIDE;
int fade_in_time, int duration = -1) OVERRIDE;
// ----------------------------------------------------------------------------------------
virtual int getSpeedIncreaseTicksLeft(unsigned int category) const OVERRIDE;
// ----------------------------------------------------------------------------------------
Expand Down
18 changes: 18 additions & 0 deletions src/karts/max_speed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "config/stk_config.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "network/network_string.hpp"
#include "physics/btKart.hpp"

Expand Down Expand Up @@ -372,6 +373,15 @@ int MaxSpeed::getSpeedIncreaseTicksLeft(unsigned int category)
return m_speed_increase[category].getTimeLeft();
} // getSpeedIncreaseTimeLeft

// ----------------------------------------------------------------------------
/** Returns how much decreased speed time is left over in the given category.
* \param category Which category to report on.
*/
int MaxSpeed::getSpeedDecreaseTicksLeft(unsigned int category)
{
return m_speed_decrease[category].getTimeLeft();
} // getSpeedIncreaseTimeLeft

// ----------------------------------------------------------------------------
/** Returns if increased speed is active in the given category.
* \param category Which category to report on.
Expand Down Expand Up @@ -447,6 +457,14 @@ void MaxSpeed::update(int ticks)
else
m_kart->getVehicle()->setMinSpeed(0); // no additional acceleration

// TODO
// 1.X ITEM POLICY: ENABLE THIS OR NOT? It will cause slight lag for all non-tux karts, but it's very needed
// PIT LIMITED / MAX SPEED IN PITS / PIT SPEED LIMITER
// if(m_speed_decrease[MS_DECREASE_BUBBLE].m_duration != 0) {
// m_current_max_speed = kart_properties_manager->getKart(std::string("tux"))->getEngineMaxSpeed()*0.1f;
// m_add_engine_force = 0.0f;
// }

if (m_kart->isOnGround())
m_kart->getVehicle()->setMaxSpeed(m_current_max_speed);
else
Expand Down
1 change: 1 addition & 0 deletions src/karts/max_speed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ friend class KartRewinder;
void setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time, int duration=-1);
int getSpeedIncreaseTicksLeft(unsigned int category);
int getSpeedDecreaseTicksLeft(unsigned int category);
int isSpeedIncreaseActive(unsigned int category);
int isSpeedDecreaseActive(unsigned int category);
void update(int ticks);
Expand Down
13 changes: 13 additions & 0 deletions src/modes/linear_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
#include "items/powerup.hpp"
#include "karts/max_speed.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/cannon_animation.hpp"
#include "karts/controller/controller.hpp"
Expand All @@ -40,6 +42,8 @@
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
#include "race/history.hpp"
#include "race/race_manager.hpp"
#include "race/item_policy.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/check_structure.hpp"
Expand Down Expand Up @@ -482,6 +486,15 @@ void LinearWorld::newLap(unsigned int kart_index)
// duplicated race positions as well.
updateRacePosition();

ItemPolicy *item_policy = RaceManager::get()->getItemPolicy();

int sec = item_policy->applyRules(kart, kart_info.m_finished_laps,
World::getWorld()->getTime(), RaceManager::get()->getNumLaps());
kart->m_item_type_last_lap = kart->getPowerup()->getType();
kart->m_item_amount_last_lap = kart->getPowerup()->getNum();

item_policy->checkAndApplyVirtualPaceCarRules(kart, sec, kart_info.m_finished_laps);

// Race finished
// We compute the exact moment the kart crossed the line
// This way, even with poor framerate, we get a time significant to the ms
Expand Down
Loading