diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 1d3f6c4f..72e8f8a4 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -943,7 +943,7 @@ void Game::init(bool initForPreviewOnly) { Window::handleEvent(); SDL_PumpEvents(); - if(world.getFactionCount() == 1 && world.getFaction(0)->getType()->getPersonalityType() == fpt_Observer) { + if(world.getFactionCount() == 1 && world.getFaction(0)->getPersonalityType() == fpt_Observer) { withRainEffect = false; } @@ -1056,6 +1056,15 @@ void Game::init(bool initForPreviewOnly) { setupPopupMenus(false); + for(int i=0; i < world.getFactionCount(); ++i) { + Faction *faction= world.getFaction(i); + + //printf("Check for team switch to observer i = %d, team = %d [%d]\n",i,faction->getTeam(),(GameConstants::maxPlayers -1 + fpt_Observer)); + if(faction != NULL && faction->getTeam() == GameConstants::maxPlayers -1 + fpt_Observer) { + faction->setPersonalityType(fpt_Observer); + world.getStats()->setPersonalityType(i, faction->getPersonalityType()); + } + } gameStarted = true; if(this->masterserverMode == true) { @@ -1105,7 +1114,7 @@ void Game::setupPopupMenus(bool checkClientAdminOverrideOnly) { exitGamePopupMenuIndex = menuItems.size()-1; if((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching && - world.getThisFaction() != NULL && world.getThisFaction()->getType()->getPersonalityType() != fpt_Observer) { + world.getThisFaction() != NULL && world.getThisFaction()->getPersonalityType() != fpt_Observer) { menuItems.push_back(lang.get("JoinOtherTeam")); joinTeamPopupMenuIndex = menuItems.size()-1; } @@ -1512,7 +1521,7 @@ void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRo faction->setFactionDisconnectHandled(true); char szBuf[1024]=""; - if(faction->getType()->getPersonalityType() != fpt_Observer) { + if(faction->getPersonalityType() != fpt_Observer) { faction->setControlType(ctCpu); aiInterfaces[i] = new AiInterface(*this, i, faction->getTeam(), faction->getStartLocationIndex()); @@ -1776,12 +1785,12 @@ void Game::mouseDownLeft(int x, int y) { for(unsigned int i = 0; i < world.getFactionCount(); ++i) { Faction *faction = world.getFaction(i); - if(faction->getType()->getPersonalityType() != fpt_Observer && + if(faction->getPersonalityType() != fpt_Observer && uniqueTeamNumbersUsed.find(faction->getTeam()) == uniqueTeamNumbersUsed.end()) { uniqueTeamNumbersUsed[faction->getTeam()] = true; } - if(faction->getType()->getPersonalityType() != fpt_Observer && + if(faction->getPersonalityType() != fpt_Observer && world.getThisFaction()->getIndex() != faction->getIndex() && world.getThisFaction()->getTeam() != faction->getTeam()) { char szBuf[1024]=""; @@ -3213,7 +3222,7 @@ void Game::checkWinner() { } void Game::checkWinnerStandard() { - if(this->masterserverMode == true || world.getThisFaction()->getType()->getPersonalityType() == fpt_Observer) { + if(this->masterserverMode == true || world.getThisFaction()->getPersonalityType() == fpt_Observer) { // lookup int is team #, value is players alive on team std::map teamsAlive; for(int i = 0; i < world.getFactionCount(); ++i) { @@ -3246,7 +3255,7 @@ void Game::checkWinnerStandard() { scriptManager.onGameOver(true); - if(world.getFactionCount() == 1 && world.getFaction(0)->getType()->getPersonalityType() == fpt_Observer) { + if(world.getFactionCount() == 1 && world.getFaction(0)->getPersonalityType() == fpt_Observer) { //printf("!!!!!!!!!!!!!!!!!!!!"); //gameCamera.setMoveY(100.0); @@ -3264,7 +3273,7 @@ void Game::checkWinnerStandard() { if(hasBuilding(world.getThisFaction()) == false) { lose= true; for(int i=0; igetType()->getPersonalityType() != fpt_Observer) { + if(world.getFaction(i)->getPersonalityType() != fpt_Observer) { if(world.getFaction(i)->isAlly(world.getThisFaction()) == false) { world.getStats()->setVictorious(i); } @@ -3296,7 +3305,7 @@ void Game::checkWinnerStandard() { bool win= true; for(int i = 0; i < world.getFactionCount(); ++i) { if(i != world.getThisFactionIndex()) { - if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) { + if(world.getFaction(i)->getPersonalityType() != fpt_Observer) { if(hasBuilding(world.getFaction(i)) && world.getFaction(i)->isAlly(world.getThisFaction()) == false) { win= false; } @@ -3307,7 +3316,7 @@ void Game::checkWinnerStandard() { //if win if(win) { for(int i=0; i< world.getFactionCount(); ++i) { - if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) { + if(world.getFaction(i)->getPersonalityType() != fpt_Observer) { if(world.getFaction(i)->isAlly(world.getThisFaction())) { world.getStats()->setVictorious(i); } @@ -3461,7 +3470,7 @@ void Game::showLoseMessageBox() { void Game::showWinMessageBox() { Lang &lang= Lang::getInstance(); - if(this->masterserverMode == true || world.getThisFaction()->getType()->getPersonalityType() == fpt_Observer) { + if(this->masterserverMode == true || world.getThisFaction()->getPersonalityType() == fpt_Observer) { showMessageBox(lang.get("GameOver")+" "+lang.get("ExitGame?"), lang.get("BattleOver"), false); } else { diff --git a/source/glest_game/game/script_manager.cpp b/source/glest_game/game/script_manager.cpp index 33b4ba66..5db9b9cf 100644 --- a/source/glest_game/game/script_manager.cpp +++ b/source/glest_game/game/script_manager.cpp @@ -47,12 +47,16 @@ public: ScriptManagerMessage::ScriptManagerMessage() { this->text= ""; this->header= ""; - + this->factionIndex=-1; + this->teamIndex=-1; } -ScriptManagerMessage::ScriptManagerMessage(string text, string header) { - this->text= text; - this->header= header; +ScriptManagerMessage::ScriptManagerMessage(string text, string header, + int factionIndex,int teamIndex) { + this->text = text; + this->header = header; + this->factionIndex = factionIndex; + this->teamIndex = teamIndex; } void ScriptManagerMessage::saveGame(XmlNode *rootNode) { @@ -63,6 +67,8 @@ void ScriptManagerMessage::saveGame(XmlNode *rootNode) { scriptManagerMessageNode->addAttribute("text",text, mapTagReplacements); //string header; scriptManagerMessageNode->addAttribute("header",header, mapTagReplacements); + scriptManagerMessageNode->addAttribute("factionIndex",intToStr(factionIndex), mapTagReplacements); + scriptManagerMessageNode->addAttribute("teamIndex",intToStr(teamIndex), mapTagReplacements); } void ScriptManagerMessage::loadGame(const XmlNode *rootNode) { @@ -70,6 +76,8 @@ void ScriptManagerMessage::loadGame(const XmlNode *rootNode) { text = scriptManagerMessageNode->getAttribute("text")->getValue(); header = scriptManagerMessageNode->getAttribute("header")->getValue(); + factionIndex = scriptManagerMessageNode->getAttribute("factionIndex")->getIntValue(); + teamIndex = scriptManagerMessageNode->getAttribute("header")->getIntValue(); } // ===================================================== @@ -223,6 +231,9 @@ void ScriptManager::init(World* world, GameCamera *gameCamera, const XmlNode *ro //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //register functions + luaScript.registerFunction(networkShowMessageForFaction, "networkShowMessageForFaction"); + luaScript.registerFunction(networkShowMessageForTeam, "networkShowMessageForTeam"); + luaScript.registerFunction(showMessage, "showMessage"); luaScript.registerFunction(setDisplayText, "setDisplayText"); luaScript.registerFunction(addConsoleText, "addConsoleText"); @@ -365,11 +376,21 @@ void ScriptManager::onMessageBoxOk() { Lang &lang= Lang::getInstance(); - if(messageQueue.empty() == false) { + for(;messageQueue.empty() == false;) { messageQueue.pop_front(); if(messageQueue.empty() == false) { - messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount)); - messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader())); +// printf("onMessageBoxOk [%s] factionIndex = %d [%d] teamIndex = %d [%d][%d]\n", +// wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount).c_str(), +// messageQueue.front().getFactionIndex(), this->world->getThisFactionIndex(), +// messageQueue.front().getTeamIndex(),this->world->getThisTeamIndex(),this->world->getThisFaction()->getTeam()); + + if((messageQueue.front().getFactionIndex() < 0 && messageQueue.front().getTeamIndex() < 0) || + messageQueue.front().getFactionIndex() == this->world->getThisFactionIndex() || + messageQueue.front().getTeamIndex() == this->world->getThisTeamIndex()) { + messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount)); + messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader())); + break; + } } } } @@ -643,6 +664,34 @@ string ScriptManager::wrapString(const string &str, int wrapCount){ return returnString; } +void ScriptManager::networkShowMessageForFaction(const string &text, const string &header,int factionIndex) { + ScriptManager_STREFLOP_Wrapper streflopWrapper; + + Lang &lang= Lang::getInstance(); + + messageQueue.push_back(ScriptManagerMessage(text, header, factionIndex)); + + if(factionIndex == this->world->getThisFactionIndex()) { + messageBox.setEnabled(true); + messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount)); + messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader())); + } +} +void ScriptManager::networkShowMessageForTeam(const string &text, const string &header,int teamIndex) { + ScriptManager_STREFLOP_Wrapper streflopWrapper; + + Lang &lang= Lang::getInstance(); + + // Team indexes are 0 based internally (but 1 based in the lua script) so convert + teamIndex--; + messageQueue.push_back(ScriptManagerMessage(text, header, -1, teamIndex)); + if(teamIndex == this->world->getThisTeamIndex()) { + messageBox.setEnabled(true); + messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount)); + messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader())); + } +} + void ScriptManager::showMessage(const string &text, const string &header){ ScriptManager_STREFLOP_Wrapper streflopWrapper; @@ -1294,6 +1343,18 @@ int ScriptManager::showMessage(LuaHandle* luaHandle){ return luaArguments.getReturnCount(); } +int ScriptManager::networkShowMessageForFaction(LuaHandle* luaHandle){ + LuaArguments luaArguments(luaHandle); + thisScriptManager->networkShowMessageForFaction(luaArguments.getString(-3), luaArguments.getString(-2), luaArguments.getInt(-1)); + return luaArguments.getReturnCount(); +} + +int ScriptManager::networkShowMessageForTeam(LuaHandle* luaHandle){ + LuaArguments luaArguments(luaHandle); + thisScriptManager->networkShowMessageForTeam(luaArguments.getString(-3), luaArguments.getString(-2), luaArguments.getInt(-1)); + return luaArguments.getReturnCount(); +} + int ScriptManager::setDisplayText(LuaHandle* luaHandle){ LuaArguments luaArguments(luaHandle); thisScriptManager->setDisplayText(luaArguments.getString(-1)); diff --git a/source/glest_game/game/script_manager.h b/source/glest_game/game/script_manager.h index b72771b9..12bc57f7 100644 --- a/source/glest_game/game/script_manager.h +++ b/source/glest_game/game/script_manager.h @@ -47,12 +47,16 @@ class ScriptManagerMessage { private: string text; string header; + int factionIndex; + int teamIndex; public: ScriptManagerMessage(); - ScriptManagerMessage(string text, string header); + ScriptManagerMessage(string text, string header, int factionIndex=-1,int teamIndex=-1); const string &getText() const {return text;} const string &getHeader() const {return header;} + int getFactionIndex() const {return factionIndex;} + int getTeamIndex() const {return teamIndex;} void saveGame(XmlNode *rootNode); void loadGame(const XmlNode *rootNode); @@ -220,6 +224,9 @@ private: string wrapString(const string &str, int wrapCount); //wrappers, commands + void networkShowMessageForFaction(const string &text, const string &header,int factionIndex); + void networkShowMessageForTeam(const string &text, const string &header,int teamIndex); + void showMessage(const string &text, const string &header); void clearDisplayText(); void setDisplayText(const string &text); @@ -312,6 +319,9 @@ private: void loadScenario(const string &name, bool keepFactions); //callbacks, commands + static int networkShowMessageForFaction(LuaHandle* luaHandle); + static int networkShowMessageForTeam(LuaHandle* luaHandle); + static int showMessage(LuaHandle* luaHandle); static int setDisplayText(LuaHandle* luaHandle); static int addConsoleText(LuaHandle* luaHandle); diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index 9faab4b9..e648fb5a 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -385,6 +385,8 @@ Faction::Faction() { loadWorldNode = NULL; techTree = NULL; + + overridePersonalityType = fpt_EndCount; } Faction::~Faction() { @@ -442,6 +444,14 @@ void Faction::end() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } + +FactionPersonalityType Faction::getPersonalityType() const { + if(overridePersonalityType != fpt_EndCount) { + return overridePersonalityType; + } + return factionType->getPersonalityType(); +} + Unit * Faction::getUnit(int i) const { Unit *result = units[i]; return result; @@ -964,7 +974,8 @@ bool Faction::checkCosts(const ProducibleType *pt,const CommandType *ct) { bool Faction::isAlly(const Faction *faction) { assert(faction != NULL); - return teamIndex==faction->getTeam(); + return (teamIndex == faction->getTeam() || + faction->getTeam() == GameConstants::maxPlayers -1 + fpt_Observer); } // ================== misc ================== @@ -1865,6 +1876,8 @@ void Faction::saveGame(XmlNode *rootNode) { // // ControlType control; factionNode->addAttribute("control",intToStr(control), mapTagReplacements); + + factionNode->addAttribute("overridePersonalityType",intToStr(overridePersonalityType), mapTagReplacements); // Texture2D *texture; // FactionType *factionType; factionNode->addAttribute("factiontype",factionType->getName(), mapTagReplacements); @@ -1970,6 +1983,11 @@ void Faction::loadGame(const XmlNode *rootNode, int factionIndex,GameSettings *s // ControlType control; control = static_cast(factionNode->getAttribute("control")->getIntValue()); + + if(factionNode->hasAttribute("overridePersonalityType") == true) { + overridePersonalityType = static_cast(factionNode->getAttribute("overridePersonalityType")->getIntValue()); + } + // Texture2D *texture; // FactionType *factionType; //factionNode->addAttribute("factiontype",factionType->getName(), mapTagReplacements); diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 43e2a57a..2d8acee8 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -113,6 +113,7 @@ private: World *world; ScriptManager *scriptManager; + FactionPersonalityType overridePersonalityType; ControlType control; Texture2D *texture; @@ -185,6 +186,8 @@ public: bool getCpuUltraControl() const {return control==ctCpuUltra;} bool getCpuMegaControl() const {return control==ctCpuMega;} ControlType getControlType() const {return control;} + FactionPersonalityType getPersonalityType() const; + void setPersonalityType(FactionPersonalityType pType) { overridePersonalityType=pType; } Unit *getUnit(int i) const; int getUnitCount() const; diff --git a/source/glest_game/world/scenario.cpp b/source/glest_game/world/scenario.cpp index 226003a4..50eb5d67 100644 --- a/source/glest_game/world/scenario.cpp +++ b/source/glest_game/world/scenario.cpp @@ -174,7 +174,7 @@ void Scenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo) { string factionTypeName=""; ControlType factionControl; - if(playersNode->hasChildAtIndex("player",i)){ + if(playersNode->hasChildAtIndex("player",i)) { playerNode = playersNode->getChild("player", i); factionControl = strToControllerType( playerNode->getAttribute("control")->getValue() ); @@ -206,13 +206,13 @@ void Scenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo) { if(factionControl != ctClosed) { int teamIndex = playerNode->getAttribute("team")->getIntValue(); - if( teamIndex < 1 || teamIndex > GameConstants::maxPlayers ) { + if( teamIndex < 1 || teamIndex > GameConstants::maxPlayers + GameConstants::specialFactions) { char szBuf[4096]=""; sprintf(szBuf,"Invalid team value specified in scenario: %d must be between %d and %d",teamIndex,1,GameConstants::maxPlayers); throw std::runtime_error(szBuf); } - scenarioInfo->teams[i]= playerNode->getAttribute("team")->getIntValue(); + scenarioInfo->teams[i]= teamIndex; scenarioInfo->factionTypeNames[i]= playerNode->getAttribute("faction")->getValue(); } else { diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 61bb5c60..17eb3276 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -941,6 +941,9 @@ void World::givePositionCommand(int unitId, const string &commandName, const Vec throw runtime_error("Invalid position commmand: " + commandName); } + if(unit->getType()->getFirstCtOfClass(cc) == NULL) { + throw runtime_error("Invalid commmand: [" + commandName + "] for unit: [" + unit->getType()->getName() + "] id [" + intToStr(unit->getId()) + "]"); + } if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] cc = %d Unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,cc,unit->getFullName().c_str()); unit->giveCommand(new Command( unit->getType()->getFirstCtOfClass(cc), pos )); if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);