stk-code_catmod/src/states_screens/arenas_screen.cpp
2018-03-23 20:20:09 +08:00

359 lines
13 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Marianne Gagnon
//
// 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 "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "io/file_manager.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/arenas_screen.hpp"
#include "states_screens/track_info_screen.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/random_generator.hpp"
#include "utils/translation.hpp"
#include <iostream>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr::video;
static const char ALL_ARENA_GROUPS_ID[] = "all";
// -----------------------------------------------------------------------------
ArenasScreen::ArenasScreen() : Screen("arenas.stkgui")
{
}
// -----------------------------------------------------------------------------
void ArenasScreen::loadedFromFile()
{
}
// -----------------------------------------------------------------------------
void ArenasScreen::beforeAddingWidget()
{
// Dynamically add tabs
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
assert( tabs != NULL );
tabs->clearAllChildren();
bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
const std::vector<std::string>& groups = track_manager->getAllArenaGroups(soccer_mode);
const int group_amount = (int)groups.size();
if (group_amount > 1)
{
//I18N: name of the tab that will show arenas from all groups
tabs->addTextChild( _("All"), ALL_ARENA_GROUPS_ID );
}
// Make group names being picked up by gettext
#define FOR_GETTEXT_ONLY(x)
//I18N: arena group name
FOR_GETTEXT_ONLY( _("standard") )
//I18N: arena group name
FOR_GETTEXT_ONLY( _("Add-Ons") )
// add others after
for (int n=0; n<group_amount; n++)
{
// try to translate the group name
tabs->addTextChild( _(groups[n].c_str()), groups[n] );
}
int num_of_arenas=0;
for (unsigned int n=0; n<track_manager->getNumberOfTracks(); n++) //iterate through tracks to find how many are arenas
{
Track* temp = track_manager->getTrack(n);
if (soccer_mode)
{
if(temp->isSoccer() && (temp->hasNavMesh() ||
race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode))
num_of_arenas++;
}
else
{
if(temp->isArena() && (temp->hasNavMesh() ||
race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode))
num_of_arenas++;
}
}
DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks");
assert( tracks_widget != NULL );
tracks_widget->setItemCountHint(num_of_arenas+1); //set the item hint to that number to prevent weird formatting
}
// -----------------------------------------------------------------------------
void ArenasScreen::init()
{
m_unsupported_arena.clear();
Screen::init();
buildTrackList();
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tracks");
// select something by default for the game master
assert( w != NULL );
w->setSelection(w->getItems()[0].m_code_name, PLAYER_ID_GAME_MASTER, true);
} // init
// -----------------------------------------------------------------------------
void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
if (name == "tracks")
{
DynamicRibbonWidget* w2 = dynamic_cast<DynamicRibbonWidget*>(widget);
if (w2 == NULL) return;
const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (UserConfigParams::logGUI())
Log::info("ArenasScreen", "Clicked on arena %s", selection.c_str());
if (selection == "random_track")
{
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
assert( tabs != NULL );
bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
std::vector<int> curr_group;
if (tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER) == ALL_ARENA_GROUPS_ID)
{
const std::vector<std::string>& groups = track_manager->getAllArenaGroups();
for (unsigned int i = 0; i < groups.size(); i++)
{
const std::vector<int>& tmp_group = track_manager->getArenasInGroup(groups[i], soccer_mode);
// Append to our main vector
curr_group.insert(curr_group.end(), tmp_group.begin(), tmp_group.end());
}
} // if on tab "all"
else
{
curr_group = track_manager->getArenasInGroup(
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER), soccer_mode );
}
// Remove unsupported arena
if (m_unsupported_arena.size() > 0)
{
for (std::set<int>::iterator it = m_unsupported_arena.begin();
it != m_unsupported_arena.end(); ++it)
{
curr_group.erase(std::remove(curr_group.begin(),
curr_group.end(), *it), curr_group.end());
}
}
RandomGenerator random;
const int randomID = random.get((int)curr_group.size());
Track* clicked_track = track_manager->getTrack( curr_group[randomID] );
if (clicked_track != NULL)
{
TrackInfoScreen::getInstance()->setTrack(clicked_track);
TrackInfoScreen::getInstance()->push();
}
}
else if (selection == "locked")
{
unlock_manager->playLockSound();
}
else if (selection == RibbonWidget::NO_ITEM_ID)
{
}
else
{
Track* clicked_track = track_manager->getTrack(selection);
if (clicked_track != NULL)
{
TrackInfoScreen::getInstance()->setTrack(clicked_track);
TrackInfoScreen::getInstance()->push();
} // clickedTrack != NULL
} // if random_track
}
else if (name == "trackgroups")
{
buildTrackList();
}
else if (name == "back")
{
StateManager::get()->escapePressed();
}
} // eventCallback
// ------------------------------------------------------------------------------------------------------
void ArenasScreen::buildTrackList()
{
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tracks");
assert( w != NULL );
// Re-build track list everytime (accounts for locking changes, etc.)
w->clearItems();
RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups");
assert( tabs != NULL );
const std::string curr_group_name = tabs->getSelectionIDString(0);
bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
bool arenas_have_navmesh = false;
if (curr_group_name == ALL_ARENA_GROUPS_ID)
{
const int track_amount = (int)track_manager->getNumberOfTracks();
for (int n=0; n<track_amount; n++)
{
Track* curr = track_manager->getTrack(n);
if (soccer_mode)
{
if(curr->isSoccer() && curr->hasNavMesh() && !arenas_have_navmesh)
arenas_have_navmesh = true;
if(!curr->isSoccer() ||
(!(curr->hasNavMesh() ||
race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode)))
{
if (curr->isSoccer())
m_unsupported_arena.insert(n);
continue;
}
}
else
{
if(curr->isArena() && curr->hasNavMesh() && !arenas_have_navmesh)
arenas_have_navmesh = true;
if(!curr->isArena() ||
(!(curr->hasNavMesh() ||
race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode)))
{
if (curr->isArena())
m_unsupported_arena.insert(n);
continue;
}
}
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );
}
else
{
w->addItem( translations->fribidize(curr->getName()), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
}
}
}
else
{
const std::vector<int>& currArenas = track_manager->getArenasInGroup(curr_group_name, soccer_mode);
const int track_amount = (int)currArenas.size();
for (int n=0; n<track_amount; n++)
{
Track* curr = track_manager->getTrack(currArenas[n]);
if (soccer_mode)
{
if(curr->isSoccer() && curr->hasNavMesh() && !arenas_have_navmesh)
arenas_have_navmesh = true;
if(!curr->isSoccer() ||
(!(curr->hasNavMesh() ||
race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode)))
{
if (curr->isSoccer())
m_unsupported_arena.insert(currArenas[n]);
continue;
}
}
else
{
if(curr->isArena() && curr->hasNavMesh() && !arenas_have_navmesh)
arenas_have_navmesh = true;
if(!curr->isArena() ||
(!(curr->hasNavMesh() ||
race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode)))
{
if (curr->isArena())
m_unsupported_arena.insert(currArenas[n]);
continue;
}
}
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );
}
else
{
w->addItem( translations->fribidize(curr->getName()), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
}
}
}
if (arenas_have_navmesh || race_manager->getNumLocalPlayers() > 1 ||
UserConfigParams::m_artist_debug_mode)
w->addItem(_("Random Arena"), "random_track", "/gui/track_random.png");
w->updateItemDisplay();
if (m_unsupported_arena.size() > 0)
w->setText( _P("%d arena unavailable in single player.",
"%d arenas unavailable in single player.",
(int)m_unsupported_arena.size()) );
}
// ------------------------------------------------------------------------------------------------------
void ArenasScreen::setFocusOnTrack(const std::string& trackName)
{
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tracks");
assert( w != NULL );
w->setSelection(trackName, PLAYER_ID_GAME_MASTER, true);
} // setFOxuOnTrack
// ------------------------------------------------------------------------------------------------------