Files
stk-code_catmod/src/states_screens/feature_unlocked.cpp
2024-05-05 13:18:59 +08:00

781 lines
28 KiB
C++

//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/feature_unlocked.hpp"
#include <SColor.h>
#include "audio/music_manager.hpp"
#include "challenges/challenge_data.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/stk_config.hpp"
#include "config/user_config.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/sp/sp_base.hpp"
#include "graphics/sp/sp_mesh.hpp"
#include "graphics/sp/sp_mesh_buffer.hpp"
#include "graphics/sp/sp_mesh_node.hpp"
#include "graphics/sp/sp_texture_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"
#include "modes/overworld.hpp"
#include "modes/world.hpp"
#include "race/grand_prix_manager.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/state_manager.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <IAnimatedMeshSceneNode.h>
#include <ICameraSceneNode.h>
#include <ILightSceneNode.h>
#include <IMeshSceneNode.h>
#include <ISceneManager.h>
#include <iostream>
#ifndef SERVER_ONLY
#include <ge_main.hpp>
#endif
using namespace irr::core;
using namespace irr::gui;
using namespace irr::video;
const float ANIM_TO = 7.0f;
const int GIFT_EXIT_FROM = (int)ANIM_TO;
const int GIFT_EXIT_TO = GIFT_EXIT_FROM + 7;
// ============================================================================
#if 0
#pragma mark FeatureUnlockedCutScene::UnlockedThing
#endif
FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(const std::string &model,
const irr::core::stringw &msg)
{
m_unlocked_kart = NULL;
m_unlock_message = msg;
m_unlock_model = model;
m_curr_image = -1;
m_scale = 1.0f;
}
// ----------------------------------------------------------------------------
FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(const KartProperties* kart,
const irr::core::stringw &msg)
{
m_unlocked_kart = kart;
m_unlock_message = msg;
m_curr_image = -1;
m_scale = 1.0f;
} // UnlockedThing::UnlockedThing
// ----------------------------------------------------------------------------
FeatureUnlockedCutScene::UnlockedThing::UnlockedThing(irr::video::ITexture* pict,
float w, float h,
const irr::core::stringw &msg)
{
m_unlocked_kart = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
m_sp_pictures.push_back(SP::SPTextureManager::get()
->getTexture(pict->getName().getPtr(), NULL, true,
""/*container_id*/));
}
else
{
m_pictures.push_back(pict);
}
#endif
m_w = w;
m_h = h;
m_unlock_message = msg;
m_curr_image = -1;
m_scale = 1.0f;
} // UnlockedThing::UnlockedThing
// ----------------------------------------------------------------------------
FeatureUnlockedCutScene::UnlockedThing
::UnlockedThing(std::vector<irr::video::ITexture*> picts,
float w, float h,
const irr::core::stringw &msg)
{
m_unlocked_kart = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
for (auto* pict : picts)
{
m_sp_pictures.push_back(SP::SPTextureManager::get()
->getTexture(pict->getName().getPtr(), NULL, true,
""/*container_id*/));
}
}
else
#endif
{
m_pictures = picts;
}
m_pictures = picts;
m_w = w;
m_h = h;
m_unlock_message = msg;
m_curr_image = 0;
m_scale = 1.0f;
} // UnlockedThing::UnlockedThing
// ----------------------------------------------------------------------------
FeatureUnlockedCutScene::UnlockedThing::~UnlockedThing()
{
if (m_root_gift_node != NULL) irr_driver->removeNode(m_root_gift_node);
m_root_gift_node = NULL;
} // UnlockedThing::~UnlockedThing
// ============================================================================
#if 0
#pragma mark -
#pragma mark FeatureUnlockedCutScene
#endif
FeatureUnlockedCutScene::FeatureUnlockedCutScene()
: CutsceneScreen("cutscene.stkgui")
{
m_key_angle = 0;
} // FeatureUnlockedCutScene
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::loadedFromFile()
{
} // loadedFromFile
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::onCutsceneEnd()
{
m_unlocked_stuff.clearAndDeleteAll();
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
SP::SPTextureManager::get()->removeUnusedTextures();
}
#endif
m_all_kart_models.clearAndDeleteAll();
// update point count and the list of locked/unlocked stuff
PlayerManager::getCurrentPlayer()->computeActive();
}
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::
findWhatWasUnlocked(RaceManager::Difficulty difficulty,
std::vector<const ChallengeData*>& unlocked)
{
if (UserConfigParams::m_unlock_everything > 0)
return;
PlayerProfile *player = PlayerManager::getCurrentPlayer();
// The number of points is updated before this function is called
int points_before = player->getPointsBefore();
int points_now = player->getPoints();
std::vector<std::string> tracks;
std::vector<std::string> gps;
std::vector<std::string> karts;
player->computeActive();
unlock_manager->findWhatWasUnlocked(points_before, points_now, tracks, gps,
karts, unlocked);
for (unsigned int i = 0; i < tracks.size(); i++)
{
addUnlockedTrack(track_manager->getTrack(tracks[i]));
}
for (unsigned int i = 0; i < gps.size(); i++)
{
addUnlockedGP(grand_prix_manager->getGrandPrix(gps[i]));
}
for (unsigned int i = 0; i < karts.size(); i++)
{
addUnlockedKart(kart_properties_manager->getKart(karts[i]));
}
}
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::addTrophy(RaceManager::Difficulty difficulty,
bool is_grandprix)
{
core::stringw msg;
int gp_factor = is_grandprix ? GP_FACTOR : 1;
RaceManager::Difficulty max_unlocked_difficulty = RaceManager::DIFFICULTY_BEST;
if (PlayerManager::getCurrentPlayer()->isLocked("difficulty_best"))
max_unlocked_difficulty = RaceManager::DIFFICULTY_HARD;
switch (difficulty)
{
case RaceManager::DIFFICULTY_EASY:
msg = _("You completed the easy challenge! "
"Points earned on this level: %i/%i",
CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY]*gp_factor,
CHALLENGE_POINTS[max_unlocked_difficulty]*gp_factor);
break;
case RaceManager::DIFFICULTY_MEDIUM:
msg = _("You completed the intermediate challenge! "
"Points earned on this level: %i/%i",
CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM]*gp_factor,
CHALLENGE_POINTS[max_unlocked_difficulty]*gp_factor);
break;
case RaceManager::DIFFICULTY_HARD:
msg = _("You completed the difficult challenge! "
"Points earned on this level: %i/%i",
CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]*gp_factor,
CHALLENGE_POINTS[max_unlocked_difficulty]*gp_factor);
break;
case RaceManager::DIFFICULTY_BEST:
msg = _("You completed the SuperTux challenge! "
"Points earned on this level: %i/%i",
CHALLENGE_POINTS[RaceManager::DIFFICULTY_BEST]*gp_factor,
CHALLENGE_POINTS[max_unlocked_difficulty]*gp_factor);
break;
default:
assert(false);
}
std::string model;
switch (difficulty)
{
case RaceManager::DIFFICULTY_EASY:
model = file_manager->getAsset(FileManager::MODEL,"trophy_bronze.spm");
break;
case RaceManager::DIFFICULTY_MEDIUM:
model = file_manager->getAsset(FileManager::MODEL,"trophy_silver.spm");
break;
case RaceManager::DIFFICULTY_HARD:
model = file_manager->getAsset(FileManager::MODEL,"trophy_gold.spm");
break;
case RaceManager::DIFFICULTY_BEST:
model = file_manager->getAsset(FileManager::MODEL,"trophy_platinum.spm");
break;
default:
assert(false);
return;
}
m_unlocked_stuff.push_back( new UnlockedThing(model, msg) );
} // addTrophy
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::addUnlockedKart(const KartProperties* unlocked_kart)
{
if (unlocked_kart == NULL)
{
Log::error("FeatureUnlockedCutScene::addUnlockedKart",
"Unlocked kart does not exist");
return;
}
irr::core::stringw msg = _("You unlocked %s!", unlocked_kart->getName());
m_unlocked_stuff.push_back( new UnlockedThing(unlocked_kart, msg) );
} // addUnlockedKart
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::addUnlockedPicture(irr::video::ITexture* picture,
float w, float h,
const irr::core::stringw &msg)
{
if (picture == NULL)
{
Log::warn("FeatureUnlockedCutScene::addUnlockedPicture",
"Unlockable has no picture: %s",
core::stringc(msg.c_str()).c_str());
picture = irr_driver->getTexture(
file_manager->getAsset(FileManager::GUI_ICON,"main_help.png"));
}
m_unlocked_stuff.push_back( new UnlockedThing(picture, w, h, msg) );
} // addUnlockedPicture
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::addUnlockedPictures
(std::vector<irr::video::ITexture*> pictures,
float w, float h, irr::core::stringw msg)
{
assert(!pictures.empty());
m_unlocked_stuff.push_back( new UnlockedThing(pictures, w, h, msg) );
} // addUnlockedPictures
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::init()
{
m_global_time = 0.0f;
CutsceneWorld::setUseDuration(false);
const int unlockedStuffCount = m_unlocked_stuff.size();
if (unlockedStuffCount == 0)
Log::error("FeatureUnlockedCutScene::init",
"There is nothing in the unlock chest");
m_all_kart_models.clearAndDeleteAll();
for (int n=0; n<unlockedStuffCount; n++)
{
if (m_unlocked_stuff[n].m_unlock_model.size() > 0)
{
irr::scene::IMesh *mesh =
irr_driver->getMesh(m_unlocked_stuff[n].m_unlock_model);
m_unlocked_stuff[n].m_root_gift_node =
irr_driver->addMesh(mesh, "unlocked_model");
m_unlocked_stuff[n].m_scale = 0.7f;
}
else if (m_unlocked_stuff[n].m_unlocked_kart != NULL)
{
KartModel *kart_model =
m_unlocked_stuff[n].m_unlocked_kart->getKartModelCopy();
m_all_kart_models.push_back(kart_model);
m_unlocked_stuff[n].m_root_gift_node =
kart_model->attachModel(true, false);
m_unlocked_stuff[n].m_scale = 5.0f;
kart_model->setAnimation(KartModel::AF_DEFAULT);
// Set model current frame to "center"
kart_model->update(0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
#ifdef DEBUG
m_unlocked_stuff[n].m_root_gift_node->setName("unlocked kart");
#endif
}
#ifndef SERVER_ONLY
else if (!m_unlocked_stuff[n].m_sp_pictures.empty())
{
scene::IMesh* mesh = irr_driver->createTexturedQuadMesh(NULL,
m_unlocked_stuff[n].m_w, m_unlocked_stuff[n].m_h);
m_unlocked_stuff[n].m_root_gift_node =
irr_driver->getSceneManager()->addEmptySceneNode();
SP::SPMesh* spm = SP::convertEVTStandard(mesh);
m_unlocked_stuff[n].m_side_1 = irr_driver->addMesh(spm,
"unlocked_picture", m_unlocked_stuff[n].m_root_gift_node);
spm->getSPMeshBuffer(0)->uploadGLMesh();
spm->getSPMeshBuffer(0)->getSPTextures()[0] =
m_unlocked_stuff[n].m_sp_pictures[0];
spm->getSPMeshBuffer(0)->reloadTextureCompare();
spm->drop();
mesh = irr_driver->createTexturedQuadMesh(NULL,
m_unlocked_stuff[n].m_w, m_unlocked_stuff[n].m_h);
spm = SP::convertEVTStandard(mesh);
m_unlocked_stuff[n].m_side_2 = irr_driver->addMesh(spm,
"unlocked_picture", m_unlocked_stuff[n].m_root_gift_node);
m_unlocked_stuff[n].m_side_2->setRotation
(core::vector3df(0.0f, 180.0f, 0.0f));
spm->getSPMeshBuffer(0)->uploadGLMesh();
spm->getSPMeshBuffer(0)->getSPTextures()[0] =
m_unlocked_stuff[n].m_sp_pictures[0];
spm->getSPMeshBuffer(0)->reloadTextureCompare();
spm->drop();
#ifdef DEBUG
m_unlocked_stuff[n].m_root_gift_node->setName("unlocked track picture");
#endif
}
#endif
else if (!m_unlocked_stuff[n].m_pictures.empty())
{
#ifndef SERVER_ONLY
bool vk = (GE::getDriver()->getDriverType() == video::EDT_VULKAN);
if (vk)
GE::getGEConfig()->m_convert_irrlicht_mesh = true;
#endif
video::SMaterial m;
//m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m.BackfaceCulling = true;
m.setTexture(0, m_unlocked_stuff[n].m_pictures[0]);
m.AmbientColor = video::SColor(255, 255, 255, 255);
m.DiffuseColor = video::SColor(255, 255, 255, 255);
m.EmissiveColor = video::SColor(255, 255, 255, 255);
m.SpecularColor = video::SColor(255, 255, 255, 255);
m.GouraudShading = false;
m.Shininess = 0;
m.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
m.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
scene::IMesh* mesh =
irr_driver->createTexturedQuadMesh(&m,
m_unlocked_stuff[n].m_w,
m_unlocked_stuff[n].m_h);
m_unlocked_stuff[n].m_root_gift_node =
irr_driver->getSceneManager()->addEmptySceneNode();
irr_driver->setAllMaterialFlags(mesh);
m_unlocked_stuff[n].m_side_1 =
irr_driver->addMesh(mesh, "unlocked_picture",
m_unlocked_stuff[n].m_root_gift_node);
mesh->drop();
mesh = irr_driver->createTexturedQuadMesh(&m,
m_unlocked_stuff[n].m_w,
m_unlocked_stuff[n].m_h);
irr_driver->setAllMaterialFlags(mesh);
m_unlocked_stuff[n].m_side_2 =
irr_driver->addMesh(mesh, "unlocked_picture",
m_unlocked_stuff[n].m_root_gift_node);
m_unlocked_stuff[n].m_side_2
->setRotation(core::vector3df(0.0f, 180.0f, 0.0f));
mesh->drop();
#ifndef SERVER_ONLY
if (vk)
GE::getGEConfig()->m_convert_irrlicht_mesh = false;
#endif
#ifdef DEBUG
m_unlocked_stuff[n].m_root_gift_node->setName("unlocked track picture");
#endif
}
else
{
Log::error("FeatureUnlockedCutScene::init", "Malformed unlocked goody");
}
}
} // init
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::tearDown()
{
Screen::tearDown();
} // tearDown
// ----------------------------------------------------------------------------
//FIXME: doesn't go here...
template<typename T>
T keepInRange(T from, T to, T value)
{
if (value < from) return from;
if (value > to ) return to;
return value;
} // keepInRange
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::onUpdate(float dt)
{
m_global_time += dt;
const int unlockedStuffCount = m_unlocked_stuff.size();
// When the chest has opened but the items are not yet at their final position
if (m_global_time > GIFT_EXIT_FROM && m_global_time < GIFT_EXIT_TO)
{
float progress_factor = (m_global_time - GIFT_EXIT_FROM)
/ (GIFT_EXIT_TO - GIFT_EXIT_FROM);
float smoothed_progress_factor =
sinf((progress_factor - 0.5f)*M_PI)/2.0f + 0.5f;
for (int n=0; n<unlockedStuffCount; n++)
{
if (m_unlocked_stuff[n].m_root_gift_node == NULL) continue;
core::vector3df pos = m_unlocked_stuff[n].m_root_gift_node->getPosition();
pos.Y = sinf(smoothed_progress_factor*2.5f)*10.0f;
// when there are more than 1 unlocked items, make sure they each
// have their own path when they move
// and that they won't end offscreen in usual situations
// Put the trophy (item 0 in the unlocked stuff) in center
// For this, we exchange the position of the trophy with
// the item in the middle of the unlocked array.
int pos_value = (n == 0) ? unlockedStuffCount/2 :
(n == unlockedStuffCount/2) ? 0 : n;
float offset = (float) pos_value - unlockedStuffCount/2.0f + 0.5f;
offset *= (unlockedStuffCount <= 3) ? 1.4f :
(unlockedStuffCount <= 5) ? 1.2f : 1.0f;
pos.X += offset*dt;
pos.Z = smoothed_progress_factor * -4.0f;
m_unlocked_stuff[n].m_root_gift_node->setPosition(pos);
}
}
for (int n=0; n<unlockedStuffCount; n++)
{
if (m_unlocked_stuff[n].m_root_gift_node == NULL) continue;
irr::core::vector3df new_rot = m_unlocked_stuff[n].m_root_gift_node
->getRotation()
+ core::vector3df(0.0f, dt*25.0f, 0.0f);
m_unlocked_stuff[n].m_root_gift_node->setRotation(new_rot);
if (!m_unlocked_stuff[n].m_pictures.empty())
{
const int picture_count = (int)m_unlocked_stuff[n].m_pictures.size();
if (picture_count > 1)
{
const int previousTextureID = m_unlocked_stuff[n].m_curr_image;
const int textureID = int(m_global_time/1.2f) % picture_count;
if (textureID != previousTextureID)
{
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
SP::SPMesh* mesh = static_cast<SP::SPMeshNode*>
(m_unlocked_stuff[n].m_side_1)->getSPM();
assert(mesh->getMeshBufferCount() == 1);
SP::SPMeshBuffer* mb = mesh->getSPMeshBuffer(0);
mb->getSPTextures()[0] =
m_unlocked_stuff[n].m_sp_pictures[textureID];
mb->reloadTextureCompare();
mesh = static_cast<SP::SPMeshNode*>
(m_unlocked_stuff[n].m_side_2)->getSPM();
assert(mesh->getMeshBufferCount() == 1);
mb = mesh->getSPMeshBuffer(0);
mb->getSPTextures()[0] =
m_unlocked_stuff[n].m_sp_pictures[textureID];
mb->reloadTextureCompare();
m_unlocked_stuff[n].m_curr_image = textureID;
}
else
{
scene::IMesh* mesh =
static_cast<scene::IMeshSceneNode*>
(m_unlocked_stuff[n].m_side_1)->getMesh();
assert(mesh->getMeshBufferCount() == 1);
scene::IMeshBuffer* mb = mesh->getMeshBuffer(0);
SMaterial& m = mb->getMaterial();
m.setTexture(0, m_unlocked_stuff[n].m_pictures[textureID]);
// FIXME: this mesh is already associated with this
// node. I'm calling this to force irrLicht to refresh
// the display, now that Material has changed.
static_cast<scene::IMeshSceneNode*>
(m_unlocked_stuff[n].m_side_1)->setMesh(mesh);
m_unlocked_stuff[n].m_curr_image = textureID;
mesh = static_cast<scene::IMeshSceneNode*>
(m_unlocked_stuff[n].m_side_2)->getMesh();
assert(mesh->getMeshBufferCount() == 1);
mb = mesh->getMeshBuffer(0);
SMaterial& m2 = mb->getMaterial();
m2.setTexture(0, m_unlocked_stuff[n].m_pictures[textureID]);
// FIXME: this mesh is already associated with this
// node. I'm calling this to force irrLicht to refresh
// the display, now that Material has changed.
static_cast<scene::IMeshSceneNode*>
(m_unlocked_stuff[n].m_side_2)->setMesh(mesh);
m_unlocked_stuff[n].m_curr_image = textureID;
}
#endif
} // textureID != previousTextureID
} // if picture_count>1
} // if !m_unlocked_stuff[n].m_pictures.empty()
float scale = m_unlocked_stuff[n].m_scale;
if (m_global_time <= GIFT_EXIT_FROM)
scale *= 0.1f;
else if (m_global_time > GIFT_EXIT_FROM &&
m_global_time < GIFT_EXIT_TO)
{
scale *= ( (m_global_time - GIFT_EXIT_FROM)
/ (GIFT_EXIT_TO - GIFT_EXIT_FROM) );
}
m_unlocked_stuff[n].m_root_gift_node
->setScale(core::vector3df(scale, scale, scale));
} // for n<unlockedStuffCount
assert(m_unlocked_stuff.size() > 0);
const int w = irr_driver->getFrameSize().Width;
const int h = irr_driver->getFrameSize().Height;
const irr::video::SColor color(255, 255, 255, 255);
GUIEngine::getTitleFont()->draw(_("Challenge Completed"),
core::rect< s32 >( 0, 0, w, h/10 ),
color,
true/* center h */, true /* center v */ );
if (m_global_time > GIFT_EXIT_TO)
{
const irr::video::SColor color2(255, 0, 0, 0);
const int fontH = GUIEngine::getFontHeight();
const int MARGIN = 10;
int message_y = h - fontH*3 - MARGIN;
for (int n=unlockedStuffCount - 1; n>=0; n--)
{
GUIEngine::getFont()->draw(m_unlocked_stuff[n].m_unlock_message,
core::rect< s32 >( 0, message_y, w,
message_y + fontH ),
color2,
true /* center h */, true /* center v */ );
message_y -= (fontH + MARGIN);
}
}
} // onUpdate
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::addUnlockedTrack(const Track* track)
{
if (track == NULL)
{
Log::error("FeatureUnlockedCutScene::addUnlockedTrack",
"Unlocked track does not exist");
return;
}
const std::string sshot = track->getScreenshotFile();
core::stringw trackname = track->getName();
addUnlockedPicture( irr_driver->getTexture(sshot.c_str()), 4.0f, 3.0f,
_("You unlocked track %0", trackname));
}
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp)
{
std::vector<ITexture*> images;
core::stringw gpname;
if (gp == NULL)
{
Log::error("FeatureUnlockedCutScene::addUnlockedGP",
"Unlocked GP does not exist");
const std::string t_name =
file_manager->getAsset(FileManager::GUI_ICON, "main_help.png");
video::ITexture* WTF_image = irr_driver->getTexture(t_name);
images.push_back(WTF_image);
}
else
{
const std::vector<std::string> gptracks = gp->getTrackNames();
const int track_amount = (int)gptracks.size();
if (track_amount == 0)
{
Log::error("FeatureUnlockedCutScene::addUnlockedGP",
"Unlocked GP is empty");
video::ITexture* WTF_image =
irr_driver->getTexture( file_manager
->getAsset(FileManager::GUI_ICON,"main_help.png"));
images.push_back(WTF_image);
}
for (int t=0; t<track_amount; t++)
{
Track* track = track_manager->getTrack(gptracks[t]);
const std::string t_name =
track ? track->getScreenshotFile()
: file_manager->getAsset(FileManager::GUI_ICON, "main_help.png");
ITexture* tex = irr_driver->getTexture(t_name);
images.push_back(tex);
}
gpname = gp->getName();
}
addUnlockedPictures(images, 4.0f, 3.0f, _("You unlocked grand prix %0", gpname));
}
// ----------------------------------------------------------------------------
bool FeatureUnlockedCutScene::onEscapePressed()
{
continueButtonPressed();
return false; // continueButtonPressed already pop'ed the menu
} // onEscapePressed
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::continueButtonPressed()
{
if (m_global_time < GIFT_EXIT_TO)
{
// If animation was not over yet, the button is used to skip the animation
while (m_global_time < GIFT_EXIT_TO)
{
// simulate all the steps of the animation until we reach the end
onUpdate(0.4f);
World::getWorld()->updateWorld(stk_config->time2Ticks(0.4f));
}
}
else
{
((CutsceneWorld*)World::getWorld())->abortCutscene();
}
} // continueButtonPressed
// ----------------------------------------------------------------------------
void FeatureUnlockedCutScene::eventCallback(GUIEngine::Widget* widget,
const std::string& name,
const int playerID)
{
if (name == "continue")
{
continueButtonPressed();
}
} // eventCallback
// ----------------------------------------------------------------------------
MusicInformation* FeatureUnlockedCutScene::getInGameMenuMusic() const
{
MusicInformation* mi = stk_config->m_unlock_music;
return mi;
}