Applied a pending merge.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/battleAI@14617 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -6,11 +6,11 @@
|
||||
|
||||
<hard>
|
||||
<karts number="1"/>
|
||||
<requirements energy="16" time="135"/>
|
||||
<requirements energy="18" time="135"/>
|
||||
</hard>
|
||||
<medium>
|
||||
<karts number="1"/>
|
||||
<requirements energy="14" time="155"/>
|
||||
<requirements energy="15" time="155"/>
|
||||
</medium>
|
||||
<easy>
|
||||
<karts number="1"/>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
data/models/bubblegum_shield_nolok.b3d
Normal file
BIN
data/models/bubblegum_shield_nolok.b3d
Normal file
Binary file not shown.
BIN
data/models/bubblegum_shield_nolok.png
Normal file
BIN
data/models/bubblegum_shield_nolok.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
BIN
data/models/easter_egg_3.png
Normal file
BIN
data/models/easter_egg_3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 592 KiB |
@@ -11,7 +11,8 @@
|
||||
<material name="stk_mod_nitroBottle.png" />
|
||||
<material name="stk_mod_nitroLogo.png" compositing="additive" light="N" disable-z-write="Y" />
|
||||
|
||||
<material name="bubblegum_shield.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="bubblegum_shield_nolok.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="parachute.png" backface-culling="n" ignore="Y"/>
|
||||
<material name="zipper.png" light="N" zipper="Y"/>
|
||||
<material name="zipper_collect.png" light="N" zipper="Y"/>
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
w-multi=" 0 30 30 30 30 0 0 0 0 0" />
|
||||
<last w=" 0 30 10 90 60 0 10 60 60 0"
|
||||
w-multi=" 0 30 30 100 60 0 0 0 0 0" />
|
||||
<battle w=" 0 30 60 0 0 10 30 0 0 0"
|
||||
<battle w="10 30 60 0 0 10 30 0 0 0"
|
||||
w-multi=" 0 0 5 0 0 0 0 0 0 0" />
|
||||
<tuto w=" 0 0 0 0 0 0 0 0 0 0"
|
||||
w-multi=" 0 0 100 0 0 0 0 0 0 0" />
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
max: How much nitro a kart can store.
|
||||
-->
|
||||
<nitro engine-force="500" consumption="1" small-container="1" big-container="3"
|
||||
max-speed-increase="5" duration="1" fade-out-time="2" max="16"/>
|
||||
max-speed-increase="5" duration="1" fade-out-time="2" max="20"/>
|
||||
|
||||
<!-- Bubble gum data:
|
||||
time: How long the bubblegum lasts.
|
||||
@@ -487,7 +487,7 @@
|
||||
<!-- Parameters for the speed-weighted objects:
|
||||
a bigger value for strength-factor leads to the speed of the kart more quickly affecting
|
||||
the strength of the animation (up to a maximum value that corresponds to the original animation) -->
|
||||
<speed-weighted strength-factor="0.05" speed-factor="5.0"/>
|
||||
<speed-weighted strength-factor="0.05" speed-factor="1.0"/>
|
||||
|
||||
<!-- friction: slip used for bullet skidding. A high value
|
||||
(like 10000000) disables bullet skidding. -->
|
||||
|
||||
@@ -837,6 +837,17 @@ namespace GUIEngine
|
||||
}
|
||||
}
|
||||
|
||||
// Hack : on the first frame, irrlicht processes all events that have been queued
|
||||
// during the loading screen. So way until the second frame to start processing events.
|
||||
// (Events queues during the loading screens are likely the user clicking on the
|
||||
// frame to focus it, or similar, and should not be used as a game event)
|
||||
static int frame = 0;
|
||||
if (frame < 2)
|
||||
{
|
||||
frame++;
|
||||
if (frame == 2)
|
||||
GUIEngine::EventHandler::get()->startAcceptingEvents();
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ using namespace irr::gui;
|
||||
|
||||
EventHandler::EventHandler()
|
||||
{
|
||||
m_accept_events = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -56,6 +57,8 @@ EventHandler::~EventHandler()
|
||||
|
||||
bool EventHandler::OnEvent (const SEvent &event)
|
||||
{
|
||||
if (!m_accept_events && event.EventType != EET_LOG_TEXT_EVENT) return true;
|
||||
|
||||
// TO DEBUG HATS (when you don't actually have a hat)
|
||||
/*
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT)
|
||||
|
||||
@@ -55,6 +55,11 @@ namespace GUIEngine
|
||||
*/
|
||||
class EventHandler : public irr::IEventReceiver
|
||||
{
|
||||
/** This variable is used to ignore events during the initial load screen, so that
|
||||
a player cannot trigger an action by clicking on the window during loading screen
|
||||
for example */
|
||||
bool m_accept_events;
|
||||
|
||||
EventPropagation onGUIEvent(const irr::SEvent& event);
|
||||
EventPropagation onWidgetActivated(Widget* w, const int playerID);
|
||||
void navigateUp(const int playerID, Input::InputType type, const bool pressedDown);
|
||||
@@ -97,6 +102,8 @@ namespace GUIEngine
|
||||
/** singleton access */
|
||||
static EventHandler* get();
|
||||
static void deallocate();
|
||||
|
||||
void startAcceptingEvents() { m_accept_events = true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -59,9 +59,8 @@ int atoi_p(const char* val)
|
||||
|
||||
bool LayoutManager::convertToCoord(std::string& x, int* absolute /* out */, int* percentage /* out */)
|
||||
{
|
||||
bool is_number;
|
||||
int i = 0;
|
||||
if (!StringUtils::fromString<int>(x, i /* out */)) return false;
|
||||
if (!StringUtils::fromString<int>(x, i /* out */)) return false;
|
||||
|
||||
if( x[x.size()-1] == '%' ) // percentage
|
||||
{
|
||||
|
||||
@@ -275,13 +275,23 @@ irr::core::stringw Binding::getAsString() const
|
||||
}
|
||||
else
|
||||
{
|
||||
//I18N: to appear in input configuration screen, for gamepad axes
|
||||
if (m_range == Input::AR_HALF)
|
||||
{
|
||||
//I18N: to appear in input configuration screen, for gamepad axes
|
||||
s = _("Axis %d %s", m_id, (m_dir == Input::AD_NEGATIVE) ? L"-" : L"+");
|
||||
}
|
||||
else
|
||||
{
|
||||
irr::core::stringw inv = _("inverted");
|
||||
s = _("Axis %d %s", m_id, (m_dir == Input::AD_NEGATIVE) ? inv : L"");
|
||||
if(m_dir == Input::AD_NEGATIVE)
|
||||
{
|
||||
//I18N: to appear in input configuration screen, for gamepad axes
|
||||
s = _("Axis %d inverted", m_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
//I18N: to appear in input configuration screen, for gamepad axes
|
||||
s = _("Axis %d", m_id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -305,10 +305,15 @@ void* WiimoteManager::threadFuncWrapper(void *data)
|
||||
int WiimoteManager::askUserToConnectWiimotes()
|
||||
{
|
||||
new MessageDialog(
|
||||
_("Press the buttons 1+2 simultaneously on your wiimote to put "
|
||||
"it in discovery mode, then click on Yes."
|
||||
#ifdef WIN32
|
||||
_("Connect your wiimote to the Bluetooth manager, then click on Ok."
|
||||
"Detailed instructions at supertuxkart.net/Wiimote"),
|
||||
MessageDialog::MESSAGE_DIALOG_CONFIRM,
|
||||
#else
|
||||
_("Press the buttons 1+2 simultaneously on your wiimote to put "
|
||||
"it in discovery mode, then click on Ok."
|
||||
"Detailed instructions at supertuxkart.net/Wiimote"),
|
||||
#endif
|
||||
MessageDialog::MESSAGE_DIALOG_OK_CANCEL,
|
||||
new WiimoteDialogListener(), true);
|
||||
|
||||
return getNumberOfWiimotes();
|
||||
|
||||
@@ -53,7 +53,7 @@ Attachment::Attachment(AbstractKart* kart)
|
||||
m_bomb_sound = NULL;
|
||||
m_bubble_explode_sound = NULL;
|
||||
m_node_scale = 1.0f;
|
||||
|
||||
|
||||
// If we attach a NULL mesh, we get a NULL scene node back. So we
|
||||
// have to attach some kind of mesh, but make it invisible.
|
||||
m_node = irr_driver->addAnimatedMesh(
|
||||
@@ -222,7 +222,8 @@ void Attachment::clear()
|
||||
void Attachment::hitBanana(Item *item, int new_attachment)
|
||||
{
|
||||
//Bubble gum shield effect:
|
||||
if(m_type == ATTACH_BUBBLEGUM_SHIELD)
|
||||
if(m_type == ATTACH_BUBBLEGUM_SHIELD ||
|
||||
m_type == ATTACH_NOLOK_BUBBLEGUM_SHIELD)
|
||||
{
|
||||
m_time_left = 0.0f;
|
||||
return;
|
||||
@@ -387,10 +388,14 @@ void Attachment::update(float dt)
|
||||
if(m_type==ATTACH_NOTHING) return;
|
||||
m_time_left -=dt;
|
||||
|
||||
if (m_node_scale < 1.0f)
|
||||
|
||||
bool is_shield = (m_type == ATTACH_BUBBLEGUM_SHIELD|| m_type == ATTACH_NOLOK_BUBBLEGUM_SHIELD);
|
||||
float m_wanted_node_scale = is_shield ? std::max(1.0f, m_kart->getHighestPoint()*1.1f) : 1.0f;
|
||||
|
||||
if (m_node_scale < m_wanted_node_scale)
|
||||
{
|
||||
m_node_scale += dt*1.5f;
|
||||
if (m_node_scale > 1.0f) m_node_scale = 1.0f;
|
||||
if (m_node_scale > m_wanted_node_scale) m_node_scale = m_wanted_node_scale;
|
||||
m_node->setScale(core::vector3df(m_node_scale,m_node_scale,m_node_scale));
|
||||
}
|
||||
|
||||
@@ -456,6 +461,7 @@ void Attachment::update(float dt)
|
||||
// Nothing to do for tinytux, this is all handled in EmergencyAnimation
|
||||
break;
|
||||
case ATTACH_BUBBLEGUM_SHIELD:
|
||||
case ATTACH_NOLOK_BUBBLEGUM_SHIELD:
|
||||
if (m_time_left < 0)
|
||||
{
|
||||
m_time_left = 0.0f;
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
ATTACH_NOLOKS_SWATTER,
|
||||
ATTACH_TINYTUX,
|
||||
ATTACH_BUBBLEGUM_SHIELD,
|
||||
ATTACH_NOLOK_BUBBLEGUM_SHIELD,
|
||||
ATTACH_MAX,
|
||||
ATTACH_NOTHING
|
||||
};
|
||||
|
||||
@@ -54,6 +54,7 @@ static const initAttachmentType iat[]=
|
||||
{Attachment::ATTACH_NOLOKS_SWATTER, "swatter_nolok.b3d", "swatter-icon.png" },
|
||||
{Attachment::ATTACH_TINYTUX, "reset-button.b3d", "reset-attach-icon.png" },
|
||||
{Attachment::ATTACH_BUBBLEGUM_SHIELD, "bubblegum_shield.b3d", "shield-icon.png" },
|
||||
{Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, "bubblegum_shield_nolok.b3d", "shield-icon.png" },
|
||||
{Attachment::ATTACH_MAX, "", "" },
|
||||
};
|
||||
|
||||
|
||||
@@ -302,13 +302,29 @@ void Powerup::use()
|
||||
|
||||
if(!m_owner->isShielded()) //if the previous shield had been used up.
|
||||
{
|
||||
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
|
||||
stk_config->m_bubblegum_shield_time);
|
||||
if (m_owner->getIdent() == "nolok")
|
||||
{
|
||||
m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD,
|
||||
stk_config->m_bubblegum_shield_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
|
||||
stk_config->m_bubblegum_shield_time);
|
||||
}
|
||||
}
|
||||
else // using a bubble gum while still having a shield
|
||||
{
|
||||
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
|
||||
stk_config->m_bubblegum_shield_time + m_owner->getShieldTime());
|
||||
if (m_owner->getIdent() == "nolok")
|
||||
{
|
||||
m_owner->getAttachment()->set(Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD,
|
||||
stk_config->m_bubblegum_shield_time + m_owner->getShieldTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_owner->getAttachment()->set(Attachment::ATTACH_BUBBLEGUM_SHIELD,
|
||||
stk_config->m_bubblegum_shield_time + m_owner->getShieldTime());
|
||||
}
|
||||
}
|
||||
|
||||
m_sound_use = sfx_manager->createSoundSource("inflate");//Extraordinary. Usually sounds are set in Powerup::set()
|
||||
|
||||
@@ -727,9 +727,6 @@ bool RubberBall::hit(AbstractKart* kart, PhysicalObject* object)
|
||||
if(kart && kart->isShielded())
|
||||
{
|
||||
kart->decreaseShieldTime();
|
||||
//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);
|
||||
|
||||
@@ -53,6 +53,7 @@ AbstractKart::AbstractKart(const std::string& ident,
|
||||
m_kart_width = m_kart_model->getWidth();
|
||||
m_kart_height = m_kart_model->getHeight();
|
||||
m_kart_length = m_kart_model->getLength();
|
||||
m_kart_highest_point = m_kart_model->getHighestPoint();
|
||||
m_wheel_graphics_position = m_kart_model->getWheelsGraphicsPosition();
|
||||
m_nitro_emitter_position = m_kart_model->getNitroEmittersPositon();
|
||||
m_has_nitro_emitter = m_kart_model->hasNitroEmitters();
|
||||
|
||||
@@ -51,6 +51,8 @@ private:
|
||||
float m_kart_width;
|
||||
/** Height of the kart, copy of the data from KartModel. */
|
||||
float m_kart_height;
|
||||
/** Coordinate on up axis */
|
||||
float m_kart_highest_point;
|
||||
/** The position of all four wheels in the 3d model */
|
||||
const Vec3* m_wheel_graphics_position;
|
||||
/** The position of all nitro emitters in the 3d model */
|
||||
@@ -150,6 +152,9 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the width of the kart. */
|
||||
float getKartWidth() const {return m_kart_width; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the highest point of the kart (coordinate on up axis) */
|
||||
float getHighestPoint() const { return m_kart_highest_point; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this kart has no wheels. */
|
||||
bool isWheeless() const;
|
||||
|
||||
@@ -38,17 +38,18 @@ ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart,
|
||||
bool direct_hit)
|
||||
{
|
||||
if(kart->isInvulnerable()) return NULL;
|
||||
else if(kart->isShielded())
|
||||
{
|
||||
kart->decreaseShieldTime();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
float r = kart->getKartProperties()->getExplosionRadius();
|
||||
|
||||
// Ignore explosion that are too far away.
|
||||
if(!direct_hit && pos.distance2(kart->getXYZ())>r*r) return NULL;
|
||||
|
||||
if(kart->isShielded())
|
||||
{
|
||||
kart->decreaseShieldTime();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new ExplosionAnimation(kart, pos, direct_hit);
|
||||
} // create
|
||||
|
||||
|
||||
@@ -839,8 +839,8 @@ void Kart::finishedRace(float time)
|
||||
RaceGUIBase* m = World::getWorld()->getRaceGUI();
|
||||
if(m)
|
||||
{
|
||||
m->addMessage((getPosition() == 2 ? _("You won the race!") : _("You finished the race!")) ,
|
||||
this, 2.0f);
|
||||
if (getPosition() == 2)
|
||||
m->addMessage(_("You won the race!"), this, 2.0f);
|
||||
}
|
||||
}
|
||||
else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES ||
|
||||
@@ -984,9 +984,15 @@ void Kart::setShieldTime(float t)
|
||||
bool Kart::isShielded() const
|
||||
{
|
||||
if(getAttachment() != NULL)
|
||||
return getAttachment()->getType() == Attachment::ATTACH_BUBBLEGUM_SHIELD;
|
||||
{
|
||||
Attachment::AttachmentType type = getAttachment()->getType();
|
||||
return type == Attachment::ATTACH_BUBBLEGUM_SHIELD ||
|
||||
type == Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // isShielded
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -249,6 +249,7 @@ KartModel* KartModel::makeCopy()
|
||||
km->m_kart_width = m_kart_width;
|
||||
km->m_kart_length = m_kart_length;
|
||||
km->m_kart_height = m_kart_height;
|
||||
km->m_kart_highest_point = m_kart_highest_point;
|
||||
km->m_mesh = m_mesh;
|
||||
km->m_model_filename = m_model_filename;
|
||||
km->m_animation_speed = m_animation_speed;
|
||||
@@ -421,6 +422,8 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
Vec3 kart_min, kart_max;
|
||||
MeshTools::minMax3D(m_mesh->getMesh(m_animation_frame[AF_STRAIGHT]), &kart_min, &kart_max);
|
||||
|
||||
m_kart_highest_point = kart_max.getY();
|
||||
|
||||
// Load the speed weighted object models. We need to do that now because it can affect the dimensions of the kart
|
||||
for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
|
||||
{
|
||||
@@ -435,7 +438,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
|
||||
// Update min/max
|
||||
Vec3 obj_min, obj_max;
|
||||
MeshTools::minMax3D(obj.m_model, &obj_min, &obj_max);
|
||||
MeshTools::minMax3D(obj.m_model, &obj_min, &obj_max);
|
||||
obj_min += obj.m_position;
|
||||
obj_max += obj.m_position;
|
||||
kart_min.min(obj_min);
|
||||
|
||||
@@ -166,6 +166,7 @@ private:
|
||||
float m_kart_width; /**< Width of kart. */
|
||||
float m_kart_length; /**< Length of kart. */
|
||||
float m_kart_height; /**< Height of kart. */
|
||||
float m_kart_highest_point; /**< Coordinate on up axis */
|
||||
/** True if this is the master copy, managed by KartProperties. This
|
||||
* is mainly used for debugging, e.g. the master copies might not have
|
||||
* anything attached to it etc. */
|
||||
@@ -263,6 +264,9 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the height of the kart. */
|
||||
float getHeight () const {return m_kart_height; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Coordoinate on up axis */
|
||||
float getHighestPoint () const { return m_kart_highest_point; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Enables- or disables the end animation. */
|
||||
void setAnimation(AnimationFrameType type);
|
||||
|
||||
@@ -115,6 +115,16 @@ void Skidding::updateSteering(float steer, float dt)
|
||||
m_visual_rotation = f;
|
||||
}
|
||||
break;
|
||||
case SKID_BREAK:
|
||||
m_real_steering = steer;
|
||||
if (m_visual_rotation > 0.05f) m_visual_rotation -= 0.05f;
|
||||
else if (m_visual_rotation < -0.05f) m_visual_rotation += 0.05f;
|
||||
else
|
||||
{
|
||||
m_visual_rotation = 0;
|
||||
reset();
|
||||
}
|
||||
break;
|
||||
case SKID_ACCUMULATE_RIGHT:
|
||||
{
|
||||
float f = (1.0f+steer)*0.5f; // map [-1,1] --> [0, 1]
|
||||
@@ -139,6 +149,8 @@ void Skidding::updateSteering(float steer, float dt)
|
||||
m_visual_rotation = m_skid_visual * m_real_steering;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} // switch m_skid_state
|
||||
|
||||
} // updateSteering
|
||||
@@ -160,6 +172,7 @@ float Skidding::getSteeringWhenSkidding(float steering) const
|
||||
case SKID_OLD: assert(false); break;
|
||||
case SKID_SHOW_GFX_LEFT:
|
||||
case SKID_SHOW_GFX_RIGHT:
|
||||
case SKID_BREAK:
|
||||
case SKID_NONE: return steering;
|
||||
break;
|
||||
case SKID_ACCUMULATE_RIGHT:
|
||||
@@ -201,7 +214,9 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
// No skidding backwards or while stopped
|
||||
if(m_kart->getSpeed() < 0.001f)
|
||||
{
|
||||
reset();
|
||||
m_skid_state = SKID_BREAK;
|
||||
m_kart->getKartGFX()->setCreationRateAbsolute(KartGFX::KGFX_SKIDL, 0);
|
||||
m_kart->getKartGFX()->setCreationRateAbsolute(KartGFX::KGFX_SKIDR, 0);
|
||||
}
|
||||
|
||||
m_skid_bonus_ready = false;
|
||||
@@ -337,6 +352,11 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
#endif
|
||||
m_skid_time = 0; // fallthrough
|
||||
}
|
||||
case SKID_BREAK:
|
||||
{
|
||||
updateSteering(steering, dt);
|
||||
break;
|
||||
}
|
||||
case SKID_ACCUMULATE_LEFT:
|
||||
case SKID_ACCUMULATE_RIGHT:
|
||||
{
|
||||
|
||||
@@ -81,10 +81,11 @@ public:
|
||||
* SKID_ACCUMULATE_RIGHT: Similar for turning right
|
||||
* SKID_SHOW_GFX_LEFT: Shows the gfx, while the bonus is active,
|
||||
* and the kart was turning left.
|
||||
* SKID_SHOW_GFX_RIGHT: Similar for turning right. */
|
||||
* SKID_SHOW_GFX_RIGHT: Similar for turning right.
|
||||
* SKID_BREAK: Skidding was stopped without bonus */
|
||||
enum SkidState {SKID_OLD, SKID_NONE, SKID_ACCUMULATE_LEFT,
|
||||
SKID_ACCUMULATE_RIGHT, SKID_SHOW_GFX_LEFT,
|
||||
SKID_SHOW_GFX_RIGHT} ;
|
||||
SKID_SHOW_GFX_RIGHT, SKID_BREAK} ;
|
||||
|
||||
private:
|
||||
/** The current skidding state. */
|
||||
|
||||
@@ -43,6 +43,7 @@ FollowTheLeaderRace::FollowTheLeaderRace() : LinearWorld()
|
||||
stk_config->m_leader_time_per_kart*race_manager->getNumberOfKarts();
|
||||
m_use_highscores = false; // disable high scores
|
||||
setClockMode(WorldStatus::CLOCK_COUNTDOWN, m_leader_intervals[0]);
|
||||
m_is_over_delay = 5.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -77,6 +78,8 @@ void FollowTheLeaderRace::reset()
|
||||
stk_config->m_leader_time_per_kart*race_manager->getNumberOfKarts();
|
||||
WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN,
|
||||
m_leader_intervals[0]);
|
||||
|
||||
m_is_over_delay = 2.0f;
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -145,15 +148,18 @@ void FollowTheLeaderRace::countdownReachedZero()
|
||||
|
||||
// Move any camera for this kart to the leader, facing backwards,
|
||||
// so that the eliminated player has something to watch.
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
if (race_manager->getNumPlayers() > 1)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
if(camera->getKart()==kart)
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
{
|
||||
camera->setMode(Camera::CM_LEADER_MODE);
|
||||
camera->setKart(getKart(0));
|
||||
}
|
||||
} // for i<number of cameras
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
if(camera->getKart()==kart)
|
||||
{
|
||||
camera->setMode(Camera::CM_LEADER_MODE);
|
||||
camera->setKart(getKart(0));
|
||||
}
|
||||
} // for i<number of cameras
|
||||
}
|
||||
} // if kart to eliminate exists
|
||||
|
||||
// almost over, use fast music
|
||||
@@ -207,7 +213,23 @@ void FollowTheLeaderRace::countdownReachedZero()
|
||||
*/
|
||||
bool FollowTheLeaderRace::isRaceOver()
|
||||
{
|
||||
return getCurrentNumKarts()==2 || getCurrentNumPlayers()==0;
|
||||
bool is_over = (getCurrentNumKarts()==2 || getCurrentNumPlayers()==0);
|
||||
if (is_over)
|
||||
{
|
||||
if (m_is_over_delay < 0.0f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_is_over_delay -= GUIEngine::getLatestDt();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // isRaceOver
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -28,6 +28,7 @@ class FollowTheLeaderRace : public LinearWorld
|
||||
{
|
||||
private:
|
||||
std::vector<float> m_leader_intervals; // time till elimination in follow leader
|
||||
float m_is_over_delay; //!< A timer used before terminating the race
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -29,19 +29,20 @@ using namespace GUIEngine;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
|
||||
MessageDialog::MessageDialog(irr::core::stringw msg, MessageDialogType type, IConfirmDialogListener* listener, bool own_listener) :
|
||||
MessageDialog::MessageDialog(const irr::core::stringw &msg, MessageDialogType type,
|
||||
IConfirmDialogListener* listener, bool own_listener) :
|
||||
ModalDialog(0.6f, 0.6f)
|
||||
{
|
||||
doInit(msg, type, listener, own_listener);
|
||||
}
|
||||
} // MessageDialog(stringw, type, listener, own_listener)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
|
||||
MessageDialog::MessageDialog(irr::core::stringw msg) :
|
||||
MessageDialog::MessageDialog(const irr::core::stringw &msg) :
|
||||
ModalDialog(0.6f, 0.6f)
|
||||
{
|
||||
doInit(msg, MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
|
||||
}
|
||||
} // MessageDialog(stringw)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -53,11 +54,11 @@ MessageDialog::~MessageDialog()
|
||||
{
|
||||
World::getWorld()->scheduleUnpause();
|
||||
}
|
||||
}
|
||||
} // ~MessageDialog
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
|
||||
void MessageDialog::doInit(irr::core::stringw msg, MessageDialogType type,
|
||||
void MessageDialog::doInit(const irr::core::stringw &msg, MessageDialogType type,
|
||||
IConfirmDialogListener* listener, bool own_listener)
|
||||
{
|
||||
if (StateManager::get()->getGameState() == GUIEngine::GAME)
|
||||
@@ -85,6 +86,12 @@ void MessageDialog::doInit(irr::core::stringw msg, MessageDialogType type,
|
||||
cancelbtn->setText(_("OK"));
|
||||
cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
}
|
||||
else if (type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL)
|
||||
{
|
||||
// In case of a OK_CANCEL dialog, change the text from 'Yes' to 'Ok'
|
||||
ButtonWidget* yesbtn = getWidget<ButtonWidget>("confirm");
|
||||
yesbtn->setText(_("OK"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -62,13 +62,15 @@ public:
|
||||
virtual void onDialogUpdate(float dt) {}
|
||||
};
|
||||
|
||||
enum MessageDialogType { MESSAGE_DIALOG_OK, MESSAGE_DIALOG_CONFIRM };
|
||||
enum MessageDialogType { MESSAGE_DIALOG_OK, MESSAGE_DIALOG_CONFIRM,
|
||||
MESSAGE_DIALOG_OK_CANCEL };
|
||||
|
||||
private:
|
||||
|
||||
IConfirmDialogListener* m_listener;
|
||||
bool m_own_listener;
|
||||
void doInit(irr::core::stringw msg, MessageDialogType type, IConfirmDialogListener* listener, bool own_listener);
|
||||
void doInit(const irr::core::stringw &msg, MessageDialogType type,
|
||||
IConfirmDialogListener* listener, bool own_listener);
|
||||
|
||||
public:
|
||||
|
||||
@@ -78,13 +80,14 @@ public:
|
||||
* \param If set to true, 'listener' will be owned by this dialog and deleted
|
||||
* along with the dialog.
|
||||
*/
|
||||
MessageDialog(irr::core::stringw msg, MessageDialogType type, IConfirmDialogListener* listener, bool delete_listener);
|
||||
MessageDialog(const irr::core::stringw &msg, MessageDialogType type,
|
||||
IConfirmDialogListener* listener, bool delete_listener);
|
||||
|
||||
/**
|
||||
* Variant of MessageDialog where cancelling is not possible (i.e. just shows a message box with OK)
|
||||
* \param msg Message to display in the dialog
|
||||
*/
|
||||
MessageDialog(irr::core::stringw msg);
|
||||
MessageDialog(const irr::core::stringw &msg);
|
||||
|
||||
|
||||
~MessageDialog();
|
||||
|
||||
@@ -728,6 +728,8 @@ void RaceGUIBase::drawGlobalReadySetGo()
|
||||
|
||||
if (race_manager->getCoinTarget() > 0)
|
||||
font->draw(_("Collect nitro!"), pos, color, true, true);
|
||||
else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||
font->draw(_("Follow the leader!"), pos, color, true, true);
|
||||
else
|
||||
font->draw(m_string_go.c_str(), pos, color, true, true);
|
||||
}
|
||||
|
||||
@@ -389,7 +389,21 @@ void Track::loadTrackInfo()
|
||||
|
||||
std::string dir = StringUtils::getPath(m_filename);
|
||||
std::string easter_name = dir+"/easter_eggs.xml";
|
||||
m_has_easter_eggs = file_manager->fileExists(easter_name);
|
||||
|
||||
XMLNode *easter = file_manager->createXMLTree(easter_name);
|
||||
|
||||
if(easter)
|
||||
{
|
||||
for(unsigned int i=0; i<easter->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *eggs = easter->getNode(i);
|
||||
if(eggs->getNumNodes() > 0)
|
||||
{
|
||||
m_has_easter_eggs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // loadTrackInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user