Merged bubble bum branch into trunk. The new bubble gum
shield is still work in progress. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@13444 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
72a2b69695
commit
df9d90b342
@ -74,6 +74,9 @@
|
|||||||
|
|
||||||
* rubber_ball-icon, plunger icon, cake icon, bowling ball texture and icon
|
* rubber_ball-icon, plunger icon, cake icon, bowling ball texture and icon
|
||||||
by Totoplus62, released under CC-BY-SA 3.0
|
by Totoplus62, released under CC-BY-SA 3.0
|
||||||
|
|
||||||
|
* shield-icon
|
||||||
|
by tuxfan, release under CC-BY-SA 3.0
|
||||||
|
|
||||||
|
|
||||||
Others are GPL, by the original (super)TuxKart team
|
Others are GPL, by the original (super)TuxKart team
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 64 KiB |
BIN
data/models/bubblegum_shield.b3d
Normal file
BIN
data/models/bubblegum_shield.b3d
Normal file
Binary file not shown.
BIN
data/models/bubblegum_shield.png
Normal file
BIN
data/models/bubblegum_shield.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
data/models/shield-icon.png
Normal file
BIN
data/models/shield-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
@ -114,8 +114,10 @@
|
|||||||
nolok-bubble-gum, easter egg -->
|
nolok-bubble-gum, easter egg -->
|
||||||
<switch time="5" items="1 0 4 4 2 5 2 7"/>
|
<switch time="5" items="1 0 4 4 2 5 2 7"/>
|
||||||
|
|
||||||
<!-- How often bubblegum get driven over before it disappears. -->
|
<!-- disappear-counter: How often bubblegum gets driven over before it disappears.
|
||||||
<bubblegum disappear-counter="1"/>
|
shield-time: How long the bubblegum shield lasts
|
||||||
|
restrict-weapons: If true, using weapons will destroy the user's shield -->
|
||||||
|
<bubblegum disappear-counter="1" shield-time="10.0" restrict-weapons="false"/>
|
||||||
|
|
||||||
<!-- explosion-impulse-objects is the impulse that pushes physical objects
|
<!-- explosion-impulse-objects is the impulse that pushes physical objects
|
||||||
away if there is an explosion. -->
|
away if there is an explosion. -->
|
||||||
|
@ -118,6 +118,7 @@ void STKConfig::load(const std::string &filename)
|
|||||||
CHECK_NEG(m_anvil_weight, "anvil-weight" );
|
CHECK_NEG(m_anvil_weight, "anvil-weight" );
|
||||||
CHECK_NEG(m_item_switch_time, "item-switch-time" );
|
CHECK_NEG(m_item_switch_time, "item-switch-time" );
|
||||||
CHECK_NEG(m_bubblegum_counter, "bubblegum disappear counter");
|
CHECK_NEG(m_bubblegum_counter, "bubblegum disappear counter");
|
||||||
|
CHECK_NEG(m_bubblegum_shield_time, "bubblegum shield-time" );
|
||||||
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
|
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
|
||||||
CHECK_NEG(m_max_history, "max-history" );
|
CHECK_NEG(m_max_history, "max-history" );
|
||||||
CHECK_NEG(m_max_skidmarks, "max-skidmarks" );
|
CHECK_NEG(m_max_skidmarks, "max-skidmarks" );
|
||||||
@ -159,6 +160,8 @@ void STKConfig::init_defaults()
|
|||||||
m_smooth_angle_limit =
|
m_smooth_angle_limit =
|
||||||
m_penalty_time = m_explosion_impulse_objects = UNDEFINED;
|
m_penalty_time = m_explosion_impulse_objects = UNDEFINED;
|
||||||
m_bubblegum_counter = -100;
|
m_bubblegum_counter = -100;
|
||||||
|
m_bubblegum_shield_time = -100;
|
||||||
|
m_shield_restrict_weapos = false;
|
||||||
m_max_karts = -100;
|
m_max_karts = -100;
|
||||||
m_max_history = -100;
|
m_max_history = -100;
|
||||||
m_max_skidmarks = -100;
|
m_max_skidmarks = -100;
|
||||||
@ -335,7 +338,9 @@ void STKConfig::getAllData(const XMLNode * root)
|
|||||||
|
|
||||||
if(const XMLNode *bubblegum_node= root->getNode("bubblegum"))
|
if(const XMLNode *bubblegum_node= root->getNode("bubblegum"))
|
||||||
{
|
{
|
||||||
bubblegum_node->get("disappear-counter", &m_bubblegum_counter);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(const XMLNode *explosion_node= root->getNode("explosion"))
|
if(const XMLNode *explosion_node= root->getNode("explosion"))
|
||||||
|
@ -74,8 +74,10 @@ public:
|
|||||||
passed on. */
|
passed on. */
|
||||||
float m_anvil_time; /**<Time an anvil is active. */
|
float m_anvil_time; /**<Time an anvil is active. */
|
||||||
float m_item_switch_time; /**< Time items will be switched. */
|
float m_item_switch_time; /**< Time items will be switched. */
|
||||||
int m_bubblegum_counter; /**< How many times bananas must be eaten
|
int m_bubblegum_counter; /**< How many times bubble gums must be
|
||||||
before they disappear. */
|
driven over before they disappear. */
|
||||||
|
float m_bubblegum_shield_time; /**<How long a bubble gum shield lasts. */
|
||||||
|
bool m_shield_restrict_weapos; /**<Wether weapon usage is punished. */
|
||||||
float m_explosion_impulse_objects;/**<Impulse of explosion on moving
|
float m_explosion_impulse_objects;/**<Impulse of explosion on moving
|
||||||
objects, e.g. road cones, ... */
|
objects, e.g. road cones, ... */
|
||||||
float m_penalty_time; /**< Penalty time when starting too
|
float m_penalty_time; /**< Penalty time when starting too
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
#include "network/race_state.hpp"
|
#include "network/race_state.hpp"
|
||||||
#include "network/network_manager.hpp"
|
#include "network/network_manager.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
// Log::verbose("attachment", "Decreasing shield \n");
|
||||||
/** Initialises the attachment each kart has.
|
/** Initialises the attachment each kart has.
|
||||||
*/
|
*/
|
||||||
Attachment::Attachment(AbstractKart* kart)
|
Attachment::Attachment(AbstractKart* kart)
|
||||||
@ -92,7 +93,7 @@ void Attachment::set(AttachmentType type, float time,
|
|||||||
{
|
{
|
||||||
bool was_bomb = (m_type == ATTACH_BOMB);
|
bool was_bomb = (m_type == ATTACH_BOMB);
|
||||||
scene::ISceneNode* bomb_scene_node = NULL;
|
scene::ISceneNode* bomb_scene_node = NULL;
|
||||||
if (was_bomb && type == ATTACH_SWATTER)
|
if (was_bomb && type == ATTACH_SWATTER) //What about ATTACH_NOLOKS_SWATTER ??
|
||||||
{
|
{
|
||||||
// let's keep the bomb node, and create a new one for
|
// let's keep the bomb node, and create a new one for
|
||||||
// the new attachment
|
// the new attachment
|
||||||
@ -206,6 +207,13 @@ void Attachment::clear()
|
|||||||
*/
|
*/
|
||||||
void Attachment::hitBanana(Item *item, int new_attachment)
|
void Attachment::hitBanana(Item *item, int new_attachment)
|
||||||
{
|
{
|
||||||
|
//Bubble gum shield effect:
|
||||||
|
if(m_type == ATTACH_BUBBLEGUM_SHIELD)
|
||||||
|
{
|
||||||
|
m_time_left -= stk_config->m_bubblegum_shield_time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float leftover_time = 0.0f;
|
float leftover_time = 0.0f;
|
||||||
|
|
||||||
bool add_a_new_item = true;
|
bool add_a_new_item = true;
|
||||||
@ -414,6 +422,18 @@ void Attachment::update(float dt)
|
|||||||
case ATTACH_TINYTUX:
|
case ATTACH_TINYTUX:
|
||||||
// Nothing to do for tinytux, this is all handled in EmergencyAnimation
|
// Nothing to do for tinytux, this is all handled in EmergencyAnimation
|
||||||
break;
|
break;
|
||||||
|
case ATTACH_BUBBLEGUM_SHIELD:
|
||||||
|
if(!m_kart->isShielded())
|
||||||
|
{
|
||||||
|
m_time_left = 0.0f;
|
||||||
|
if (m_kart->m_bubble_drop)
|
||||||
|
{
|
||||||
|
Log::verbose("Attachment", "Drop a small bubble gum. \n");;
|
||||||
|
//TODO: drop a bubble gum item on the track
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
// Detach attachment if its time is up.
|
// Detach attachment if its time is up.
|
||||||
|
@ -59,6 +59,7 @@ public:
|
|||||||
ATTACH_SWATTER,
|
ATTACH_SWATTER,
|
||||||
ATTACH_NOLOKS_SWATTER,
|
ATTACH_NOLOKS_SWATTER,
|
||||||
ATTACH_TINYTUX,
|
ATTACH_TINYTUX,
|
||||||
|
ATTACH_BUBBLEGUM_SHIELD,
|
||||||
ATTACH_MAX,
|
ATTACH_MAX,
|
||||||
ATTACH_NOTHING
|
ATTACH_NOTHING
|
||||||
};
|
};
|
||||||
|
@ -47,13 +47,14 @@ struct initAttachmentType {Attachment::AttachmentType attachment;
|
|||||||
|
|
||||||
static const initAttachmentType iat[]=
|
static const initAttachmentType iat[]=
|
||||||
{
|
{
|
||||||
{Attachment::ATTACH_PARACHUTE, "parachute.b3d", "parachute-attach-icon.png"},
|
{Attachment::ATTACH_PARACHUTE, "parachute.b3d", "parachute-attach-icon.png" },
|
||||||
{Attachment::ATTACH_BOMB, "bomb.b3d", "bomb-attach-icon.png" },
|
{Attachment::ATTACH_BOMB, "bomb.b3d", "bomb-attach-icon.png" },
|
||||||
{Attachment::ATTACH_ANVIL, "anchor.b3d", "anchor-attach-icon.png" },
|
{Attachment::ATTACH_ANVIL, "anchor.b3d", "anchor-attach-icon.png" },
|
||||||
{Attachment::ATTACH_SWATTER, "swatter.b3d", "swatter-icon.png" },
|
{Attachment::ATTACH_SWATTER, "swatter.b3d", "swatter-icon.png" },
|
||||||
{Attachment::ATTACH_NOLOKS_SWATTER, "swatter_nolok.b3d","swatter-icon.png" },
|
{Attachment::ATTACH_NOLOKS_SWATTER, "swatter_nolok.b3d", "swatter-icon.png" },
|
||||||
{Attachment::ATTACH_TINYTUX, "reset-button.b3d", "reset-attach-icon.png" },
|
{Attachment::ATTACH_TINYTUX, "reset-button.b3d", "reset-attach-icon.png" },
|
||||||
{Attachment::ATTACH_MAX, "", "" },
|
{Attachment::ATTACH_BUBBLEGUM_SHIELD, "bubblegum_shield.b3d", "shield-icon.png" },
|
||||||
|
{Attachment::ATTACH_MAX, "", "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
#include "utils/random_generator.hpp"
|
#include "utils/random_generator.hpp"
|
||||||
|
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
float Bowling::m_st_max_distance; // maximum distance for a bowling ball to be attracted
|
float Bowling::m_st_max_distance; // maximum distance for a bowling ball to be attracted
|
||||||
float Bowling::m_st_max_distance_squared;
|
float Bowling::m_st_max_distance_squared;
|
||||||
float Bowling::m_st_force_to_target;
|
float Bowling::m_st_force_to_target;
|
||||||
@ -213,11 +215,21 @@ bool Bowling::hit(AbstractKart* kart, PhysicalObject* obj)
|
|||||||
bool was_real_hit = Flyable::hit(kart, obj);
|
bool was_real_hit = Flyable::hit(kart, obj);
|
||||||
if(was_real_hit)
|
if(was_real_hit)
|
||||||
{
|
{
|
||||||
m_has_hit_kart = kart != NULL;
|
if(kart && kart->isShielded())
|
||||||
explode(kart, obj, /*hit_secondary*/false);
|
{
|
||||||
|
kart->decreaseShieldTime(0.0f); //Decreasing the shield time by the default value.
|
||||||
|
Log::verbose("Bowling", "Decreasing shield!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_has_hit_kart = kart != NULL;
|
||||||
|
explode(kart, obj, /*hit_secondary*/false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return was_real_hit;
|
return was_real_hit;
|
||||||
} // hit
|
} // hit
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Returns the hit effect object to use when this objects hits something.
|
/** Returns the hit effect object to use when this objects hits something.
|
||||||
* \returns The hit effect object, or NULL if no hit effect should be played.
|
* \returns The hit effect object, or NULL if no hit effect should be played.
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
#include "utils/random_generator.hpp"
|
#include "utils/random_generator.hpp"
|
||||||
|
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
float Cake::m_st_max_distance_squared;
|
float Cake::m_st_max_distance_squared;
|
||||||
float Cake::m_gravity;
|
float Cake::m_gravity;
|
||||||
|
|
||||||
@ -168,7 +170,15 @@ bool Cake::hit(AbstractKart* kart, PhysicalObject* obj)
|
|||||||
{
|
{
|
||||||
bool was_real_hit = Flyable::hit(kart, obj);
|
bool was_real_hit = Flyable::hit(kart, obj);
|
||||||
if(was_real_hit)
|
if(was_real_hit)
|
||||||
|
{
|
||||||
|
if(kart && kart->isShielded())
|
||||||
|
{
|
||||||
|
kart->decreaseShieldTime(0.0f); //Decreasing the shield time by the default value.
|
||||||
|
Log::verbose("Cake", "Decreasing shield! \n");
|
||||||
|
return false; //Not sure if a shield hit is a real hit.
|
||||||
|
}
|
||||||
explode(kart, obj);
|
explode(kart, obj);
|
||||||
|
}
|
||||||
|
|
||||||
return was_real_hit;
|
return was_real_hit;
|
||||||
} // hit
|
} // hit
|
||||||
|
@ -425,7 +425,7 @@ void Flyable::updateFromServer(const FlyableInfo &f, float dt)
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Returns true if the item hit the kart who shot it (to avoid that an item
|
/** Returns true if the item hit the kart who shot it (to avoid that an item
|
||||||
* that's too close to the shoter hits the shoter).
|
* that's too close to the shooter hits the shooter).
|
||||||
* \param kart Kart who was hit.
|
* \param kart Kart who was hit.
|
||||||
*/
|
*/
|
||||||
bool Flyable::isOwnerImmunity(const AbstractKart* kart_hit) const
|
bool Flyable::isOwnerImmunity(const AbstractKart* kart_hit) const
|
||||||
@ -448,7 +448,7 @@ bool Flyable::hit(AbstractKart *kart_hit, PhysicalObject* object)
|
|||||||
if(isOwnerImmunity(kart_hit)) return false;
|
if(isOwnerImmunity(kart_hit)) return false;
|
||||||
|
|
||||||
if (kart_hit != NULL)
|
if (kart_hit != NULL)
|
||||||
{
|
{ //TODO: reduce shield time; add other string ?
|
||||||
RaceGUIBase* gui = World::getWorld()->getRaceGUI();
|
RaceGUIBase* gui = World::getWorld()->getRaceGUI();
|
||||||
irr::core::stringw hit_message =
|
irr::core::stringw hit_message =
|
||||||
StringUtils::insertValues(getHitString(kart_hit),
|
StringUtils::insertValues(getHitString(kart_hit),
|
||||||
|
@ -278,6 +278,10 @@ Item* ItemManager::newItem(const Vec3& xyz, float distance,
|
|||||||
void ItemManager::collectedItem(Item *item, AbstractKart *kart, int add_info)
|
void ItemManager::collectedItem(Item *item, AbstractKart *kart, int add_info)
|
||||||
{
|
{
|
||||||
assert(item);
|
assert(item);
|
||||||
|
if((item->getType() == Item::ITEM_BUBBLEGUM || item->getType() == Item::ITEM_BUBBLEGUM_NOLOK) && kart->isShielded())
|
||||||
|
{// shielded karts can simply drive over bubble gums without any effect.
|
||||||
|
return;
|
||||||
|
}
|
||||||
item->collected(kart);
|
item->collected(kart);
|
||||||
kart->collectedItem(item, add_info);
|
kart->collectedItem(item, add_info);
|
||||||
} // collectedItem
|
} // collectedItem
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
|
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
Plunger::Plunger(AbstractKart *kart)
|
Plunger::Plunger(AbstractKart *kart)
|
||||||
@ -180,6 +180,13 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
|||||||
{
|
{
|
||||||
if(isOwnerImmunity(kart)) return false;
|
if(isOwnerImmunity(kart)) return false;
|
||||||
|
|
||||||
|
/*if(kart && kart->isShielded())
|
||||||
|
{
|
||||||
|
//kart->decreaseShieldTime(0.0f); //Decreasing the shield time by the default value.
|
||||||
|
Log::verbose("Plunger", "Almost Decreasing shield! \n");
|
||||||
|
|
||||||
|
return false; //Not sure if a shield hit is a real hit.
|
||||||
|
}*/
|
||||||
RaceGUIBase* gui = World::getWorld()->getRaceGUI();
|
RaceGUIBase* gui = World::getWorld()->getRaceGUI();
|
||||||
irr::core::stringw hit_message;
|
irr::core::stringw hit_message;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "physics/triangle_mesh.hpp"
|
#include "physics/triangle_mesh.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
const wchar_t* getAnchorString()
|
const wchar_t* getAnchorString()
|
||||||
{
|
{
|
||||||
@ -164,7 +164,7 @@ void Powerup::set(PowerupManager::PowerupType type, int n)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PowerupManager::POWERUP_BUBBLEGUM:
|
case PowerupManager::POWERUP_BUBBLEGUM:
|
||||||
m_sound_use = sfx_manager->createSoundSource("goo");
|
m_sound_use = sfx_manager->createSoundSource("goo");
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case PowerupManager::POWERUP_SWITCH:
|
case PowerupManager::POWERUP_SWITCH:
|
||||||
@ -192,12 +192,38 @@ Material *Powerup::getIcon() const
|
|||||||
return powerup_manager->getIcon(m_type);
|
return powerup_manager->getIcon(m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Does the sound configuration.
|
||||||
|
*/
|
||||||
|
void Powerup::adjustSound()
|
||||||
|
{
|
||||||
|
m_sound_use->position(m_owner->getXYZ());
|
||||||
|
// in multiplayer mode, sounds are NOT positional (because we have multiple listeners)
|
||||||
|
// so the sounds of all AIs are constantly heard. So reduce volume of sounds.
|
||||||
|
if (race_manager->getNumLocalPlayers() > 1)
|
||||||
|
{
|
||||||
|
// player karts played at full volume; AI karts much dimmer
|
||||||
|
|
||||||
|
if (m_owner->getController()->isPlayerController())
|
||||||
|
{
|
||||||
|
m_sound_use->volume( 1.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sound_use->volume( std::min(0.5f, 1.0f / race_manager->getNumberOfKarts()) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Use (fire) this powerup.
|
/** Use (fire) this powerup.
|
||||||
*/
|
*/
|
||||||
void Powerup::use()
|
void Powerup::use()
|
||||||
{
|
{
|
||||||
// Play custom kart sound when collectible is used
|
// Play custom kart sound when collectible is used //TODO: what about the bubble gum?
|
||||||
if (m_type != PowerupManager::POWERUP_NOTHING &&
|
if (m_type != PowerupManager::POWERUP_NOTHING &&
|
||||||
m_type != PowerupManager::POWERUP_SWATTER &&
|
m_type != PowerupManager::POWERUP_SWATTER &&
|
||||||
m_type != PowerupManager::POWERUP_ZIPPER)
|
m_type != PowerupManager::POWERUP_ZIPPER)
|
||||||
@ -233,26 +259,11 @@ void Powerup::use()
|
|||||||
case PowerupManager::POWERUP_RUBBERBALL:
|
case PowerupManager::POWERUP_RUBBERBALL:
|
||||||
case PowerupManager::POWERUP_BOWLING:
|
case PowerupManager::POWERUP_BOWLING:
|
||||||
case PowerupManager::POWERUP_PLUNGER:
|
case PowerupManager::POWERUP_PLUNGER:
|
||||||
|
if(stk_config->m_shield_restrict_weapos)
|
||||||
m_sound_use->position(m_owner->getXYZ());
|
m_owner->setShieldTime(0.0f); // make weapon usage destroy the shield
|
||||||
|
Powerup::adjustSound();
|
||||||
// in multiplayer mode, sounds are NOT positional (because we have multiple listeners)
|
|
||||||
// so the sounds of all AIs are constantly heard. So reduce volume of sounds.
|
|
||||||
if (race_manager->getNumLocalPlayers() > 1)
|
|
||||||
{
|
|
||||||
// player karts played at full volume; AI karts much dimmer
|
|
||||||
|
|
||||||
if (m_owner->getController()->isPlayerController())
|
|
||||||
{
|
|
||||||
m_sound_use->volume( 1.0f );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sound_use->volume( std::min(0.5f, 1.0f / race_manager->getNumberOfKarts()) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sound_use->play();
|
m_sound_use->play();
|
||||||
|
|
||||||
projectile_manager->newProjectile(m_owner, world->getTrack(), m_type);
|
projectile_manager->newProjectile(m_owner, world->getTrack(), m_type);
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
@ -261,51 +272,55 @@ void Powerup::use()
|
|||||||
->set(Attachment::ATTACH_SWATTER,
|
->set(Attachment::ATTACH_SWATTER,
|
||||||
m_owner->getKartProperties()->getSwatterDuration());
|
m_owner->getKartProperties()->getSwatterDuration());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PowerupManager::POWERUP_BUBBLEGUM:
|
case PowerupManager::POWERUP_BUBBLEGUM:
|
||||||
|
// use the bubble gum the traditional way, if the kart is looking back
|
||||||
|
if (m_owner->getControls().m_look_back)
|
||||||
{
|
{
|
||||||
Vec3 hit_point;
|
Vec3 hit_point;
|
||||||
Vec3 normal;
|
Vec3 normal;
|
||||||
const Material* material_hit;
|
const Material* material_hit;
|
||||||
Vec3 pos = m_owner->getXYZ();
|
Vec3 pos = m_owner->getXYZ();
|
||||||
Vec3 to=pos+Vec3(0, -10000, 0);
|
Vec3 to=pos+Vec3(0, -10000, 0);
|
||||||
world->getTrack()->getTriangleMesh().castRay(pos, to, &hit_point,
|
world->getTrack()->getTriangleMesh().castRay(pos, to, &hit_point,
|
||||||
&material_hit, &normal);
|
&material_hit, &normal);
|
||||||
// This can happen if the kart is 'over nothing' when dropping
|
// This can happen if the kart is 'over nothing' when dropping
|
||||||
// the bubble gum
|
// the bubble gum
|
||||||
if(!material_hit)
|
if(!material_hit)
|
||||||
return;
|
return;
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
|
|
||||||
// in multiplayer mode, sounds are NOT positional (because we have multiple listeners)
|
Powerup::adjustSound();
|
||||||
// so the sounds of all AIs are constantly heard. So reduce volume of sounds.
|
m_sound_use->play();
|
||||||
if (race_manager->getNumLocalPlayers() > 1)
|
|
||||||
|
pos.setY(hit_point.getY()-0.05f);
|
||||||
|
|
||||||
|
ItemManager::get()->newItem(Item::ITEM_BUBBLEGUM, pos, normal, m_owner);
|
||||||
|
}
|
||||||
|
else // if the kart is looking forward, use the bubblegum as a shield
|
||||||
{
|
{
|
||||||
const int np = race_manager->getNumLocalPlayers();
|
|
||||||
const int nai = race_manager->getNumberOfKarts() - np;
|
|
||||||
|
|
||||||
// player karts played at full volume; AI karts much dimmer
|
if(!m_owner->isShielded()) //if the previous shield had been used up.
|
||||||
|
|
||||||
if (m_owner->getController()->isPlayerController())
|
|
||||||
{
|
{
|
||||||
m_sound_use->volume( 1.0f );
|
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
|
||||||
|
stk_config->m_bubblegum_shield_time);
|
||||||
}
|
}
|
||||||
else
|
else // using a bubble gum while still having a shield
|
||||||
{
|
{
|
||||||
m_sound_use->volume( 1.0f / nai );
|
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
|
||||||
|
stk_config->m_bubblegum_shield_time + m_owner->getShieldTime());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_sound_use->position(m_owner->getXYZ());
|
m_sound_use = sfx_manager->createSoundSource("inflate");//Extraordinary. Usually sounds are set in Powerup::set()
|
||||||
m_sound_use->play();
|
//In this case this is a workaround, since the bubblegum item has two different sounds.
|
||||||
|
|
||||||
pos.setY(hit_point.getY()-0.05f);
|
Powerup::adjustSound();
|
||||||
|
m_sound_use->play();
|
||||||
|
|
||||||
ItemManager::get()->newItem(Item::ITEM_BUBBLEGUM, pos, normal, m_owner);
|
} // end of PowerupManager::POWERUP_BUBBLEGUM
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PowerupManager::POWERUP_ANVIL:
|
case PowerupManager::POWERUP_ANVIL:
|
||||||
|
|
||||||
//Attach an anvil(twice as good as the one given
|
//Attach an anvil(twice as good as the one given
|
||||||
//by the bananas) to the kart in the 1st position.
|
//by the bananas) to the kart in the 1st position.
|
||||||
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
||||||
@ -351,6 +366,12 @@ void Powerup::use()
|
|||||||
{
|
{
|
||||||
AbstractKart *kart=world->getKart(i);
|
AbstractKart *kart=world->getKart(i);
|
||||||
if(kart->isEliminated() || kart== m_owner) continue;
|
if(kart->isEliminated() || kart== m_owner) continue;
|
||||||
|
if(kart->isShielded())
|
||||||
|
{
|
||||||
|
kart->decreaseShieldTime(stk_config->m_bubblegum_shield_time);
|
||||||
|
Log::verbose("Powerup", "Decreasing shield \n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(m_owner->getPosition() > kart->getPosition())
|
if(m_owner->getPosition() > kart->getPosition())
|
||||||
{
|
{
|
||||||
kart->getAttachment()
|
kart->getAttachment()
|
||||||
|
@ -56,8 +56,9 @@ public:
|
|||||||
void set (PowerupManager::PowerupType _type, int n=1);
|
void set (PowerupManager::PowerupType _type, int n=1);
|
||||||
void reset ();
|
void reset ();
|
||||||
Material* getIcon () const;
|
Material* getIcon () const;
|
||||||
|
void adjustSound ();
|
||||||
void use ();
|
void use ();
|
||||||
void hitBonusBox (const Item &item, int newC=-1);
|
void hitBonusBox (const Item &item, int newC=-1);
|
||||||
|
|
||||||
/** Returns the number of powerups. */
|
/** Returns the number of powerups. */
|
||||||
int getNum () const {return m_number;}
|
int getNum () const {return m_number;}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "audio/sfx_base.hpp"
|
#include "audio/sfx_base.hpp"
|
||||||
#include "audio/sfx_manager.hpp"
|
#include "audio/sfx_manager.hpp"
|
||||||
|
#include "config/stk_config.hpp"
|
||||||
#include "items/attachment.hpp"
|
#include "items/attachment.hpp"
|
||||||
#include "items/projectile_manager.hpp"
|
#include "items/projectile_manager.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
@ -28,6 +29,8 @@
|
|||||||
#include "physics/triangle_mesh.hpp"
|
#include "physics/triangle_mesh.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
|
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
float RubberBall::m_st_interval;
|
float RubberBall::m_st_interval;
|
||||||
float RubberBall::m_st_min_interpolation_distance;
|
float RubberBall::m_st_min_interpolation_distance;
|
||||||
float RubberBall::m_st_squash_duration;
|
float RubberBall::m_st_squash_duration;
|
||||||
@ -717,6 +720,21 @@ bool RubberBall::hit(AbstractKart* kart, PhysicalObject* object)
|
|||||||
}
|
}
|
||||||
bool was_real_hit = Flyable::hit(kart, object);
|
bool was_real_hit = Flyable::hit(kart, object);
|
||||||
if(was_real_hit)
|
if(was_real_hit)
|
||||||
explode(kart, object);
|
{
|
||||||
|
/*if(kart && kart->isShielded() && kart->getShieldTime() > stk_config->m_bubblegum_shield_time )
|
||||||
|
{ //remove twice the default shield time
|
||||||
|
kart->decreaseShieldTime(stk_config->m_bubblegum_shield_time * 2);
|
||||||
|
Log::verbose("rubber_ball", "Decreasing shield 1! \n");
|
||||||
|
}
|
||||||
|
else */if(kart && kart->isShielded())
|
||||||
|
{
|
||||||
|
kart->decreaseShieldTime(stk_config->m_bubblegum_shield_time);
|
||||||
|
//kart->getAttachment()->update(0.0f);
|
||||||
|
//kart->setSquash(m_st_squash_duration, m_st_squash_slowdown);
|
||||||
|
Log::verbose("rubber_ball", "Decreasing shield 2! \n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
explode(kart, object);
|
||||||
|
}
|
||||||
return was_real_hit;
|
return was_real_hit;
|
||||||
} // hit
|
} // hit
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
|
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
#include <IMesh.h>
|
#include <IMesh.h>
|
||||||
|
|
||||||
const wchar_t* getPlungerString()
|
const wchar_t* getPlungerString()
|
||||||
@ -135,7 +137,7 @@ void RubberBand::updatePosition()
|
|||||||
*/
|
*/
|
||||||
void RubberBand::update(float dt)
|
void RubberBand::update(float dt)
|
||||||
{
|
{
|
||||||
if(m_owner->isEliminated())
|
if(m_owner->isEliminated() || m_owner->isShielded())
|
||||||
{
|
{
|
||||||
// Rubber band snaps
|
// Rubber band snaps
|
||||||
m_plunger->hit(NULL);
|
m_plunger->hit(NULL);
|
||||||
@ -238,10 +240,20 @@ void RubberBand::hit(AbstractKart *kart_hit, const Vec3 *track_xyz)
|
|||||||
// a hit as well as the bullet physics.
|
// a hit as well as the bullet physics.
|
||||||
if(m_attached_state!=RB_TO_PLUNGER) return;
|
if(m_attached_state!=RB_TO_PLUNGER) return;
|
||||||
|
|
||||||
|
|
||||||
// A kart was hit
|
// A kart was hit
|
||||||
// ==============
|
// ==============
|
||||||
if(kart_hit)
|
if(kart_hit)
|
||||||
{
|
{
|
||||||
|
if(kart_hit->isShielded())
|
||||||
|
{
|
||||||
|
kart_hit->decreaseShieldTime(0.0f); //Decreasing the shield time by the default value.
|
||||||
|
m_plunger->setKeepAlive(0.0f);
|
||||||
|
Log::verbose("rubber_band", "Decreasing shield! \n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_hit_kart = kart_hit;
|
m_hit_kart = kart_hit;
|
||||||
m_attached_state = RB_TO_KART;
|
m_attached_state = RB_TO_KART;
|
||||||
|
|
||||||
|
@ -378,6 +378,18 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void setInvulnerableTime(float t) = 0;
|
virtual void setInvulnerableTime(float t) = 0;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns if the kart is protected by a shield. */
|
||||||
|
virtual bool isShielded() const = 0;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void setShieldTime(float t) = 0;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual float getShieldTime() const = 0;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Decreases the kart's shield time. */
|
||||||
|
//Hard coded shield decrease time
|
||||||
|
virtual void decreaseShieldTime(float t) = 0;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/** Shows the star effect for a certain time. */
|
/** Shows the star effect for a certain time. */
|
||||||
virtual void showStarEffect(float t) = 0;
|
virtual void showStarEffect(float t) = 0;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -403,6 +415,9 @@ public:
|
|||||||
/** Set a text that is displayed on top of a kart.
|
/** Set a text that is displayed on top of a kart.
|
||||||
*/
|
*/
|
||||||
virtual void setOnScreenText(const wchar_t *text) = 0;
|
virtual void setOnScreenText(const wchar_t *text) = 0;
|
||||||
|
/** Whether an unused bubble gum shield becomes a bubble gum on the ground.
|
||||||
|
* */
|
||||||
|
bool m_bubble_drop;
|
||||||
}; // AbstractKart
|
}; // AbstractKart
|
||||||
|
|
||||||
|
|
||||||
|
@ -1149,6 +1149,10 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle,
|
|||||||
* better job on higher level AI - e.g. aiming at karts ahead/behind, wait an
|
* better job on higher level AI - e.g. aiming at karts ahead/behind, wait an
|
||||||
* appropriate time before using multiple items etc.
|
* appropriate time before using multiple items etc.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
|
* TODO: Implications of Bubble-Shield for AI's powerup-handling
|
||||||
|
|
||||||
|
* STATE: shield on -> avoid usage of offensive items (with certain tolerance)
|
||||||
|
* STATE: swatter on -> avoid usage of shield
|
||||||
*/
|
*/
|
||||||
void SkiddingAI::handleItems(const float dt)
|
void SkiddingAI::handleItems(const float dt)
|
||||||
{
|
{
|
||||||
@ -1192,11 +1196,13 @@ void SkiddingAI::handleItems(const float dt)
|
|||||||
|
|
||||||
// Tactic 2: calculate
|
// Tactic 2: calculate
|
||||||
// -------------------
|
// -------------------
|
||||||
|
float min_bubble_time = 2.0f;
|
||||||
|
|
||||||
switch( m_kart->getPowerup()->getType() )
|
switch( m_kart->getPowerup()->getType() )
|
||||||
{
|
{
|
||||||
case PowerupManager::POWERUP_BUBBLEGUM:
|
case PowerupManager::POWERUP_BUBBLEGUM:
|
||||||
// Avoid dropping all bubble gums one after another
|
// Avoid dropping all bubble gums one after another
|
||||||
if( m_time_since_last_shot <3.0f) break;
|
if( m_time_since_last_shot < 3.0f) break;
|
||||||
|
|
||||||
// Either use the bubble gum after 10 seconds, or if the next kart
|
// Either use the bubble gum after 10 seconds, or if the next kart
|
||||||
// behind is 'close' but not too close (too close likely means that the
|
// behind is 'close' but not too close (too close likely means that the
|
||||||
@ -1205,16 +1211,30 @@ void SkiddingAI::handleItems(const float dt)
|
|||||||
// kart as well? I.e. only drop if the kart behind is faster? Otoh
|
// kart as well? I.e. only drop if the kart behind is faster? Otoh
|
||||||
// this approach helps preventing an overtaken kart to overtake us
|
// this approach helps preventing an overtaken kart to overtake us
|
||||||
// again.
|
// again.
|
||||||
|
m_controls->m_look_back = true; //handle traditinal usage as bubble gum
|
||||||
m_controls->m_fire = (m_distance_behind < 15.0f &&
|
m_controls->m_fire = (m_distance_behind < 15.0f &&
|
||||||
m_distance_behind > 3.0f );
|
m_distance_behind > 3.0f );//TODO: is this criteria sufficient to hit another kart with a high probability
|
||||||
|
|
||||||
|
m_controls->m_look_back = false;
|
||||||
|
//Do not use a shield, when you still have a swatter
|
||||||
|
if (m_kart->getAttachment()->getType() == Attachment::ATTACH_SWATTER || m_kart->getAttachment()->getType() == Attachment::ATTACH_NOLOKS_SWATTER)
|
||||||
|
break;
|
||||||
|
//else there are no objections not to use a shield
|
||||||
|
m_controls->m_fire = true;
|
||||||
|
|
||||||
break; // POWERUP_BUBBLEGUM
|
break; // POWERUP_BUBBLEGUM
|
||||||
|
|
||||||
// All the thrown/fired items might be improved by considering the angle
|
// All the thrown/fired items might be improved by considering the angle
|
||||||
// towards m_kart_ahead.
|
// towards m_kart_ahead.
|
||||||
case PowerupManager::POWERUP_CAKE:
|
case PowerupManager::POWERUP_CAKE:
|
||||||
{
|
{
|
||||||
|
// Do not destroy your own shield
|
||||||
|
if(m_kart->getShieldTime() > min_bubble_time) // if the kart has a shield, do not break it by using a swatter.
|
||||||
|
break;
|
||||||
// Leave some time between shots
|
// Leave some time between shots
|
||||||
if(m_time_since_last_shot<3.0f) break;
|
if(m_time_since_last_shot<3.0f) break;
|
||||||
|
//TODO: do not fire if the kart is driving too slow
|
||||||
|
|
||||||
// Since cakes can be fired all around, just use a sane distance
|
// Since cakes can be fired all around, just use a sane distance
|
||||||
// with a bit of extra for backwards, as enemy will go towards cake
|
// with a bit of extra for backwards, as enemy will go towards cake
|
||||||
bool fire_backwards = (m_kart_behind && m_kart_ahead &&
|
bool fire_backwards = (m_kart_behind && m_kart_ahead &&
|
||||||
@ -1231,6 +1251,9 @@ void SkiddingAI::handleItems(const float dt)
|
|||||||
|
|
||||||
case PowerupManager::POWERUP_BOWLING:
|
case PowerupManager::POWERUP_BOWLING:
|
||||||
{
|
{
|
||||||
|
// Do not destroy your own shield
|
||||||
|
if(m_kart->getShieldTime() > min_bubble_time) // if the kart has a shield, do not break it by using a swatter.
|
||||||
|
break;
|
||||||
// Leave more time between bowling balls, since they are
|
// Leave more time between bowling balls, since they are
|
||||||
// slower, so it should take longer to hit something which
|
// slower, so it should take longer to hit something which
|
||||||
// can result in changing our target.
|
// can result in changing our target.
|
||||||
@ -1258,6 +1281,10 @@ void SkiddingAI::handleItems(const float dt)
|
|||||||
|
|
||||||
case PowerupManager::POWERUP_PLUNGER:
|
case PowerupManager::POWERUP_PLUNGER:
|
||||||
{
|
{
|
||||||
|
// Do not destroy your own shield
|
||||||
|
if(m_kart->getShieldTime() > min_bubble_time) // if the kart has a shield, do not break it by using a swatter.
|
||||||
|
break;
|
||||||
|
|
||||||
// Leave more time after a plunger, since it will take some
|
// Leave more time after a plunger, since it will take some
|
||||||
// time before a plunger effect becomes obvious.
|
// time before a plunger effect becomes obvious.
|
||||||
if(m_time_since_last_shot < 5.0f) break;
|
if(m_time_since_last_shot < 5.0f) break;
|
||||||
@ -1311,6 +1338,9 @@ void SkiddingAI::handleItems(const float dt)
|
|||||||
{
|
{
|
||||||
// Squared distance for which the swatter works
|
// Squared distance for which the swatter works
|
||||||
float d2 = m_kart->getKartProperties()->getSwatterDistance2();
|
float d2 = m_kart->getKartProperties()->getSwatterDistance2();
|
||||||
|
// if the kart has a shield, do not break it by using a swatter.
|
||||||
|
if(m_kart->getShieldTime() > min_bubble_time)
|
||||||
|
break;
|
||||||
// Fire if the closest kart ahead or to the back is not already
|
// Fire if the closest kart ahead or to the back is not already
|
||||||
// squashed and close enough.
|
// squashed and close enough.
|
||||||
// FIXME: this can be improved on, since more than one kart might
|
// FIXME: this can be improved on, since more than one kart might
|
||||||
@ -1325,6 +1355,9 @@ void SkiddingAI::handleItems(const float dt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PowerupManager::POWERUP_RUBBERBALL:
|
case PowerupManager::POWERUP_RUBBERBALL:
|
||||||
|
// Do not destroy your own shield
|
||||||
|
if(m_kart->getShieldTime() > min_bubble_time) // if the kart has a shield, do not break it by using a swatter.
|
||||||
|
break;
|
||||||
// Perhaps some more sophisticated algorithm might be useful.
|
// Perhaps some more sophisticated algorithm might be useful.
|
||||||
// For now: fire if there is a kart ahead (which means that
|
// For now: fire if there is a kart ahead (which means that
|
||||||
// this kart is certainly not the first kart)
|
// this kart is certainly not the first kart)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "karts/kart_properties.hpp"
|
#include "karts/kart_properties.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
/** A static create function that does only create an explosion if
|
/** A static create function that does only create an explosion if
|
||||||
* the explosion happens to be close enough to affect the kart.
|
* the explosion happens to be close enough to affect the kart.
|
||||||
@ -37,7 +38,12 @@ ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart,
|
|||||||
bool direct_hit)
|
bool direct_hit)
|
||||||
{
|
{
|
||||||
if(kart->isInvulnerable()) return NULL;
|
if(kart->isInvulnerable()) return NULL;
|
||||||
|
/*else if(kart->isShielded() && !direct_hit) //How can I test this code ??
|
||||||
|
{
|
||||||
|
kart->decreaseShieldTime(0.0f); //Decreasing the shield time by the default value.
|
||||||
|
Log::verbose("ExlosionAnimation", "Decreasing shield \n");
|
||||||
|
return NULL;
|
||||||
|
}*/
|
||||||
float r = kart->getKartProperties()->getExplosionRadius();
|
float r = kart->getKartProperties()->getExplosionRadius();
|
||||||
|
|
||||||
// Ignore explosion that are too far away.
|
// Ignore explosion that are too far away.
|
||||||
@ -53,6 +59,12 @@ ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart,
|
|||||||
ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart)
|
ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart)
|
||||||
{
|
{
|
||||||
if(kart->isInvulnerable()) return NULL;
|
if(kart->isInvulnerable()) return NULL;
|
||||||
|
else if(kart->isShielded())
|
||||||
|
{
|
||||||
|
kart->decreaseShieldTime(0.0f) ; //decreasing the shieldtime by the default amount
|
||||||
|
Log::verbose("ExplosionAnimation", "Decreasing shield 2\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return new ExplosionAnimation(kart, kart->getXYZ(), /*direct hit*/true);
|
return new ExplosionAnimation(kart, kart->getXYZ(), /*direct hit*/true);
|
||||||
} // create
|
} // create
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "challenges/unlock_manager.hpp"
|
#include "challenges/unlock_manager.hpp"
|
||||||
#include "config/user_config.hpp"
|
#include "config/user_config.hpp"
|
||||||
#include "graphics/camera.hpp"
|
#include "graphics/camera.hpp"
|
||||||
|
#include "graphics/explosion.hpp"
|
||||||
#include "graphics/material_manager.hpp"
|
#include "graphics/material_manager.hpp"
|
||||||
#include "graphics/particle_emitter.hpp"
|
#include "graphics/particle_emitter.hpp"
|
||||||
#include "graphics/particle_kind.hpp"
|
#include "graphics/particle_kind.hpp"
|
||||||
@ -67,8 +68,9 @@
|
|||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "tracks/track_manager.hpp"
|
#include "tracks/track_manager.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
|
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||||
|
|
||||||
|
|
||||||
#include "graphics/explosion.hpp"
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||||
// Disable warning for using 'this' in base member initializer list
|
// Disable warning for using 'this' in base member initializer list
|
||||||
@ -511,7 +513,23 @@ void Kart::setPosition(int p)
|
|||||||
} // setPosition
|
} // setPosition
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
/** Sets that the view is blocked by a plunger. The duration depends on
|
||||||
|
* the difficulty, see KartPorperties getPlungerInFaceTime.
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
if(isShielded())
|
||||||
|
{
|
||||||
|
decreaseShieldTime(0.0f); //decrease the default amount of time
|
||||||
|
Log::verbose("Kart", "Decreasing shield, because of removing the plunger. \n");
|
||||||
|
}
|
||||||
|
} // blockViewWithPlunger
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
/** Returns a transform that will align an object with the kart: the heading
|
/** Returns a transform that will align an object with the kart: the heading
|
||||||
* and the pitch will be set appropriately. A custom pitch value can be
|
* and the pitch will be set appropriately. A custom pitch value can be
|
||||||
* specified in order to overwrite the terrain pitch (which would be used
|
* specified in order to overwrite the terrain pitch (which would be used
|
||||||
@ -942,6 +960,67 @@ bool Kart::isNearGround() const
|
|||||||
< stk_config->m_near_ground);
|
< stk_config->m_near_ground);
|
||||||
} // isNearGround
|
} // isNearGround
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Enables a kart shield protection for a certain amount of time.
|
||||||
|
*/
|
||||||
|
void Kart::setShieldTime(float t)
|
||||||
|
{
|
||||||
|
if(this->isShielded())
|
||||||
|
{
|
||||||
|
this->getAttachment()->setTimeLeft(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Returns true if the kart is protected by a shield.
|
||||||
|
*/
|
||||||
|
bool Kart::isShielded() const
|
||||||
|
{
|
||||||
|
if(getAttachment() != NULL)
|
||||||
|
return getAttachment()->getType() == Attachment::ATTACH_BUBBLEGUM_SHIELD;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
*Returns the remaining time the kart is protected by a shield.
|
||||||
|
*/
|
||||||
|
float Kart::getShieldTime() const
|
||||||
|
{
|
||||||
|
if(isShielded())
|
||||||
|
return getAttachment()->getTimeLeft();
|
||||||
|
else
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Decreases the kart's shield time.
|
||||||
|
* \param t The time substracted from the shield timer. If t == 0.0f, the default amout of time is substracted.
|
||||||
|
*/
|
||||||
|
void Kart::decreaseShieldTime(float t)
|
||||||
|
{
|
||||||
|
if(this->isShielded())
|
||||||
|
{
|
||||||
|
getAttachment()->setTimeLeft( getAttachment()->getTimeLeft() - t );
|
||||||
|
if(t == 0.0f)
|
||||||
|
{
|
||||||
|
getAttachment()->setTimeLeft( getAttachment()->getTimeLeft()
|
||||||
|
- stk_config->m_bubblegum_shield_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Let the kart drop a bubble gum, if the shield was not damaged.
|
||||||
|
//This is the default, whenever a powerup is used by a kart.
|
||||||
|
//It is turned off, if the shield was reduced below zero by a hit. (Or by intently damaging the shield.)
|
||||||
|
if(!this->isShielded())
|
||||||
|
m_bubble_drop = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Shows the star effect for a certain time.
|
/** Shows the star effect for a certain time.
|
||||||
* \param t Time to show the star effect for.
|
* \param t Time to show the star effect for.
|
||||||
@ -1009,7 +1088,9 @@ void Kart::update(float dt)
|
|||||||
|
|
||||||
// if its view is blocked by plunger, decrease remaining time
|
// if its view is blocked by plunger, decrease remaining time
|
||||||
if(m_view_blocked_by_plunger > 0) m_view_blocked_by_plunger -= dt;
|
if(m_view_blocked_by_plunger > 0) m_view_blocked_by_plunger -= dt;
|
||||||
|
//unblock the view if kart just became shielded
|
||||||
|
if(isShielded())
|
||||||
|
m_view_blocked_by_plunger = 0.0f;
|
||||||
// Decrease remaining invulnerability time
|
// Decrease remaining invulnerability time
|
||||||
if(m_invulnerable_time>0)
|
if(m_invulnerable_time>0)
|
||||||
{
|
{
|
||||||
@ -1085,6 +1166,7 @@ void Kart::update(float dt)
|
|||||||
// since use() can test if something needs to be switched on/off.
|
// since use() can test if something needs to be switched on/off.
|
||||||
m_powerup->use() ;
|
m_powerup->use() ;
|
||||||
World::getWorld()->onFirePressed(getController());
|
World::getWorld()->onFirePressed(getController());
|
||||||
|
m_bubble_drop = true;
|
||||||
}
|
}
|
||||||
// Reset the fire button
|
// Reset the fire button
|
||||||
m_controls.m_fire = 0;
|
m_controls.m_fire = 0;
|
||||||
@ -1268,6 +1350,13 @@ void Kart::setSquash(float time, float slowdown)
|
|||||||
{
|
{
|
||||||
if (isInvulnerable()) return;
|
if (isInvulnerable()) return;
|
||||||
|
|
||||||
|
if (isShielded())
|
||||||
|
{
|
||||||
|
decreaseShieldTime(stk_config->m_bubblegum_shield_time/2.0f);
|
||||||
|
Log::verbose("Kart", "Decreasing shield \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_attachment->getType()==Attachment::ATTACH_BOMB && time>0)
|
if(m_attachment->getType()==Attachment::ATTACH_BOMB && time>0)
|
||||||
{
|
{
|
||||||
ExplosionAnimation::create(this);
|
ExplosionAnimation::create(this);
|
||||||
|
@ -136,6 +136,8 @@ private:
|
|||||||
/** The torque to apply after hitting a bubble gum. */
|
/** The torque to apply after hitting a bubble gum. */
|
||||||
float m_bubblegum_torque;
|
float m_bubblegum_torque;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Bullet physics parameters
|
// Bullet physics parameters
|
||||||
// -------------------------
|
// -------------------------
|
||||||
btCompoundShape m_kart_chassis;
|
btCompoundShape m_kart_chassis;
|
||||||
@ -310,13 +312,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets that the view is blocked by a plunger. The duration depends on
|
/** Sets that the view is blocked by a plunger. The duration depends on
|
||||||
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
||||||
virtual void blockViewWithPlunger()
|
virtual void blockViewWithPlunger();
|
||||||
{
|
|
||||||
// Avoid that a plunger extends the plunger time
|
|
||||||
if(m_view_blocked_by_plunger<=0)
|
|
||||||
m_view_blocked_by_plunger =
|
|
||||||
m_kart_properties->getPlungerInFaceTime();
|
|
||||||
} // blockViewWithPlunger
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
/** Returns a bullet transform object located at the kart's position
|
/** Returns a bullet transform object located at the kart's position
|
||||||
and oriented in the direction the kart is going. Can be useful
|
and oriented in the direction the kart is going. Can be useful
|
||||||
@ -395,11 +391,25 @@ public:
|
|||||||
virtual void eliminate();
|
virtual void eliminate();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Makes a kart invulnerable for a certain amount of time. */
|
/** Makes a kart invulnerable for a certain amount of time. */
|
||||||
virtual void setInvulnerableTime(float t) { m_invulnerable_time = t; };
|
virtual void setInvulnerableTime(float t) { m_invulnerable_time = t; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns if the kart is invulnerable. */
|
/** Returns if the kart is invulnerable. */
|
||||||
virtual bool isInvulnerable() const { return m_invulnerable_time > 0; }
|
virtual bool isInvulnerable() const { return m_invulnerable_time > 0; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Enables a kart shield protection for a certain amount of time. */
|
||||||
|
virtual void setShieldTime(float t);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns if the kart is protected by a shield. */
|
||||||
|
virtual bool isShielded() const;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns the remaining time the kart is protected by a shield. */
|
||||||
|
virtual float getShieldTime() const;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Decreases the kart's shield time. */
|
||||||
|
//If t = 0.0f: decrease shield time by the default amount.
|
||||||
|
virtual void decreaseShieldTime(float t);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/** Sets the energy the kart has collected. */
|
/** Sets the energy the kart has collected. */
|
||||||
virtual void setEnergy(float val) { m_collected_energy = val; }
|
virtual void setEnergy(float val) { m_collected_energy = val; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -76,7 +76,7 @@ void KartWithStats::update(float dt)
|
|||||||
*/
|
*/
|
||||||
void KartWithStats::setKartAnimation(AbstractKartAnimation *ka)
|
void KartWithStats::setKartAnimation(AbstractKartAnimation *ka)
|
||||||
{
|
{
|
||||||
bool is_new = !getKartAnimation() && !isInvulnerable();
|
bool is_new = !getKartAnimation() && !isInvulnerable() && !isShielded();
|
||||||
Kart::setKartAnimation(ka);
|
Kart::setKartAnimation(ka);
|
||||||
// Nothing to count if it's not a new animation
|
// Nothing to count if it's not a new animation
|
||||||
if(!is_new) return;
|
if(!is_new) return;
|
||||||
|
@ -223,11 +223,15 @@ void Physics::update(float dt)
|
|||||||
// --------------------
|
// --------------------
|
||||||
// Only explode a bowling ball if the target is
|
// Only explode a bowling ball if the target is
|
||||||
// not invulnerable
|
// not invulnerable
|
||||||
|
AbstractKart* target_kart = p->getUserPointer(1)->getPointerKart();
|
||||||
if(p->getUserPointer(0)->getPointerFlyable()->getType()
|
if(p->getUserPointer(0)->getPointerFlyable()->getType()
|
||||||
!=PowerupManager::POWERUP_BOWLING ||
|
!=PowerupManager::POWERUP_BOWLING ||
|
||||||
!p->getUserPointer(1)->getPointerKart()->isInvulnerable() )
|
!target_kart->isInvulnerable() )
|
||||||
|
{
|
||||||
p->getUserPointer(0)->getPointerFlyable()
|
p->getUserPointer(0)->getPointerFlyable()
|
||||||
->hit(p->getUserPointer(1)->getPointerKart());
|
->hit(target_kart);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user