Index: /code/trunk/data/gui/layouts/HighscoreMenu.layout
===================================================================
--- /code/trunk/data/gui/layouts/HighscoreMenu.layout (revision 11356)
+++ /code/trunk/data/gui/layouts/HighscoreMenu.layout (revision 11356)
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /code/trunk/data/gui/layouts/MainMenu.layout
===================================================================
--- /code/trunk/data/gui/layouts/MainMenu.layout (revision 11355)
+++ /code/trunk/data/gui/layouts/MainMenu.layout (revision 11356)
@@ -11,5 +11,5 @@
-
+
@@ -17,5 +17,5 @@
-
+
@@ -23,11 +23,17 @@
-
+
+
+
+
+
+
+
-
+
@@ -35,5 +41,5 @@
-
+
@@ -41,5 +47,5 @@
-
+
Index: /code/trunk/data/gui/scripts/HighscoreMenu.lua
===================================================================
--- /code/trunk/data/gui/scripts/HighscoreMenu.lua (revision 11356)
+++ /code/trunk/data/gui/scripts/HighscoreMenu.lua (revision 11356)
@@ -0,0 +1,169 @@
+-- HighscoreMenu.lua
+
+local P = createMenuSheet("HighscoreMenu")
+
+P.highscoreList = {}
+P.tabList = {}
+P.linesList = {}
+P.levelList = {}
+
+
+P.imageHeight = 50
+
+function P.onLoad()
+ P.createLevelList()
+end
+
+function P.onShow()
+
+ -- reset tables
+ P.highscoreList = {}
+ P.tabList = {}
+ P.linesList = {}
+
+ -- fetch save scores and write it into the list
+ for i=orxonox.Highscore:getInstance():getNumberOfHighscores()-1,0,-1 do
+ table.insert(P.highscoreList, orxonox.Highscore:getInstance():getHighscore(i))
+
+ end
+
+ -- read minigames out of the levelList
+ for k,v in pairs(P.levelList) do
+ if(v:getName() ~= "Hover level" and v:getName() ~= "Pong") then -- hover and pong dont contain relevant scores
+ P.createFilterTab(v:getName(), v:getName())
+ end
+ end
+
+end
+function P.onHide()
+
+ -- delete old windows to reload them on show
+ local tabControl = winMgr:getWindow("orxonox/HighscoreTabControl")
+ for k,v in pairs(P.tabList) do
+ local default = winMgr:getWindow(v)
+ tabControl:removeChildWindow(default)
+ winMgr:destroyWindow(default)
+ end
+end
+function P.createLevelList()
+ P.levelList = {}
+ local size = orxonox.LevelManager:getInstance():getNumberOfLevels()
+ local index = 0
+ local level = nil
+ while index < size do
+ level = orxonox.LevelManager:getInstance():getAvailableLevelListItem(index)
+ if (level ~= nil and level:getXMLFilename() ~= "_temp.oxw" and level:hasTag("minigame")) then
+ table.insert(P.levelList, level)
+ end
+ index = index + 1
+ end
+end
+function P.createFilterTab(name, tag)
+ -- create unique tab window name
+ local tabName = "orxonox/HighscoreLevelTab"
+ if tag ~= nil then
+ tabName = tabName..tag
+ end
+
+ table.insert(P.tabList, tabName)
+ -- create new tab window with desired name
+ local default = (winMgr:createWindow("DefaultWindow", tabName))
+ default:setText(name)
+ default:setProperty("UnifiedMaxSize", "{{1,0},{1,0}}")
+ default:setProperty("UnifiedAreaRect", "{{0,0},{0,0},{1,0},{1,0}}")
+ local pane = winMgr:createWindow("MenuWidgets/ScrollablePane", tabName .. "pane")
+ pane:setSize(CEGUI.UVector2(CEGUI.UDim(1,0),CEGUI.UDim(1,0)))
+ default:addChildWindow(pane)
+
+
+ local offset = 2
+ for k,v in pairs(P.highscoreList) do
+ -- split the score ("Playername./.game./.score")
+ local splitlist = P.Split(v,"./.")
+ if(splitlist[2] == name)then
+ local line = P.createPickupEntry(tabName .. k,k,tag)
+ table.insert(P.linesList, line)
+ line:setYPosition(CEGUI.UDim(0,offset))
+ offset = offset + line:getHeight():asAbsolute(1)+2
+ pane:addChildWindow(line)
+ end
+
+ end
+
+ local tabControl = winMgr:getWindow("orxonox/HighscoreTabControl")
+ tabControl:addChildWindow(default)
+
+
+
+end
+function P.createPickupEntry(parent,k,tag)
+
+ local name = "orxonox/HiscoreEntry" .. parent
+ local splitlist = P.Split(P.highscoreList[k],"./.")
+ local item = winMgr:createWindow("DefaultWindow", name)
+ item:setSize(CEGUI.UVector2(CEGUI.UDim(1, 0), CEGUI.UDim(0, P.imageHeight)))
+ item:setPosition(CEGUI.UVector2(CEGUI.UDim(0, 0), CEGUI.UDim(0, 0)))
+
+ local player = winMgr:createWindow("MenuWidgets/StaticText", name .. "/Player")
+ player:setText(splitlist[1])
+ player:setPosition(CEGUI.UVector2(CEGUI.UDim(0.005,0), CEGUI.UDim(0,0)))
+ player:setSize(CEGUI.UVector2(CEGUI.UDim(0.49, 0), CEGUI.UDim(0, P.imageHeight)))
+
+ item:addChildWindow(player)
+
+ local score = winMgr:createWindow("MenuWidgets/StaticText", name .. "/Score")
+ score:setText(splitlist[3])
+ score:setPosition(CEGUI.UVector2(CEGUI.UDim(0.5,0), CEGUI.UDim(0,0)))
+ score:setSize(CEGUI.UVector2(CEGUI.UDim(0.495, 0), CEGUI.UDim(0, P.imageHeight)))
+
+ item:addChildWindow(score)
+
+ return item
+end
+function P.HighscoreGetSelectedLevel()
+ -- choose the active listbox
+ local tabControl = CEGUI.toTabControl(winMgr:getWindow("orxonox/HighscoreTabControl"))
+ local listbox = CEGUI.toListbox(tabControl:getTabContentsAtIndex(tabControl:getSelectedTabIndex()))
+ local choice = listbox:getFirstSelectedItem()
+ if choice ~= nil then
+ -- get the right tab and the right index
+ local tabIndexes = P.activeTabIndexes[tabControl:getSelectedTabIndex()+1]
+ local index = tabIndexes[listbox:getItemIndex(choice)+1]
+ return P.levelList[index]
+ else
+ return nil
+ end
+end
+function P.Split(str, delim, maxNb)
+ -- Eliminate bad cases...
+ if string.find(str, delim) == nil then
+ return { str }
+ end
+ if maxNb == nil or maxNb < 1 then
+ maxNb = 0 -- No limit
+ end
+ local result = {}
+ local pat = "(.-)" .. delim .. "()"
+ local nb = 0
+ local lastPos
+ for part, pos in string.gfind(str, pat) do
+ nb = nb + 1
+ result[nb] = part
+ lastPos = pos
+ if nb == maxNb then break end
+ end
+ -- Handle the last field
+ if nb ~= maxNb then
+ result[nb + 1] = string.sub(str, lastPos)
+ end
+ return result
+end
+
+
+
+function P.HighscoreBackButton_clicked(e)
+ hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/trunk/data/gui/scripts/MainMenu.lua
===================================================================
--- /code/trunk/data/gui/scripts/MainMenu.lua (revision 11355)
+++ /code/trunk/data/gui/scripts/MainMenu.lua (revision 11356)
@@ -2,5 +2,5 @@
local P = createMenuSheet("MainMenu")
-P.loadAlong = { "SingleplayerMenu", "MultiplayerMenu", "SettingsMenu", "CreditsMenu" }
+P.loadAlong = { "SingleplayerMenu", "MultiplayerMenu", "HighscoreMenu", "SettingsMenu", "CreditsMenu" }
function P.onLoad()
@@ -22,14 +22,19 @@
P:setButton(4, 1, {
+ ["button"] = winMgr:getWindow("orxonox/HighscoreButton"),
+ ["callback"] = P.MultiplayerButton_clicked
+ })
+
+ P:setButton(5, 1, {
["button"] = winMgr:getWindow("orxonox/SettingsButton"),
["callback"] = P.SettingsButton_clicked
})
- P:setButton(5, 1, {
+ P:setButton(6, 1, {
["button"] = winMgr:getWindow("orxonox/CreditsButton"),
["callback"] = P.CreditsButton_clicked
})
- P:setButton(6, 1, {
+ P:setButton(7, 1, {
["button"] = winMgr:getWindow("orxonox/ExitButton"),
["callback"] = P.ExitButton_clicked
@@ -51,4 +56,8 @@
end
+function P.HighscoreButton_clicked(e)
+ showMenuSheet("HighscoreMenu", true)
+end
+
function P.SettingsButton_clicked(e)
showMenuSheet("SettingsMenu", true)
Index: /code/trunk/data/gui/scripts/MiscConfigMenu.lua
===================================================================
--- /code/trunk/data/gui/scripts/MiscConfigMenu.lua (revision 11355)
+++ /code/trunk/data/gui/scripts/MiscConfigMenu.lua (revision 11356)
@@ -18,4 +18,5 @@
P.commandList = {}
+ table.insert(P.commandList, "Highscore playerName_")
table.insert(P.commandList, "KeyBinder mouseSensitivity_")
table.insert(P.commandList, "KeyBinder mouseSensitivityDerived_")
@@ -43,4 +44,5 @@
P.nameList = {}
+ table.insert(P.nameList, "Playername")
table.insert(P.nameList, "Mouse sensitivity")
table.insert(P.nameList, "Mouse acceleration")
Index: /code/trunk/src/modules/dodgerace/DodgeRace.cc
===================================================================
--- /code/trunk/src/modules/dodgerace/DodgeRace.cc (revision 11355)
+++ /code/trunk/src/modules/dodgerace/DodgeRace.cc (revision 11356)
@@ -36,4 +36,5 @@
#include "DodgeRaceCube.h"
#include "core/CoreIncludes.h"
+#include "Highscore.h"
namespace orxonox
@@ -224,4 +225,10 @@
// It will misteriously crash the game!
// Instead startMainMenu, this won't crash.
+ if (Highscore::exists()){
+ int score = this->getPoints();
+ if(score > Highscore::getInstance().getHighestScoreOfGame("Dodge Race"))
+ Highscore::getInstance().storeHighscore("Dodge Race",score);
+
+ }
GSLevel::startMainMenu();
}
Index: /code/trunk/src/modules/invader/Invader.cc
===================================================================
--- /code/trunk/src/modules/invader/Invader.cc (revision 11355)
+++ /code/trunk/src/modules/invader/Invader.cc (revision 11356)
@@ -33,5 +33,5 @@
#include "Invader.h"
-
+#include "Highscore.h"
#include "core/CoreIncludes.h"
#include "core/EventIncludes.h"
@@ -189,4 +189,10 @@
// It will misteriously crash the game!
// Instead startMainMenu, this won't crash.
+ if (Highscore::exists()){
+ int score = this->getPoints();
+ if(score > Highscore::getInstance().getHighestScoreOfGame("Orxonox Arcade"))
+ Highscore::getInstance().storeHighscore("Orxonox Arcade",score);
+
+ }
GSLevel::startMainMenu();
}
Index: /code/trunk/src/modules/jump/Jump.cc
===================================================================
--- /code/trunk/src/modules/jump/Jump.cc (revision 11355)
+++ /code/trunk/src/modules/jump/Jump.cc (revision 11356)
@@ -34,4 +34,5 @@
#include "Jump.h"
#include "core/CoreIncludes.h"
+#include "Highscore.h"
#include "JumpCenterpoint.h"
@@ -311,5 +312,10 @@
cleanup();
GSLevel::startMainMenu();
-
+ if (Highscore::exists()){
+ int score = this->getScore(this->getPlayer());
+ if(score > Highscore::getInstance().getHighestScoreOfGame("Jump"))
+ Highscore::getInstance().storeHighscore("Jump",score);
+
+ }
Deathmatch::end();
}
Index: /code/trunk/src/modules/tetris/Tetris.cc
===================================================================
--- /code/trunk/src/modules/tetris/Tetris.cc (revision 11355)
+++ /code/trunk/src/modules/tetris/Tetris.cc (revision 11356)
@@ -39,4 +39,5 @@
#include "Tetris.h"
+#include "Highscore.h"
#include "core/CoreIncludes.h"
@@ -327,5 +328,10 @@
this->player_->stopControl();
}
-
+ if (Highscore::exists()){
+ int score = this->getScore(this->getPlayer());
+ if(score > Highscore::getInstance().getHighestScoreOfGame("Tetris"))
+ Highscore::getInstance().storeHighscore("Tetris",score);
+
+ }
this->cleanup();
Index: /code/trunk/src/modules/towerdefense/TowerDefense.cc
===================================================================
--- /code/trunk/src/modules/towerdefense/TowerDefense.cc (revision 11355)
+++ /code/trunk/src/modules/towerdefense/TowerDefense.cc (revision 11356)
@@ -81,4 +81,5 @@
#include "chat/ChatManager.h"
#include "core/CoreIncludes.h"
+#include "Highscore.h"
namespace orxonox
@@ -197,5 +198,10 @@
void TowerDefense::end()
{
-
+ if (Highscore::exists()){
+ int score = this->getWaveNumber();
+ if(score > Highscore::getInstance().getHighestScoreOfGame("Tower Defense"))
+ Highscore::getInstance().storeHighscore("Tower Defense",score);
+
+ }
TeamDeathmatch::end();
ChatManager::message("Match is over! Gameover!");
Index: /code/trunk/src/orxonox/CMakeLists.txt
===================================================================
--- /code/trunk/src/orxonox/CMakeLists.txt (revision 11355)
+++ /code/trunk/src/orxonox/CMakeLists.txt (revision 11356)
@@ -28,4 +28,5 @@
LevelInfo.cc
LevelManager.cc
+ Highscore.cc
Main.cc
MoodManager.cc
@@ -61,4 +62,5 @@
LevelInfo.h
LevelManager.h
+ Highscore.h
MoodManager.h
controllers/HumanController.h
Index: /code/trunk/src/orxonox/Highscore.cc
===================================================================
--- /code/trunk/src/orxonox/Highscore.cc (revision 11356)
+++ /code/trunk/src/orxonox/Highscore.cc (revision 11356)
@@ -0,0 +1,58 @@
+#include "Highscore.h"
+
+#include
+#include "core/CoreIncludes.h"
+#include "core/config/ConfigValueIncludes.h"
+#include "core/singleton/ScopedSingletonIncludes.h"
+
+namespace orxonox
+{
+
+ ManageScopedSingleton(Highscore, ScopeID::ROOT, false);
+ RegisterClassNoArgs(Highscore);
+
+ Highscore::Highscore()
+ {
+ RegisterObject(Highscore);
+ this->setConfigValues();
+ }
+ /**
+ * @brief set the config values in the orxonox.ini file
+ */
+ void Highscore::setConfigValues()
+ {
+ SetConfigValue(highscores_, std::vector()).description("Highscores saved as vector");
+ SetConfigValue(playerName_, "Player").description("Name of the player");
+ }
+ /**
+ * @brief Returns highest score of given game, if exists.
+ * Else returns -1.
+ */
+ int Highscore::getHighestScoreOfGame(std::string game){
+ std::string delimiter = "./."; //score save as "Playername./.game./.score"
+ int best = -1;
+ //check for the highest Score of given game
+ for (std::string score : this->highscores_)
+ {
+ //filter the game string from given highscore
+ score.erase(0, score.find(delimiter) + delimiter.length());
+ if(game.compare(score.substr(0,score.find(delimiter))) == 0){
+ score.erase(0, score.find(delimiter) + delimiter.length());
+ int possibleBest = std::stoi(score);
+ if(possibleBest > best) best = possibleBest;
+ }
+
+
+ }
+
+ return best;
+
+ }
+ /**
+ * @brief stores a new highscore in the orxonox.ini file
+ */
+ void Highscore::storeHighscore(std::string level, int points){
+ ModifyConfigValue(highscores_, add, playerName_+"./."+level+"./."+std::to_string(points));
+ }
+
+}
Index: /code/trunk/src/orxonox/Highscore.h
===================================================================
--- /code/trunk/src/orxonox/Highscore.h (revision 11356)
+++ /code/trunk/src/orxonox/Highscore.h (revision 11356)
@@ -0,0 +1,39 @@
+#include
+#include "core/config/Configurable.h"
+#include "OrxonoxPrereqs.h"
+#include "util/Singleton.h"
+// tolua_begin
+namespace orxonox
+{
+class _OrxonoxExport Highscore
+// tolua_end
+ : public Singleton, public Configurable
+{ //tolua_export
+ friend class Singleton;
+ public:
+ Highscore(); // Constructor
+ void setConfigValues(); // Inherited function
+ void storeHighscore(std::string level, int points);
+
+ int getHighestScoreOfGame(std::string game);
+ // tolua_begin
+ inline unsigned int getNumberOfHighscores()
+ { return this->highscores_.size(); }
+ inline const std::string& getHighscore(unsigned int index)
+ { return this->highscores_[index]; }
+
+ static Highscore& getInstance()
+ { return Singleton::getInstance(); }
+
+ // tolua_end
+
+
+ private:
+ std::vector highscores_;
+ float version_;
+ std::string playerName_;
+ static Highscore* singletonPtr_s;
+}; //tolua_export
+
+
+} //tolua_export
Index: /code/trunk/src/orxonox/LevelInfo.cc
===================================================================
--- /code/trunk/src/orxonox/LevelInfo.cc (revision 11355)
+++ /code/trunk/src/orxonox/LevelInfo.cc (revision 11356)
@@ -151,4 +151,14 @@
}
+ bool LevelInfoItem::addHighscore(const std::string& name, const int score)
+ {
+ std::stringstream stream;
+ stream << name << "/:/" << score;
+ bool success = this->highscores_.insert(stream.str()).second;
+ if(success)
+ this->highscoresUpdated();
+ return success;
+ }
+
/**
@brief
@@ -191,4 +201,19 @@
}
+ void LevelInfoItem::highscoresUpdated(void)
+ {
+ std::stringstream stream;
+ std::set::iterator temp;
+ for(std::set::iterator it = this->highscores_.begin(); it != this->highscores_.end(); )
+ {
+ temp = it;
+ if(++it == this->highscores_.end()) // If this is the last tag we don't add a comma.
+ stream << *temp;
+ else
+ stream << *temp << ", ";
+ }
+
+ this->highscoresString_ = std::string(stream.str());
+ }
/**
@brief
Index: /code/trunk/src/orxonox/LevelInfo.h
===================================================================
--- /code/trunk/src/orxonox/LevelInfo.h (revision 11355)
+++ /code/trunk/src/orxonox/LevelInfo.h (revision 11356)
@@ -118,4 +118,8 @@
inline bool hasTag(const std::string& tag) const { return this->tags_.find(tag) != this->tags_.end(); } // tolua_export
+ bool addHighscore(const std::string& name,const int score);
+
+ inline const std::string& getHighscores(void) const { return this->highscoresString_; } // tolua_export
+
void setStartingShips(const std::string& ships); //!< Set the starting ship models of the level
bool addStartingShip(const std::string& ship, bool update = true); //!< Add a model to shipselection
@@ -154,4 +158,5 @@
void startingshipsUpdated(void); //!< Updates the comma-seperated string of all possible starting ships.
void tagsUpdated(void); //!< Updates the comma-seperated string of all tags, if the set of tags has changed.
+ void highscoresUpdated(void);
static void initializeTags(void); //!< Initialize the set of allowed tags.
/**
@@ -170,4 +175,8 @@
std::string screenshot_; //!< The screenshot of the Level.
std::set tags_; //!< The set of tags the Level is tagged with.
+
+ std::set highscores_;
+ std::string highscoresString_;
+
std::string tagsString_; //!< The comma-seperated string of all the tags the Level is tagged with.
std::set startingShips_; //!< The set of starting ship models the Level allows.
@@ -244,4 +253,7 @@
inline const std::string& getTags(void) const
{ return this->LevelInfoItem::getTags(); }
+
+ inline const std::string& getHighscores(void) const
+ { return this->LevelInfoItem::getHighscores(); }
/**
@brief Set the starting ship models of the level