Add GUI option in track info screen for random item location.

This commit is contained in:
Benau 2016-03-17 12:16:19 +08:00
parent d2509baf5c
commit 5b7161710d
7 changed files with 80 additions and 47 deletions

View File

@ -70,11 +70,11 @@
</div>
<spacer height="10"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="reverse-text" proportion="1" I18N="In the track info screen" text="Drive in reverse" text_align="right"/>
<label id="option-text" proportion="1" I18N="In the track info screen" text_align="right"/>
<spacer width="40"/>
<div proportion="1" height="fit" layout="horizontal-row">
<div width="50%" height="fit" text-align="center" layout="vertical-row" >
<checkbox id="reverse" align="center"/>
<checkbox id="option" align="center"/>
</div>
</div>
</div>

View File

@ -515,6 +515,9 @@ namespace UserConfigParams
/** If track debugging is enabled. */
PARAM_PREFIX int m_track_debug PARAM_DEFAULT( false );
/** If random number of items is used in an arena. */
PARAM_PREFIX bool m_random_arena_item PARAM_DEFAULT( false );
/** True if check structures should be debugged. */
PARAM_PREFIX bool m_check_debug PARAM_DEFAULT( false );

View File

@ -23,6 +23,7 @@
#include <sstream>
#include "config/stk_config.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
@ -476,18 +477,13 @@ void ItemManager::switchItems()
} // switchItems
//-----------------------------------------------------------------------------
bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos,
unsigned int bonus, unsigned int big_nitro,
unsigned int small_nitro, unsigned int banana)
bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
{
if (!UserConfigParams::m_random_arena_item) return false;
if (!BattleGraph::get()) return false;
if (bonus == 0 && big_nitro == 0 && small_nitro == 0 && banana == 0)
return false;
std::vector<int> used_location;
std::vector<int> invalid_location;
std::vector<int> final_location;
for (unsigned int i = 0; i < pos.size(); i++)
{
// Load all starting positions of arena, so no items will be near them
@ -498,21 +494,25 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos,
invalid_location.push_back(node);
}
const unsigned int total_item = bonus + big_nitro + small_nitro + banana;
for (unsigned int i = 0; i < total_item; i++)
RandomGenerator random;
const unsigned int MIN_DIST = sqrt(BattleGraph::get()->getNumNodes());
const unsigned int TOTAL_ITEM = MIN_DIST / 2;
Log::info("[ItemManager]","Creating %d random items for arena", TOTAL_ITEM);
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
{
int chosen_node = -1;
const unsigned int total_node = BattleGraph::get()->getNumNodes();
while(true)
{
if (final_location.size() + invalid_location.size() == total_node)
if (used_location.size() - pos.size() +
invalid_location.size() == total_node)
{
Log::warn("[ItemManager]","Can't place more random items! "
"Use default item location.");
return false;
}
RandomGenerator random;
const int node = random.get(total_node);
// Check if tried
@ -535,7 +535,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos,
Vec3 d = BattleGraph::get()
->getPolyOfNode(used_location[j]).getCenter() -
BattleGraph::get()->getPolyOfNode(node).getCenter();
found = d.length_2d() > 20.0f;
found = d.length_2d() > MIN_DIST;
}
if (found)
{
@ -549,20 +549,28 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos,
assert(chosen_node != -1);
used_location.push_back(chosen_node);
final_location.push_back(chosen_node);
}
assert (final_location.size() == total_item);
for (unsigned int i = 0; i < total_item; i++)
for (unsigned int i = 0; i < pos.size(); i++)
used_location.erase(used_location.begin());
assert (used_location.size() == TOTAL_ITEM);
// Hard-coded ratio for now
const int BONUS_BOX = 4;
const int NITRO_BIG = 2;
const int NITRO_SMALL = 1;
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
{
Item::ItemType type = (i < bonus ? Item::ITEM_BONUS_BOX :
i < bonus + big_nitro ? Item::ITEM_NITRO_BIG :
i < bonus + big_nitro + small_nitro ? Item::ITEM_NITRO_SMALL :
Item::ITEM_BANANA);
const int j = random.get(10);
Item::ItemType type = (j > BONUS_BOX ? Item::ITEM_BONUS_BOX :
j > NITRO_BIG ? Item::ITEM_NITRO_BIG :
j > NITRO_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA);
Vec3 loc = BattleGraph::get()
->getPolyOfNode(final_location[i]).getCenter();
->getPolyOfNode(used_location[i]).getCenter();
Item* item = newItem(type, loc, Vec3(0, 1, 0));
BattleGraph::get()->insertItems(item, final_location[i]);
BattleGraph::get()->insertItems(item, used_location[i]);
}
return true;

View File

@ -113,9 +113,7 @@ public:
int add_info=-1);
void switchItems ();
// ------------------------------------------------------------------------
bool randomItemsForArena(const AlignedArray<btTransform>& pos,
unsigned int bonus, unsigned int big_nitro,
unsigned int small_nitro, unsigned int banana);
bool randomItemsForArena(const AlignedArray<btTransform>& pos);
// ------------------------------------------------------------------------
/** Returns the number of items. */
unsigned int getNumberOfItems() const { return (unsigned int) m_all_items.size(); }

View File

@ -67,9 +67,9 @@ void TrackInfoScreen::loadedFromFile()
{
m_lap_spinner = getWidget<SpinnerWidget>("lap-spinner");
m_ai_kart_spinner = getWidget<SpinnerWidget>("ai-spinner");
m_reverse = getWidget<CheckBoxWidget>("reverse");
m_option = getWidget<CheckBoxWidget>("option");
m_record_race = getWidget<CheckBoxWidget>("record");
m_reverse->setState(false);
m_option->setState(false);
m_record_race->setState(false);
m_highscore_label = getWidget<LabelWidget>("highscores");
@ -198,18 +198,31 @@ void TrackInfoScreen::init()
else
race_manager->setNumKarts(local_players);
// Reverse track
// Reverse track or random item in arena
// -------------
const bool reverse_available = m_track->reverseAvailable() &&
race_manager->getMinorMode() != RaceManager::MINOR_MODE_EASTER_EGG;
m_reverse->setVisible(reverse_available);
getWidget<LabelWidget>("reverse-text")->setVisible(reverse_available);
const bool random_item = m_track->hasNavMesh();
m_option->setVisible(reverse_available || random_item);
getWidget<LabelWidget>("option-text")->setVisible(reverse_available || random_item);
if (reverse_available)
{
m_reverse->setState(race_manager->getReverseTrack());
//I18N: In the track info screen
getWidget<LabelWidget>("option-text")->setText(_("Drive in reverse"), false);
}
else if (random_item)
{
//I18N: In the track info screen
getWidget<LabelWidget>("option-text")->setText(_("Random item location"), false);
}
if (reverse_available)
{
m_option->setState(race_manager->getReverseTrack());
}
else
m_reverse->setState(false);
m_option->setState(false);
// Record race or not
// -------------
@ -312,12 +325,16 @@ void TrackInfoScreen::onEnterPressedInternal()
// not be accessible after dismiss:
const int num_laps = race_manager->modeHasLaps() ? m_lap_spinner->getValue()
: -1;
const bool reverse_track = m_reverse == NULL ? false
: m_reverse->getState();
const bool option_state = m_option == NULL ? false
: m_option->getState();
// Avoid negative lap numbers (after e.g. easter egg mode).
if(num_laps>=0)
m_track->setActualNumberOfLaps(num_laps);
race_manager->setReverseTrack(reverse_track);
if(m_track->hasNavMesh())
UserConfigParams::m_random_arena_item = option_state;
else
race_manager->setReverseTrack(option_state);
// Avoid invaild Ai karts number during switching game modes
const int max_arena_players = m_track->getMaxArenaPlayers();
@ -361,12 +378,19 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
{
StateManager::get()->escapePressed();
}
else if (name == "reverse")
else if (name == "option")
{
race_manager->setReverseTrack(m_reverse->getState());
// Makes sure the highscores get swapped when clicking the 'reverse'
// checkbox.
updateHighScores();
if (m_track->hasNavMesh())
{
UserConfigParams::m_random_arena_item = m_option->getState();
}
else
{
race_manager->setReverseTrack(m_option->getState());
// Makes sure the highscores get swapped when clicking the 'reverse'
// checkbox.
updateHighScores();
}
}
else if (name == "record")
{

View File

@ -52,8 +52,8 @@ class TrackInfoScreen : public GUIEngine::Screen,
/** Spinner for number of AI karts. */
GUIEngine::SpinnerWidget* m_ai_kart_spinner;
/** Check box for reverse mode. */
GUIEngine::CheckBoxWidget* m_reverse;
/** Check box for reverse mode or random item in arena. */
GUIEngine::CheckBoxWidget* m_option;
/** Check box for record race. */
GUIEngine::CheckBoxWidget* m_record_race;

View File

@ -1862,10 +1862,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
createPhysicsModel(main_track_count);
const bool arena_random_item = (m_has_navmesh && ItemManager::get()
->randomItemsForArena(m_start_transforms,5,2,2,1));
const bool arena_random_item_created =
ItemManager::get()->randomItemsForArena(m_start_transforms);
if (!arena_random_item)
if (!arena_random_item_created)
{
for (unsigned int i=0; i<root->getNumNodes(); i++)
{
@ -1882,7 +1882,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
delete root;
if ((m_is_arena || m_is_soccer) && !m_is_cutscene && m_has_navmesh && !arena_random_item)
if ((m_is_arena || m_is_soccer) && !m_is_cutscene && m_has_navmesh && !arena_random_item_created)
BattleGraph::get()->findItemsOnGraphNodes();
if (UserConfigParams::m_track_debug &&