From 7d53df698ad860b0059ec1d35e0a954985188215 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Wed, 21 Sep 2011 06:51:28 +0000 Subject: [PATCH] - added new in-game popup menu and new ability to switch teams in game (turned off by default in advanced settings) --- source/glest_game/ai/ai.cpp | 38 +++- source/glest_game/ai/ai.h | 1 + source/glest_game/ai/ai_interface.cpp | 7 + source/glest_game/ai/ai_interface.h | 2 + source/glest_game/facilities/components.cpp | 118 ++++++++++++ source/glest_game/facilities/components.h | 31 +++ source/glest_game/game/commander.cpp | 141 ++++++++++++++ source/glest_game/game/commander.h | 4 + source/glest_game/game/game.cpp | 182 +++++++++++++++++- source/glest_game/game/game.h | 11 ++ source/glest_game/game/game_settings.h | 12 +- source/glest_game/graphics/renderer.cpp | 103 ++++++++++ source/glest_game/graphics/renderer.h | 1 + .../menu/menu_state_connected_game.cpp | 36 ++++ .../menu/menu_state_connected_game.h | 5 + .../menu/menu_state_custom_game.cpp | 80 ++++++++ .../glest_game/menu/menu_state_custom_game.h | 5 + source/glest_game/menu/menu_state_root.cpp | 23 ++- source/glest_game/menu/menu_state_root.h | 3 + source/glest_game/network/network_message.cpp | 5 + source/glest_game/network/network_message.h | 2 + source/glest_game/network/network_types.h | 4 +- source/glest_game/type_instances/faction.cpp | 80 +++++++- source/glest_game/type_instances/faction.h | 33 +++- source/glest_game/types/command_type.cpp | 57 ++++++ source/glest_game/types/command_type.h | 19 ++ source/glest_game/world/unit_updater.cpp | 56 ++++++ source/glest_game/world/unit_updater.h | 1 + source/glest_game/world/world.cpp | 41 +++- source/glest_game/world/world.h | 7 + 30 files changed, 1087 insertions(+), 21 deletions(-) diff --git a/source/glest_game/ai/ai.cpp b/source/glest_game/ai/ai.cpp index ca3633b6..8678252f 100644 --- a/source/glest_game/ai/ai.cpp +++ b/source/glest_game/ai/ai.cpp @@ -157,6 +157,42 @@ void Ai::update() { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [START]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + if(aiInterface->getMyFaction()->getFirstSwitchTeamVote() != NULL) { + const SwitchTeamVote *vote = aiInterface->getMyFaction()->getFirstSwitchTeamVote(); + aiInterface->getMyFaction()->setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex); + + factionSwitchTeamRequestCount[vote->factionIndex]++; + int factionSwitchTeamRequestCountCurrent = factionSwitchTeamRequestCount[vote->factionIndex]; + + //int allowJoinTeam = random.randRange(0, 100); + srand(time(NULL) + aiInterface->getMyFaction()->getIndex()); + int allowJoinTeam = rand() % 100; + + SwitchTeamVote *voteResult = aiInterface->getMyFaction()->getSwitchTeamVote(vote->factionIndex); + voteResult->voted = true; + voteResult->allowSwitchTeam = false; + + const GameSettings *settings = aiInterface->getWorld()->getGameSettings(); + // Can only ask the AI player 2 times max per game + if(factionSwitchTeamRequestCountCurrent <= 2) { + // x% chance the AI will answer yes + if(settings->getAiAcceptSwitchTeamPercentChance() >= 100) { + voteResult->allowSwitchTeam = true; + } + else if(settings->getAiAcceptSwitchTeamPercentChance() <= 0) { + voteResult->allowSwitchTeam = false; + } + else { + voteResult->allowSwitchTeam = (allowJoinTeam >= (100 - settings->getAiAcceptSwitchTeamPercentChance())); + } + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] AI for faction# %d voted %s [%d] factionSwitchTeamRequestCountCurrent [%d] settings->getAiAcceptSwitchTeamPercentChance() [%d]\n",__FILE__,__FUNCTION__,__LINE__,aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent,settings->getAiAcceptSwitchTeamPercentChance()); + //printf("AI for faction# %d voted %s [%d] factionSwitchTeamRequestCountCurrent [%d]\n",aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent); + + aiInterface->giveCommandSwitchTeamVote(aiInterface->getMyFaction(),voteResult); + } + //process ai rules for(int ruleIdx = 0; ruleIdx < aiRules.size(); ++ruleIdx) { AiRule *rule = aiRules[ruleIdx]; @@ -412,7 +448,7 @@ void Ai::addExpansion(const Vec2i &pos){ } } -Vec2i Ai::getRandomHomePosition(){ +Vec2i Ai::getRandomHomePosition() { if(expansionPositions.empty() || random.randRange(0, 1) == 0){ return aiInterface->getHomeLocation(); diff --git a/source/glest_game/ai/ai.h b/source/glest_game/ai/ai.h index bcee03c3..d44703be 100644 --- a/source/glest_game/ai/ai.h +++ b/source/glest_game/ai/ai.h @@ -144,6 +144,7 @@ private: Tasks tasks; Positions expansionPositions; RandomGen random; + std::map factionSwitchTeamRequestCount; bool getAdjacentUnits(std::map > &signalAdjacentUnits, const Unit *unit); diff --git a/source/glest_game/ai/ai_interface.cpp b/source/glest_game/ai/ai_interface.cpp index 137b330b..749f9e1f 100644 --- a/source/glest_game/ai/ai_interface.cpp +++ b/source/glest_game/ai/ai_interface.cpp @@ -117,6 +117,13 @@ bool AiInterface::executeCommandOverNetwork() { return faction->getCpuControl(enableServerControlledAI,isNetworkGame,role); } +CommandResult AiInterface::giveCommandSwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) { + assert(this->gameSettings != NULL); + + commander->trySwitchTeamVote(faction,vote); + return crSuccess; +} + CommandResult AiInterface::giveCommand(int unitIndex, CommandClass commandClass, const Vec2i &pos){ assert(this->gameSettings != NULL); diff --git a/source/glest_game/ai/ai_interface.h b/source/glest_game/ai/ai_interface.h index b3607616..257b8433 100644 --- a/source/glest_game/ai/ai_interface.h +++ b/source/glest_game/ai/ai_interface.h @@ -70,6 +70,8 @@ public: CommandResult giveCommand(int unitIndex, const CommandType *commandType, Unit *u= NULL); CommandResult giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId); + CommandResult giveCommandSwitchTeamVote(const Faction* faction, SwitchTeamVote *vote); + //get data const ControlType getControlType(); int getMapMaxPlayers(); diff --git a/source/glest_game/facilities/components.cpp b/source/glest_game/facilities/components.cpp index 299dd40c..a66ad442 100644 --- a/source/glest_game/facilities/components.cpp +++ b/source/glest_game/facilities/components.cpp @@ -646,5 +646,123 @@ int GraphicScrollBar::getThickness() const { return horizontal?getH():getW(); } +// =========================================================== +// class PopupMenu +// =========================================================== + +const int PopupMenu::defH= 240; +const int PopupMenu::defW= 350; + +PopupMenu::PopupMenu() { + h= defH; + w= defW; +} + +PopupMenu::~PopupMenu() { + +} + +void PopupMenu::init(string menuHeader,std::vector menuItems) { + header = menuHeader; + + font= CoreData::getInstance().getMenuFontNormal(); + font3D= CoreData::getInstance().getMenuFontNormal3D(); + + buttons.clear(); + + const Metrics &metrics= Metrics::getInstance(); + + x= (metrics.getVirtualW()-w)/2; + y= (metrics.getVirtualH()-h)/2; + + int maxButtonWidth = -1; + for(unsigned int i = 0; i < menuItems.size(); ++i) { + int currentButtonWidth = -1; + if(font3D != NULL) { + FontMetrics *fontMetrics= font3D->getMetrics(); + currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]); + } + else { + FontMetrics *fontMetrics= font->getMetrics(); + currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]); + } + + if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) { + maxButtonWidth = currentButtonWidth + 5; + } + } + + int textHeight = 30; + int yStartOffset = y + (h/2) + (textHeight/2); + for(unsigned int i = 0; i < menuItems.size(); ++i) { + GraphicButton button; + button.init(x+(w-maxButtonWidth)/2, yStartOffset - (i*textHeight)); + button.setText(menuItems[i]); + button.setW(maxButtonWidth); + + buttons.push_back(button); + } +} + +void PopupMenu::setX(int x) { + this->x= x; + + for(unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + button.init(x+(w-GraphicButton::defW)/4, y+25 + (i*25)); + } +} + +void PopupMenu::setY(int y) { + this->y= y; + + for(unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + button.init(x+(w-GraphicButton::defW)/4, y+25 + (i*25)); + } +} + +bool PopupMenu::mouseMove(int x, int y){ + if(this->getVisible() == false) { + return false; + } + + for(unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + if(button.mouseMove(x, y)) { + return true; + } + } + + return false; +} + +bool PopupMenu::mouseClick(int x, int y) { + if(this->getVisible() == false) { + return false; + } + + for(unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + if(button.mouseClick(x, y)) { + return true; + } + } + return false; +} + +std::pair PopupMenu::mouseClickedMenuItem(int x, int y) { + std::pair result; + for(unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + if(button.mouseClick(x, y)) { + result.first = i; + result.second = buttons[i].getText(); + break; + } + } + + return result; +} }}//end namespace diff --git a/source/glest_game/facilities/components.h b/source/glest_game/facilities/components.h index b38c4104..562abceb 100644 --- a/source/glest_game/facilities/components.h +++ b/source/glest_game/facilities/components.h @@ -336,5 +336,36 @@ public: int getVisibleCompPosEnd() const {return visibleCompPosEnd;} }; +// =========================================================== +// class PopupMenu +// =========================================================== + +class PopupMenu: public GraphicComponent { +public: + static const int defH; + static const int defW; + +private: + std::vector buttons; + string header; + +public: + PopupMenu(); + ~PopupMenu(); + void init(string menuHeader, std::vector menuItems); + + std::vector & getMenuItems() {return buttons;} + string getHeader() const {return header;} + + virtual void setX(int x); + virtual void setY(int y); + + void setHeader(string header) {this->header= header;} + + virtual bool mouseMove(int x, int y); + virtual bool mouseClick(int x, int y); + std::pair mouseClickedMenuItem(int x, int y); +}; + }}//end namespace #endif diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index 59fd3695..eb49f091 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -459,6 +459,15 @@ void Commander::trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const { pushNetworkCommand(&command); } +void Commander::trySwitchTeam(const Faction* faction, int teamIndex) const { + NetworkCommand command(this->world,nctSwitchTeam, faction->getIndex(), teamIndex); + pushNetworkCommand(&command); +} + +void Commander::trySwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) const { + NetworkCommand command(this->world,nctSwitchTeamVote, faction->getIndex(), vote->factionIndex,Vec2i(0),vote->allowSwitchTeam); + pushNetworkCommand(&command); +} // ==================== PRIVATE ==================== @@ -660,6 +669,138 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); } break; + + case nctSwitchTeam: { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); + + int factionIndex = networkCommand->getUnitId(); + int newTeam = networkCommand->getCommandTypeId(); + + // Auto join empty team or ask players to join + bool autoJoinTeam = true; + for(int i = 0; i < world->getFactionCount(); ++i) { + if(newTeam == world->getFaction(i)->getTeam()) { + autoJoinTeam = false; + break; + } + } + + if(autoJoinTeam == true) { + Faction *faction = world->getFaction(factionIndex); + int oldTeam = faction->getTeam(); + faction->setTeam(newTeam); + GameSettings *settings = world->getGameSettingsPtr(); + settings->setTeam(factionIndex,newTeam); + + if(factionIndex == world->getThisFactionIndex()) { + world->setThisTeamIndex(newTeam); + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + if(gameNetworkInterface != NULL) { + char szMsg[1024]=""; + sprintf(szMsg,"Player %s switched from team# %d to team# %d.",settings->getNetworkPlayerName(factionIndex).c_str(),oldTeam,newTeam); + gameNetworkInterface->sendTextMessage(szMsg,-1, true, ""); + } + } + } + else { + for(int i = 0; i < world->getFactionCount(); ++i) { + if(newTeam == world->getFaction(i)->getTeam()) { + Faction *faction = world->getFaction(factionIndex); + + SwitchTeamVote vote; + vote.factionIndex = factionIndex; + vote.allowSwitchTeam = false; + vote.oldTeam = faction->getTeam(); + vote.newTeam = newTeam; + vote.voted = false; + + world->getFaction(i)->setSwitchTeamVote(vote); + } + } + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); + } + break; + + case nctSwitchTeamVote: { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); + + int votingFactionIndex = networkCommand->getUnitId(); + int factionIndex = networkCommand->getCommandTypeId(); + bool allowSwitchTeam = networkCommand->getUnitTypeId(); + + Faction *faction = world->getFaction(votingFactionIndex); + + SwitchTeamVote *vote = faction->getSwitchTeamVote(factionIndex); + if(vote == NULL) { + throw runtime_error("vote == NULL"); + } + vote->voted = true; + vote->allowSwitchTeam = allowSwitchTeam; + + // Join the new team if > 50 % said yes + int newTeamTotalMemberCount=0; + int newTeamVotedYes=0; + int newTeamVotedNo=0; + + for(int i = 0; i < world->getFactionCount(); ++i) { + if(vote->newTeam == world->getFaction(i)->getTeam()) { + newTeamTotalMemberCount++; + + SwitchTeamVote *teamVote = world->getFaction(i)->getSwitchTeamVote(factionIndex); + if(teamVote != NULL && teamVote->voted == true) { + if(teamVote->allowSwitchTeam == true) { + newTeamVotedYes++; + } + else { + newTeamVotedNo++; + } + } + } + } + + // If > 50% of team vote yes, switch th eplayers team + if(newTeamVotedYes / newTeamTotalMemberCount > 0.5) { + Faction *faction = world->getFaction(factionIndex); + int oldTeam = faction->getTeam(); + faction->setTeam(vote->newTeam); + GameSettings *settings = world->getGameSettingsPtr(); + settings->setTeam(factionIndex,vote->newTeam); + + if(factionIndex == world->getThisFactionIndex()) { + world->setThisTeamIndex(vote->newTeam); + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + if(gameNetworkInterface != NULL) { + char szMsg[1024]=""; + sprintf(szMsg,"Player %s switched from team# %d to team# %d.",settings->getNetworkPlayerName(factionIndex).c_str(),oldTeam,vote->newTeam); + gameNetworkInterface->sendTextMessage(szMsg,-1, true, ""); + } + } + } + else if(newTeamTotalMemberCount == (newTeamVotedYes + newTeamVotedNo)) { + if(factionIndex == world->getThisFactionIndex()) { + GameSettings *settings = world->getGameSettingsPtr(); + Faction *faction = world->getFaction(factionIndex); + int oldTeam = faction->getTeam(); + + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + if(gameNetworkInterface != NULL) { + char szMsg[1024]=""; + sprintf(szMsg,"Player %s was denied the request to switch from team# %d to team# %d.",settings->getNetworkPlayerName(factionIndex).c_str(),oldTeam,vote->newTeam); + gameNetworkInterface->sendTextMessage(szMsg,-1, true, ""); + } + } + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); + } + break; + default: assert(false); } diff --git a/source/glest_game/game/commander.h b/source/glest_game/game/commander.h index 8691a55c..8d446fcb 100644 --- a/source/glest_game/game/commander.h +++ b/source/glest_game/game/commander.h @@ -34,6 +34,7 @@ class Command; class CommandType; class NetworkCommand; class Game; +class SwitchTeamVote; // ===================================================== // class Commander @@ -98,6 +99,9 @@ public: CommandResult tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit= NULL, bool tryQueue = false, int unitCommandGroupId = -1) const; CommandResult tryCancelCommand(const Selection *selection) const; void trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const; + void trySwitchTeam(const Faction* faction, int teamIndex) const; + void trySwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) const; + CommandResult pushNetworkCommand(const NetworkCommand* networkCommand) const; //void giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const; diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 8c3b07e1..70b98fbc 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -42,6 +42,9 @@ Game *thisGamePtr = NULL; const float PHOTO_MODE_MAXHEIGHT = 500.0; +const int CREATE_NEW_TEAM = -100; +const int CANCEL_SWITCH_TEAM = -1; + Game::Game() : ProgramState(NULL) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); originalDisplayMsgCallback = NULL; @@ -83,6 +86,10 @@ Game::Game() : ProgramState(NULL) { withRainEffect=false; program=NULL; gameStarted=false; + + switchTeamConfirmMessageBox.setEnabled(false); + exitGamePopupMenuIndex = -1; + joinTeamPopupMenuIndex = -1; } Game::Game(Program *program, const GameSettings *gameSettings): @@ -110,6 +117,10 @@ Game::Game(Program *program, const GameSettings *gameSettings): originalDisplayMsgCallback = NULL; thisGamePtr = this; + switchTeamConfirmMessageBox.setEnabled(false); + exitGamePopupMenuIndex = -1; + joinTeamPopupMenuIndex = -1; + this->gameSettings= *gameSettings; scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5"); photoModeEnabled = Config::getInstance().getBool("PhotoMode","false"); @@ -879,6 +890,26 @@ void Game::init(bool initForPreviewOnly) if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled) SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"================ STARTING GAME ================\n"); if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled) SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"PathFinderType: %s\n", (getGameSettings()->getPathFinderType() ? "RoutePlanner" : "PathFinder")); + + //PopupMenu popupMenu; + std::vector menuItems; + menuItems.push_back(lang.get("ExitGame?")); + exitGamePopupMenuIndex = menuItems.size()-1; + + if((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching) { + menuItems.push_back(lang.get("JoinOtherTeam")); + joinTeamPopupMenuIndex = menuItems.size()-1; + } + menuItems.push_back(lang.get("Exit")); + popupMenu.setW(200); + popupMenu.setH(200); + popupMenu.init(lang.get("GameMenuTitle"),menuItems); + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + popupMenuSwitchTeams.setEnabled(false); + popupMenuSwitchTeams.setVisible(false); + gameStarted = true; if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = %llu\n",__FILE__,__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount()); @@ -904,6 +935,20 @@ void Game::update() { return; } + if(world.getThisFaction()->getFirstSwitchTeamVote() != NULL) { + const SwitchTeamVote *vote = world.getThisFaction()->getFirstSwitchTeamVote(); + GameSettings *settings = world.getGameSettingsPtr(); + char szBuf[1024]=""; + sprintf(szBuf,"Allow player [%s] to join your team\n(changing from team# %d to team# %d)?",settings->getNetworkPlayerName(vote->factionIndex).c_str(),vote->oldTeam,vote->newTeam); + + Lang &lang= Lang::getInstance(); + switchTeamConfirmMessageBox.setText(szBuf); + switchTeamConfirmMessageBox.init(lang.get("Yes"), lang.get("No")); + switchTeamConfirmMessageBox.setEnabled(true); + + world.getThisFactionPtr()->setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex); + } + //misc updateFps++; mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim; @@ -1173,6 +1218,24 @@ void Game::tick() { // ==================== events ==================== +int Game::getFirstUnusedTeamNumber() { + std::map uniqueTeamNumbersUsed; + for(unsigned int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + uniqueTeamNumbersUsed[faction->getTeam()]=true; + } + + int result = -1; + for(int i = 0; i < GameConstants::maxPlayers; ++i) { + if(uniqueTeamNumbersUsed.find(i) == uniqueTeamNumbersUsed.end()) { + result = i; + break; + } + } + + return result; +} + void Game::mouseDownLeft(int x, int y) { try { if(gameStarted == false) { @@ -1185,6 +1248,106 @@ void Game::mouseDownLeft(int x, int y) { NetworkManager &networkManager= NetworkManager::getInstance(); bool messageBoxClick= false; + if(popupMenu.mouseClick(x, y)) { + std::pair result = popupMenu.mouseClickedMenuItem(x, y); + //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + // Exit game + if(result.first == exitGamePopupMenuIndex) { + showMessageBox(Lang::getInstance().get("ExitGame?"), "", true); + } + else if(result.first == joinTeamPopupMenuIndex) { + switchTeamIndexMap.clear(); + std::map uniqueTeamNumbersUsed; + std::vector menuItems; + for(unsigned int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + if(uniqueTeamNumbersUsed.find(faction->getTeam()) == uniqueTeamNumbersUsed.end()) { + uniqueTeamNumbersUsed[faction->getTeam()] = true; + } + + if(world.getThisFaction()->getIndex() != faction->getIndex() && + world.getThisFaction()->getTeam() != faction->getTeam()) { + char szBuf[1024]=""; + sprintf(szBuf,"Join player #%d - %s on Team: %d",faction->getIndex(),this->gameSettings.getNetworkPlayerName(i).c_str(),faction->getTeam()); + + menuItems.push_back(szBuf); + + switchTeamIndexMap[menuItems.size()-1] = faction->getTeam(); + } + } + if(uniqueTeamNumbersUsed.size() < 8) { + menuItems.push_back("Create New Team"); + switchTeamIndexMap[menuItems.size()-1] = CREATE_NEW_TEAM; + } + menuItems.push_back("Cancel"); + switchTeamIndexMap[menuItems.size()-1] = CANCEL_SWITCH_TEAM; + + popupMenuSwitchTeams.setW(400); + popupMenuSwitchTeams.setH(400); + popupMenuSwitchTeams.init("Switch Teams",menuItems); + popupMenuSwitchTeams.setEnabled(true); + popupMenuSwitchTeams.setVisible(true); + } + } + else if(popupMenuSwitchTeams.mouseClick(x, y)) { + //popupMenuSwitchTeams + std::pair result = popupMenuSwitchTeams.mouseClickedMenuItem(x, y); + //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + + popupMenuSwitchTeams.setEnabled(false); + popupMenuSwitchTeams.setVisible(false); + + bool isNetworkGame = this->gameSettings.isNetworkGame(); + + int teamIndex = switchTeamIndexMap[result.first]; + switch(teamIndex) { + case CREATE_NEW_TEAM: + { + int newTeam = getFirstUnusedTeamNumber(); + if(isNetworkGame == true) { + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeam(faction,newTeam); + } + else { + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeam(faction,newTeam); + } + } + break; + case CANCEL_SWITCH_TEAM: + break; + default: + if(isNetworkGame == true) { + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeam(faction,teamIndex); + } + else { + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeam(faction,teamIndex); + } + + break; + } + } + + if(switchTeamConfirmMessageBox.getEnabled() == true) { + int button= -1; + if(switchTeamConfirmMessageBox.mouseClick(x,y,button)) { + switchTeamConfirmMessageBox.setEnabled(false); + + SwitchTeamVote *vote = world.getThisFactionPtr()->getSwitchTeamVote(world.getThisFaction()->getCurrentSwitchTeamVoteFactionIndex()); + vote->voted = true; + vote->allowSwitchTeam = (button == 1); + + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeamVote(faction,vote); + } + } + //scrip message box, only if the exit box is not enabled if( mainMessageBox.getEnabled() == false && errorMessageBox.getEnabled() == false && @@ -1408,6 +1571,9 @@ void Game::mouseMove(int x, int y, const MouseState *ms) { return; } + popupMenu.mouseMove(x, y); + popupMenuSwitchTeams.mouseMove(x, y); + const Metrics &metrics = Metrics::getInstance(); mouseX = x; @@ -1467,6 +1633,10 @@ void Game::mouseMove(int x, int y, const MouseState *ms) { } } + if(switchTeamConfirmMessageBox.getEnabled() == true) { + switchTeamConfirmMessageBox.mouseMove(x,y); + } + if (mainMessageBox.getEnabled()) { mainMessageBox.mouseMove(x, y); } @@ -1672,7 +1842,10 @@ void Game::keyDown(SDL_KeyboardEvent key) { //exit //else if(key == configKeys.getCharKey("ExitKey")) { else if(isKeyPressed(configKeys.getSDLKey("ExitKey"),key, false) == true) { - showMessageBox(lang.get("ExitGame?"), "", true); + //showMessageBox(lang.get("ExitGame?"), "", true); + + popupMenu.setEnabled(!popupMenu.getEnabled()); + popupMenu.setVisible(popupMenu.getEnabled()); } //group //else if(key>='0' && key<'0'+Selection::maxGroups){ @@ -2012,6 +2185,10 @@ void Game::render2d(){ //selection renderer.renderSelectionQuad(); + if(switchTeamConfirmMessageBox.getEnabled() == true) { + renderer.renderMessageBox(&switchTeamConfirmMessageBox); + } + //exit message box if(errorMessageBox.getEnabled()) { renderer.renderMessageBox(&errorMessageBox); @@ -2043,6 +2220,9 @@ void Game::render2d(){ } } + renderer.renderPopupMenu(&popupMenu); + renderer.renderPopupMenu(&popupMenuSwitchTeams); + if(program != NULL) program->renderProgramMsgBox(); renderer.renderChatManager(&chatManager); diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 5fa0b5fb..7827d1be 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -127,6 +127,15 @@ private: time_t lastMaxUnitCalcTime; + PopupMenu popupMenu; + PopupMenu popupMenuSwitchTeams; + + std::map switchTeamIndexMap; + GraphicMessageBox switchTeamConfirmMessageBox; + + int exitGamePopupMenuIndex; + int joinTeamPopupMenuIndex; + public: Game(); Game(Program *program, const GameSettings *gameSettings); @@ -223,6 +232,8 @@ private: void ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role); void calcCameraMoveX(); void calcCameraMoveZ(); + + int getFirstUnusedTeamNumber(); }; }}//end namespace diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index bfa02341..773f2da2 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -27,8 +27,8 @@ namespace Glest{ namespace Game{ enum FlagTypes1 { ft1_none = 0x00, - ft1_show_map_resources = 0x01 - //ft1_xx = 0x02, + ft1_show_map_resources = 0x01, + ft1_allow_team_switching = 0x02 //ft1_xx = 0x04, //ft1_xx = 0x08, //ft1_xx = 0x10, @@ -77,6 +77,8 @@ private: int32 techCRC; vector > factionCRCList; + int aiAcceptSwitchTeamPercentChance; + public: GameSettings() { @@ -111,6 +113,7 @@ public: tilesetCRC = 0; techCRC = 0; factionCRCList.clear(); + aiAcceptSwitchTeamPercentChance = 30; } // default copy constructor will do fine, and will maintain itself ;) @@ -231,6 +234,9 @@ public: void setFactionCRCList(vector > value) { factionCRCList = value; } + int getAiAcceptSwitchTeamPercentChance() const { return aiAcceptSwitchTeamPercentChance;} + void setAiAcceptSwitchTeamPercentChance(int value) { aiAcceptSwitchTeamPercentChance = value; } + string toString() const { string result = ""; @@ -275,6 +281,8 @@ public: result += "factionCRCList name [" + factionCRCList[i].first + "] CRC = " + intToStr(factionCRCList[i].second) + "\n"; } + result += "aiAcceptSwitchTeamPercentChance = " + intToStr(aiAcceptSwitchTeamPercentChance) + "\n"; + return result; } }; diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 0a13da53..54dd1eef 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -6793,4 +6793,107 @@ void Renderer::renderFPSWhenEnabled(int lastFps) { } } +void Renderer::renderPopupMenu(PopupMenu *menu) { + if(menu->getVisible() == false || menu->getEnabled() == false) { + return; + } + + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10); + glVertex2i(menu->getX(), menu->getY()); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10); + glVertex2i(menu->getX() + menu->getW(), menu->getY()); + glEnd(); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(menu->getX(), menu->getY() + menu->getH()); + glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH()); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10); + glEnd(); + + glBegin(GL_LINE_LOOP); + glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; + glVertex2i(menu->getX(), menu->getY()); + + glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ; + glVertex2i(menu->getX() + menu->getW(), menu->getY()); + + glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; + glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH()); + + glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ; + glVertex2i(menu->getX(), menu->getY() + menu->getH()); + glEnd(); + + glBegin(GL_LINE_STRIP); + glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ; + glVertex2i(menu->getX(), menu->getY() + 90*menu->getH()/100); + + glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; + glVertex2i(menu->getX()+ menu->getW(), menu->getY() + 90*menu->getH()/100); + glEnd(); + + glPopAttrib(); + + Vec4f fontColor; + //if(game!=NULL){ + // fontColor=game->getGui()->getDisplay()->getColor(); + //} + //else { + // white shadowed is default ( in the menu for example ) + fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f); + //} + + if(renderText3DEnabled == true) { + //text + renderTextBoundingBox3D( + menu->getHeader(), menu->getFont3D(),fontColor, + menu->getX(), menu->getY()+93*menu->getH()/100,menu->getW(),0, + true,false ); + + } + else { + //text + renderTextShadow( + menu->getHeader(), menu->getFont(),fontColor, + menu->getX()+15, menu->getY()+93*menu->getH()/100, + true); + } + + //buttons +// int maxButtonWidth = -1; + std::vector &menuItems = menu->getMenuItems(); +// for(unsigned int i = 0; i < menuItems.size(); ++i) { +// GraphicButton *button = &menuItems[i]; +// int currentButtonWidth = -1; +// if(renderText3DEnabled == true) { +// FontMetrics *fontMetrics= menu->getFont3D()->getMetrics(); +// currentButtonWidth = fontMetrics->getTextWidth(button->getText()); +// } +// else { +// FontMetrics *fontMetrics= menu->getFont()->getMetrics(); +// currentButtonWidth = fontMetrics->getTextWidth(button->getText()); +// } +// +// if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) { +// maxButtonWidth = currentButtonWidth + 5; +// } +// } + + for(unsigned int i = 0; i < menuItems.size(); ++i) { + GraphicButton *button = &menuItems[i]; + + //button->setW(maxButtonWidth); + renderButton(button); + } + +} + }}//end namespace diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 8c6be2f7..04924590 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -435,6 +435,7 @@ public: void renderScrollBar(const GraphicScrollBar *sb); void renderListBox(GraphicListBox *listBox); void renderMessageBox(GraphicMessageBox *listBox); + void renderPopupMenu(PopupMenu *menu); //complex rendering void renderSurface(const int renderFps); diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index a314ab97..90d510e2 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -189,6 +189,28 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM listBoxEnableObserverMode.setEditable(false); labelEnableObserverMode.setText(lang.get("EnableObserverMode")); + // Allow Switch Team Mode + labelEnableSwitchTeamMode.registerGraphicComponent(containerName,"labelEnableSwitchTeamMode"); + labelEnableSwitchTeamMode.init(xoffset+150, aHeadPos+40, 80); + labelEnableSwitchTeamMode.setText(lang.get("EnableSwitchTeamMode")); + + listBoxEnableSwitchTeamMode.registerGraphicComponent(containerName,"listBoxEnableSwitchTeamMode"); + listBoxEnableSwitchTeamMode.init(xoffset+150, aPos+40, 80); + listBoxEnableSwitchTeamMode.pushBackItem(lang.get("Yes")); + listBoxEnableSwitchTeamMode.pushBackItem(lang.get("No")); + listBoxEnableSwitchTeamMode.setSelectedItemIndex(1); + + labelAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"labelAISwitchTeamAcceptPercent"); + labelAISwitchTeamAcceptPercent.init(xoffset+250, aHeadPos+40, 80); + labelAISwitchTeamAcceptPercent.setText(lang.get("AISwitchTeamAcceptPercent")); + + listBoxAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"listBoxAISwitchTeamAcceptPercent"); + listBoxAISwitchTeamAcceptPercent.init(xoffset+250, aPos+40, 80); + for(int i = 0; i <= 100; i = i + 10) { + listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i)); + } + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30)); + labelPathFinderType.registerGraphicComponent(containerName,"labelPathFinderType"); labelPathFinderType.init(xoffset+450, aHeadPos, 80); labelPathFinderType.setText(lang.get("PathFinderType")); @@ -1019,6 +1041,9 @@ void MenuStateConnectedGame::render() { renderer.renderLabel(&labelEnableObserverMode); renderer.renderLabel(&labelPathFinderType); + renderer.renderLabel(&labelEnableSwitchTeamMode); + renderer.renderLabel(&labelAISwitchTeamAcceptPercent); + renderer.renderListBox(&listBoxEnableObserverMode); renderer.renderListBox(&listBoxPathFinderType); @@ -1029,6 +1054,9 @@ void MenuStateConnectedGame::render() { renderer.renderLabel(&labelNetworkPauseGameForLaggedClients); renderer.renderListBox(&listBoxNetworkPauseGameForLaggedClients); + renderer.renderListBox(&listBoxEnableSwitchTeamMode); + renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(fileFTPProgressList.empty() == false) { Lang &lang= Lang::getInstance(); @@ -1780,6 +1808,14 @@ void MenuStateConnectedGame::update() { listBoxAllowObservers.setSelectedItemIndex(0); } + if((gameSettings->getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching){ + listBoxEnableSwitchTeamMode.setSelectedItemIndex(0); + } + else { + listBoxEnableSwitchTeamMode.setSelectedItemIndex(1); + } + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(gameSettings->getAiAcceptSwitchTeamPercentChance())); + if(gameSettings->getEnableObserverModeAtEndGame()) { listBoxEnableObserverMode.setSelectedItemIndex(0); } diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index c1bb84fb..54af475e 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -169,6 +169,11 @@ private: std::map > fileFTPProgressList; GraphicButton buttonCancelDownloads; + GraphicLabel labelEnableSwitchTeamMode; + GraphicListBox listBoxEnableSwitchTeamMode; + GraphicLabel labelAISwitchTeamAcceptPercent; + GraphicListBox listBoxAISwitchTeamAcceptPercent; + public: MenuStateConnectedGame(Program *program, MainMenu *mainMenu, JoinMenu joinMenuInfo=jmSimple, bool openNetworkSlots= false); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index fbfe8288..5484cae0 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -305,6 +305,28 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b listBoxEnableObserverMode.pushBackItem(lang.get("No")); listBoxEnableObserverMode.setSelectedItemIndex(0); + // Allow Switch Team Mode + labelEnableSwitchTeamMode.registerGraphicComponent(containerName,"labelEnableSwitchTeamMode"); + labelEnableSwitchTeamMode.init(xoffset+310, aHeadPos+40, 80); + labelEnableSwitchTeamMode.setText(lang.get("EnableSwitchTeamMode")); + + listBoxEnableSwitchTeamMode.registerGraphicComponent(containerName,"listBoxEnableSwitchTeamMode"); + listBoxEnableSwitchTeamMode.init(xoffset+310, aPos+40, 80); + listBoxEnableSwitchTeamMode.pushBackItem(lang.get("Yes")); + listBoxEnableSwitchTeamMode.pushBackItem(lang.get("No")); + listBoxEnableSwitchTeamMode.setSelectedItemIndex(1); + + labelAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"labelAISwitchTeamAcceptPercent"); + labelAISwitchTeamAcceptPercent.init(xoffset+460, aHeadPos+40, 80); + labelAISwitchTeamAcceptPercent.setText(lang.get("AISwitchTeamAcceptPercent")); + + listBoxAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"listBoxAISwitchTeamAcceptPercent"); + listBoxAISwitchTeamAcceptPercent.init(xoffset+460, aPos+40, 80); + for(int i = 0; i <= 100; i = i + 10) { + listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i)); + } + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30)); + // Which Pathfinder labelPathFinderType.registerGraphicComponent(containerName,"labelPathFinderType"); labelPathFinderType.init(xoffset+650, aHeadPos, 80); @@ -768,6 +790,32 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ lastSetChangedGameSettings = time(NULL); } } + else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxEnableSwitchTeamMode.mouseClick(x, y)) { + MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + + if(listBoxPublishServer.getSelectedItemIndex() == 0) { + needToRepublishToMasterserver = true; + } + + if(hasNetworkGameSettings() == true) + { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxAISwitchTeamAcceptPercent.getEnabled() && listBoxAISwitchTeamAcceptPercent.mouseClick(x, y)) { + MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + + if(listBoxPublishServer.getSelectedItemIndex() == 0) { + needToRepublishToMasterserver = true; + } + + if(hasNetworkGameSettings() == true) + { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxPathFinderType.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); @@ -1309,6 +1357,9 @@ void MenuStateCustomGame::mouseMove(int x, int y, const MouseState *ms){ //labelNetworkFramePeriod.mouseMove(x, y); //listBoxNetworkFramePeriod.mouseMove(x, y); + listBoxEnableSwitchTeamMode.mouseMove(x, y); + listBoxAISwitchTeamAcceptPercent.mouseMove(x, y); + labelNetworkPauseGameForLaggedClients.mouseMove(x, y); listBoxNetworkPauseGameForLaggedClients.mouseMove(x, y); @@ -1443,10 +1494,16 @@ void MenuStateCustomGame::render() { renderer.renderLabel(&labelEnableObserverMode); renderer.renderLabel(&labelPathFinderType); + renderer.renderLabel(&labelEnableSwitchTeamMode); + renderer.renderLabel(&labelAISwitchTeamAcceptPercent); + renderer.renderListBox(&listBoxFogOfWar); renderer.renderListBox(&listBoxAllowObservers); renderer.renderListBox(&listBoxEnableObserverMode); renderer.renderListBox(&listBoxPathFinderType); + + renderer.renderListBox(&listBoxEnableSwitchTeamMode); + renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent); } renderer.renderLabel(&labelTileset); renderer.renderLabel(&labelMapFilter); @@ -1747,6 +1804,8 @@ void MenuStateCustomGame::update() { GameSettings gameSettings; loadGameSettings(&gameSettings); + listBoxAISwitchTeamAcceptPercent.setEnabled(listBoxEnableSwitchTeamMode.getSelectedItemIndex() == 0); + int factionCount = 0; for(int i= 0; i< mapInfo.players; ++i) { if(hasNetworkGameSettings() == true) { @@ -2332,6 +2391,17 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); + valueFlags1 = gameSettings->getFlagTypes1(); + if(listBoxEnableSwitchTeamMode.getSelectedItemIndex() == 0) { + valueFlags1 |= ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } + else { + valueFlags1 &= ~ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } + gameSettings->setAiAcceptSwitchTeamPercentChance(strToInt(listBoxAISwitchTeamAcceptPercent.getSelectedItem())); + // First save Used slots //for(int i=0; i(properties.getInt("PathFinderType",intToStr(pfBasic).c_str()))); gameSettings.setEnableServerControlledAI(properties.getBool("EnableServerControlledAI","true")); gameSettings.setNetworkFramePeriod(properties.getInt("NetworkFramePeriod",intToStr(GameConstants::networkFramePeriod).c_str())); @@ -2717,6 +2793,10 @@ void MenuStateCustomGame::setupUIFromGameSettings(const GameSettings &gameSettin listBoxAllowObservers.setSelectedItem(gameSettings.getAllowObservers() == true ? lang.get("Yes") : lang.get("No")); listBoxEnableObserverMode.setSelectedItem(gameSettings.getEnableObserverModeAtEndGame() == true ? lang.get("Yes") : lang.get("No")); + + listBoxEnableSwitchTeamMode.setSelectedItem((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching ? lang.get("Yes") : lang.get("No")); + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(gameSettings.getAiAcceptSwitchTeamPercentChance())); + listBoxPathFinderType.setSelectedItemIndex(gameSettings.getPathFinderType()); //listBoxEnableServerControlledAI.setSelectedItem(gameSettings.getEnableServerControlledAI() == true ? lang.get("Yes") : lang.get("No")); diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index b6a678c8..5ad7bcbd 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -102,6 +102,11 @@ private: GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; GraphicListBox listBoxPlayerStatus; + GraphicLabel labelEnableSwitchTeamMode; + GraphicListBox listBoxEnableSwitchTeamMode; + GraphicLabel labelAISwitchTeamAcceptPercent; + GraphicListBox listBoxAISwitchTeamAcceptPercent; + bool needToSetChangedGameSettings; time_t lastSetChangedGameSettings; time_t lastMasterserverPublishing; diff --git a/source/glest_game/menu/menu_state_root.cpp b/source/glest_game/menu/menu_state_root.cpp index 161f3fb2..a4340c8d 100644 --- a/source/glest_game/menu/menu_state_root.cpp +++ b/source/glest_game/menu/menu_state_root.cpp @@ -78,6 +78,17 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu): mainMessageBox.init(lang.get("Yes"), lang.get("No")); mainMessageBox.setEnabled(false); + //PopupMenu popupMenu; + std::vector menuItems; + menuItems.push_back("1"); + menuItems.push_back("2"); + menuItems.push_back("3"); + popupMenu.setW(100); + popupMenu.setH(100); + popupMenu.init("Test Menu",menuItems); + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + GraphicComponent::applyAllCustomProperties(containerName); } @@ -86,7 +97,12 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){ CoreData &coreData= CoreData::getInstance(); SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - if(mainMessageBox.getEnabled() == false && buttonNewGame.mouseClick(x, y)){ + if(popupMenu.mouseClick(x, y)) { + std::pair result = popupMenu.mouseClickedMenuItem(x, y); + + printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + } + else if(mainMessageBox.getEnabled() == false && buttonNewGame.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); mainMenu->setState(new MenuStateNewGame(program, mainMenu)); } @@ -125,6 +141,7 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){ } void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){ + popupMenu.mouseMove(x, y); buttonNewGame.mouseMove(x, y); buttonMods.mouseMove(x, y); buttonOptions.mouseMove(x, y); @@ -187,6 +204,7 @@ void MenuStateRoot::render() { currentX += extraLogo->getPixmap()->getW(); } + renderer.renderButton(&buttonNewGame); renderer.renderButton(&buttonMods); renderer.renderButton(&buttonOptions); @@ -196,10 +214,13 @@ void MenuStateRoot::render() { renderer.renderConsole(&console,false,true); + renderer.renderPopupMenu(&popupMenu); + //exit message box if(mainMessageBox.getEnabled()) { renderer.renderMessageBox(&mainMessageBox); } + if(program != NULL) program->renderProgramMsgBox(); } diff --git a/source/glest_game/menu/menu_state_root.h b/source/glest_game/menu/menu_state_root.h index a01562d7..493e6e24 100644 --- a/source/glest_game/menu/menu_state_root.h +++ b/source/glest_game/menu/menu_state_root.h @@ -22,6 +22,7 @@ namespace Glest{ namespace Game{ // =============================== class GraphicMessageBox; +class PopupMenu; class MenuStateRoot: public MenuState { private: @@ -34,6 +35,8 @@ private: GraphicMessageBox mainMessageBox; + PopupMenu popupMenu; + public: MenuStateRoot(Program *program, MainMenu *mainMenu); diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index ebda5413..137ddfe1 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -230,6 +230,7 @@ NetworkMessageLaunch::NetworkMessageLaunch() { data.factionNameList[i] = ""; data.factionCRCList[i] = 0; } + data.aiAcceptSwitchTeamPercentChance = 0; } NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType) { @@ -278,6 +279,8 @@ NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 data.teams[i]= gameSettings->getTeam(i); data.startLocationIndex[i]= gameSettings->getStartLocationIndex(i); } + + data.aiAcceptSwitchTeamPercentChance = gameSettings->getAiAcceptSwitchTeamPercentChance(); } void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { @@ -322,6 +325,8 @@ void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { gameSettings->setTeam(i, data.teams[i]); gameSettings->setStartLocationIndex(i, data.startLocationIndex[i]); } + + gameSettings->setAiAcceptSwitchTeamPercentChance(data.aiAcceptSwitchTeamPercentChance); } vector > NetworkMessageLaunch::getFactionCRCList() const { diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index f9637a37..3f7417e7 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -232,6 +232,8 @@ private: int8 networkPauseGameForLaggedClients; int8 pathFinderType; uint32 flagTypes1; + + int8 aiAcceptSwitchTeamPercentChance; }; private: diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 61e2088a..3054b31c 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -65,7 +65,9 @@ public: enum NetworkCommandType { nctGiveCommand, nctCancelCommand, - nctSetMeetingPoint + nctSetMeetingPoint, + nctSwitchTeam, + nctSwitchTeamVote //nctNetworkCommand }; diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index 1155c3c4..34cccdf3 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -34,17 +34,60 @@ CommandGroupSorter::CommandGroupSorter() { this->unit = NULL; } +CommandGroupSorter::~CommandGroupSorter() { + this->unit = NULL; +} + CommandGroupSorter::CommandGroupSorter(Unit *unit) { this->unit = unit; } -bool CommandGroupSorter::operator< (const CommandGroupSorter *j) const { - return operator<(*j); +CommandGroupSorter::CommandGroupSorter(const CommandGroupSorter &obj) { + copyAll(obj); +} + +CommandGroupSorter::CommandGroupSorter(const CommandGroupSorter *obj) { + if(obj != NULL) { + copyAll(*obj); + } +} + +CommandGroupSorter & CommandGroupSorter::operator=(const CommandGroupSorter &obj) { + copyAll(obj); + return *this; } -bool CommandGroupSorter::compare(const CommandGroupSorter *l, const CommandGroupSorter *r) { - return (*l < *r); +void CommandGroupSorter::copyAll(const CommandGroupSorter &obj) { + if(this != &obj) { + this->unit = obj.unit; + } +} + +bool CommandGroupSorter::comparePtr(const CommandGroupSorter *l, const CommandGroupSorter *r) { + if(!l) { + printf("Error l == NULL\n"); + } + if(!r) { + printf("Error r == NULL\n"); + } + + assert(l && r); + + if(l->unit == NULL || r->unit == NULL) + printf("Unit l [%s - %d] r [%s - %d]\n", + (l->unit != NULL ? l->unit->getType()->getName().c_str() : "null"), + (l->unit != NULL ? l->unit->getId() : -1), + (r->unit != NULL ? r->unit->getType()->getName().c_str() : "null"), + (r->unit != NULL ? r->unit->getId() : -1)); + + const CommandGroupSorter &lRef = *l; + const CommandGroupSorter &rRef = *r; + return (lRef < rRef); +} + +bool CommandGroupSorter::compare(const CommandGroupSorter &l, const CommandGroupSorter &r) { + return (l < r); } bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const { @@ -1456,6 +1499,35 @@ int Faction::getFrameCount() { return frameCount; } +const SwitchTeamVote * Faction::getFirstSwitchTeamVote() const { + const SwitchTeamVote *vote = NULL; + if(switchTeamVotes.size() > 0) { + for(std::map::const_iterator iterMap = switchTeamVotes.begin(); + iterMap != switchTeamVotes.end(); ++iterMap) { + const SwitchTeamVote &curVote = iterMap->second; + if(curVote.voted == false) { + vote = &curVote; + break; + } + } + } + + return vote; +} + +SwitchTeamVote * Faction::getSwitchTeamVote(int factionIndex) { + SwitchTeamVote *vote = NULL; + if(switchTeamVotes.find(factionIndex) != switchTeamVotes.end()) { + vote = &switchTeamVotes[factionIndex]; + } + + return vote; +} + +void Faction::setSwitchTeamVote(SwitchTeamVote &vote) { + switchTeamVotes[vote.factionIndex] = vote; +} + std::string Faction::toString() const { std::string result = ""; diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 83d5025c..e598861d 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -54,10 +54,17 @@ public: Unit *unit; CommandGroupSorter(); + ~CommandGroupSorter(); CommandGroupSorter(Unit *unit); + CommandGroupSorter(const CommandGroupSorter &obj); + CommandGroupSorter(const CommandGroupSorter *obj); + CommandGroupSorter & operator=(const CommandGroupSorter &obj); bool operator< (const CommandGroupSorter &j) const; - bool operator< (const CommandGroupSorter *j) const; - bool static compare(const CommandGroupSorter *l, const CommandGroupSorter *r); + static bool comparePtr(const CommandGroupSorter *l, const CommandGroupSorter *r); + static bool compare(const CommandGroupSorter &l, const CommandGroupSorter &r); + +protected: + void copyAll(const CommandGroupSorter &obj); }; class FactionThread : public BaseThread { @@ -80,6 +87,16 @@ public: bool isSignalPathfinderCompleted(int frameIndex); }; +class SwitchTeamVote { +public: + + int factionIndex; + int oldTeam; + int newTeam; + bool voted; + bool allowSwitchTeam; +}; + class Faction { private: typedef vector Resources; @@ -119,6 +136,9 @@ private: RandomGen random; FactionThread *workerThread; + std::map switchTeamVotes; + int currentSwitchTeamVoteFactionIndex; + public: Faction(); ~Faction(); @@ -137,7 +157,16 @@ public: int getStoreAmount(const ResourceType *rt) const; const FactionType *getType() const {return factionType;} int getIndex() const {return index;} + int getTeam() const {return teamIndex;} + void setTeam(int team) {teamIndex=team;} + + const SwitchTeamVote * getFirstSwitchTeamVote() const; + SwitchTeamVote * getSwitchTeamVote(int factionIndex); + void setSwitchTeamVote(SwitchTeamVote &vote); + int getCurrentSwitchTeamVoteFactionIndex() const { return currentSwitchTeamVoteFactionIndex; } + void setCurrentSwitchTeamVoteFactionIndex(int index) { currentSwitchTeamVoteFactionIndex = index; } + bool getCpuControl(bool enableServerControlledAI, bool isNetworkGame, NetworkRole role) const; bool getCpuControl() const; bool getCpuEasyControl() const {return control==ctCpuEasy;} diff --git a/source/glest_game/types/command_type.cpp b/source/glest_game/types/command_type.cpp index 8caccfcb..b2c86ade 100644 --- a/source/glest_game/types/command_type.cpp +++ b/source/glest_game/types/command_type.cpp @@ -818,6 +818,62 @@ const ProducibleType *MorphCommandType::getProduced() const{ return morphUnit; } +// ===================================================== +// class SwitchTeamCommandType +// ===================================================== + +//varios +SwitchTeamCommandType::SwitchTeamCommandType(){ + commandTypeClass= ccSwitchTeam; + clicks= cOne; +} + +void SwitchTeamCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const { + unitUpdater->updateSwitchTeam(unit, frameIndex); +} + +void SwitchTeamCommandType::load(int id, const XmlNode *n, const string &dir, + const TechTree *tt, const FactionType *ft, const UnitType &ut, + std::map > > &loadedFileList, string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, parentLoader); + + //morph skill + //string skillName= n->getChild("morph-skill")->getAttribute("value")->getRestrictedValue(); + //morphSkillType= static_cast(ut.getSkillType(skillName, scMorph)); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +string SwitchTeamCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{ + string str= name+"\n"; + Lang &lang= Lang::getInstance(); + + //prod speed + //str+= lang.get("MorphSpeed")+": "+ intToStr(morphSkillType->getSpeed())+"\n"; + + //mpcost +// if(morphSkillType->getEpCost()!=0){ +// str+= lang.get("EpCost")+": "+intToStr(morphSkillType->getEpCost())+"\n"; +// } +// if(morphSkillType->getHpCost()!=0){ +// str+= lang.get("HpCost")+": "+intToStr(morphSkillType->getHpCost())+"\n"; +// } +// +// //discount +// if(discount!=0){ +// str+= lang.get("Discount")+": "+intToStr(discount)+"%\n"; +// } +// +// str+= "\n"+getProduced()->getReqDesc(); + + return str; +} + +string SwitchTeamCommandType::toString() const{ + Lang &lang= Lang::getInstance(); + return lang.get("SwitchTeam"); +} + // ===================================================== // class CommandFactory // ===================================================== @@ -833,6 +889,7 @@ CommandTypeFactory::CommandTypeFactory(){ registerClass("produce"); registerClass("upgrade"); registerClass("morph"); + registerClass("switch_team"); } CommandTypeFactory &CommandTypeFactory::getInstance(){ diff --git a/source/glest_game/types/command_type.h b/source/glest_game/types/command_type.h index 6bdb4710..bab149cc 100644 --- a/source/glest_game/types/command_type.h +++ b/source/glest_game/types/command_type.h @@ -42,6 +42,7 @@ enum CommandClass { ccProduce, ccUpgrade, ccMorph, + ccSwitchTeam, ccCount, ccNull @@ -381,6 +382,24 @@ public: int getDiscount() const {return discount;} }; +// =============================== +// class SwitchTeamCommandType +// =============================== + +class SwitchTeamCommandType: public CommandType { +private: + + +public: + SwitchTeamCommandType(); + virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const; + virtual void load(int id, const XmlNode *n, const string &dir, + const TechTree *tt, const FactionType *ft, const UnitType &ut, + std::map > > &loadedFileList, string parentLoader); + virtual string getDesc(const TotalUpgrade *totalUpgrade) const; + virtual string toString() const; +}; + // =============================== // class CommandFactory // =============================== diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 2f55e013..c706c10c 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -1882,6 +1882,62 @@ void UnitUpdater::updateMorph(Unit *unit, int frameIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); } + +// ==================== updateMove ==================== +void UnitUpdater::updateSwitchTeam(Unit *unit, int frameIndex) { +// Chrono chrono; +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); +// +// Command *command= unit->getCurrCommand(); +// const MoveCommandType *mct= static_cast(command->getCommandType()); +// +// Vec2i pos= command->getUnit()!=NULL? command->getUnit()->getCenteredPos(): command->getPos(); +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { +// char szBuf[4096]=""; +// sprintf(szBuf,"[updateMove] pos [%s] unit [%d - %s] cmd [%s]",pos.getString().c_str(),unit->getId(),unit->getFullName().c_str(),command->toString().c_str()); +// unit->logSynchData(__FILE__,__LINE__,szBuf); +// } +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +// +// TravelState tsValue = tsImpossible; +// switch(this->game->getGameSettings()->getPathFinderType()) { +// case pfBasic: +// tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex); +// break; +// case pfRoutePlanner: +// tsValue = routePlanner->findPath(unit, pos); +// break; +// default: +// throw runtime_error("detected unsupported pathfinder type!"); +// } +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +// +// if(frameIndex < 0) { +// switch (tsValue) { +// case tsMoving: +// unit->setCurrSkill(mct->getMoveSkillType()); +// break; +// +// case tsBlocked: +// unit->setCurrSkill(scStop); +// if(unit->getPath()->isBlocked()){ +// unit->finishCommand(); +// } +// break; +// +// default: +// unit->finishCommand(); +// } +// } +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +} + + +// ==================== updateAttack ==================== + // ==================== PRIVATE ==================== // ==================== attack ==================== diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index e752fc72..c5557ae8 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -111,6 +111,7 @@ public: void updateProduce(Unit *unit, int frameIndex); void updateUpgrade(Unit *unit, int frameIndex); void updateMorph(Unit *unit, int frameIndex); + void updateSwitchTeam(Unit *unit, int frameIndex); void clearUnitPrecache(Unit *unit); void removeUnitPrecache(Unit *unit); diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 0f829186..603d6db5 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -306,7 +306,7 @@ void World::updateAllFactionUnits() { } if(unitListToSort.empty() == false) { //printf("About to Sort...\n"); - std::sort(unitListToSort.begin(),unitListToSort.end(),CommandGroupSorter::compare); + std::sort(unitListToSort.begin(),unitListToSort.end(),CommandGroupSorter::comparePtr); } if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { @@ -332,8 +332,8 @@ void World::updateAllFactionUnits() { } if(sortedUnitsAllowed == true) { - std::vector &unitListSorted = unitsInFactionsSorted[faction->getIndex()]; - faction->signalWorkerThread(frameCount,&unitListSorted); + std::vector *unitListSorted = &unitsInFactionsSorted[faction->getIndex()]; + faction->signalWorkerThread(frameCount,unitListSorted); } else { faction->signalWorkerThread(frameCount,NULL); @@ -394,11 +394,6 @@ void World::updateAllFactionUnits() { } unitUpdater.updateUnit(unit); - - if(sortedUnitsAllowed == true) { - delete (*unitListSorted)[j]; - (*unitListSorted)[j] = NULL; - } } // int unitCount = faction->getUnitCount(); @@ -412,7 +407,31 @@ void World::updateAllFactionUnits() { // } } - unitsInFactionsSorted.clear(); + if(sortedUnitsAllowed == true) { + if(workThreadsFinished == false) { + sleep(0); + } + for(int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + if(faction == NULL) { + throw runtime_error("faction == NULL"); + } + + std::vector *unitListSorted = &unitsInFactionsSorted[faction->getIndex()]; + unsigned int unitCount = unitListSorted->size(); + + for(int j = 0; j < unitCount; ++j) { + Unit *unit = (*unitListSorted)[j]->unit; + if(unit == NULL) { + throw runtime_error("unit == NULL"); + } + + delete (*unitListSorted)[j]; + (*unitListSorted)[j] = NULL; + } + } + unitsInFactionsSorted.clear(); + } if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount); } @@ -1713,6 +1732,10 @@ void World::computeFow(int factionIdxToTick) { } } +GameSettings * World::getGameSettingsPtr() { + return (game != NULL ? game->getGameSettings() : NULL); +} + const GameSettings * World::getGameSettings() const { return (game != NULL ? game->getReadOnlyGameSettings() : NULL); } diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index 08763d4e..74e0a7db 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -150,8 +150,13 @@ public: //get int getMaxPlayers() const {return map.getMaxPlayers();} int getThisFactionIndex() const {return thisFactionIndex;} + int getThisTeamIndex() const {return thisTeamIndex;} + void setThisTeamIndex(int team) { thisTeamIndex=team;} + const Faction *getThisFaction() const {return &factions[thisFactionIndex];} + Faction *getThisFactionPtr() {return &factions[thisFactionIndex];} + int getFactionCount() const {return factions.size();} const Map *getMap() const {return ↦} const Tileset *getTileset() const {return &tileset;} @@ -223,6 +228,8 @@ public: Game * getGame() { return game; } const GameSettings * getGameSettings() const; + GameSettings * getGameSettingsPtr(); + std::vector validateFactionTypes(); std::vector validateResourceTypes();