- first attempt to add a special builtin Observer faction to allow people to observe games

This commit is contained in:
Mark Vejvoda 2010-09-03 07:12:40 +00:00
parent a1eebafac6
commit 358d61aa38
8 changed files with 245 additions and 152 deletions

View File

@ -1638,15 +1638,53 @@ void Game::checkWinner(){
} }
void Game::checkWinnerStandard(){ void Game::checkWinnerStandard(){
if(world.getThisFaction()->getType()->getPersonalityType() == fpt_Observer) {
// lookup int is team #, value is players alive on team
std::map<int,int> teamsAlive;
for(int i = 0; i < world.getFactionCount(); ++i) {
if(i != world.getThisFactionIndex()) {
if(hasBuilding(world.getFaction(i))) {
teamsAlive[world.getFaction(i)->getTeam()] = teamsAlive[world.getFaction(i)->getTeam()] + 1;
}
}
}
// did some team win
if(teamsAlive.size() <= 1) {
for(int i=0; i< world.getFactionCount(); ++i) {
if(i != world.getThisFactionIndex() && teamsAlive.find(world.getFaction(i)->getTeam()) != teamsAlive.end()) {
world.getStats()->setVictorious(i);
}
}
gameOver= true;
if(this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the happy winner view everything left in the world
world.setFogOfWar(false);
// This caused too much LAG for network games
if(this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(500);
}
// END
}
scriptManager.onGameOver(true);
showWinMessageBox();
}
}
else {
//lose //lose
bool lose= false; bool lose= false;
if(hasBuilding(world.getThisFaction()) == false) { if(hasBuilding(world.getThisFaction()) == false) {
lose= true; lose= true;
for(int i=0; i<world.getFactionCount(); ++i) { for(int i=0; i<world.getFactionCount(); ++i) {
if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) {
if(world.getFaction(i)->isAlly(world.getThisFaction()) == false) { if(world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
world.getStats()->setVictorious(i); world.getStats()->setVictorious(i);
} }
} }
}
gameOver= true; gameOver= true;
if(this->gameSettings.getEnableObserverModeAtEndGame() == true) { if(this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the poor user watch everything unfold // Let the poor user watch everything unfold
@ -1671,21 +1709,25 @@ void Game::checkWinnerStandard(){
//win //win
if(lose == false) { if(lose == false) {
bool win= true; bool win= true;
for(int i=0; i<world.getFactionCount(); ++i) { for(int i = 0; i < world.getFactionCount(); ++i) {
if(i!=world.getThisFactionIndex()){ if(i != world.getThisFactionIndex()) {
if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) {
if(hasBuilding(world.getFaction(i)) && world.getFaction(i)->isAlly(world.getThisFaction()) == false) { if(hasBuilding(world.getFaction(i)) && world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
win= false; win= false;
} }
} }
} }
}
//if win //if win
if(win) { if(win) {
for(int i=0; i< world.getFactionCount(); ++i) { for(int i=0; i< world.getFactionCount(); ++i) {
if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) {
if(world.getFaction(i)->isAlly(world.getThisFaction())) { if(world.getFaction(i)->isAlly(world.getThisFaction())) {
world.getStats()->setVictorious(i); world.getStats()->setVictorious(i);
} }
} }
}
gameOver= true; gameOver= true;
if(this->gameSettings.getEnableObserverModeAtEndGame() == true) { if(this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the happy winner view everything left in the world // Let the happy winner view everything left in the world
@ -1704,6 +1746,7 @@ void Game::checkWinnerStandard(){
showWinMessageBox(); showWinMessageBox();
} }
} }
}
} }
void Game::checkWinnerScripted(){ void Game::checkWinnerScripted(){
@ -1794,7 +1837,13 @@ void Game::showLoseMessageBox(){
void Game::showWinMessageBox() { void Game::showWinMessageBox() {
Lang &lang= Lang::getInstance(); Lang &lang= Lang::getInstance();
if(world.getThisFaction()->getType()->getPersonalityType() == fpt_Observer) {
showMessageBox(lang.get("GameOver")+", "+lang.get("ExitGame?"), lang.get("BattleOver"), false);
}
else {
showMessageBox(lang.get("YouWin")+", "+lang.get("ExitGame?"), lang.get("BattleOver"), false); showMessageBox(lang.get("YouWin")+", "+lang.get("ExitGame?"), lang.get("BattleOver"), false);
}
} }
void Game::showMessageBox(const string &text, const string &header, bool toggle) { void Game::showMessageBox(const string &text, const string &header, bool toggle) {

View File

@ -16,6 +16,7 @@
#include "game_constants.h" #include "game_constants.h"
#include "faction.h" #include "faction.h"
#include "faction_type.h"
#include "vec.h" #include "vec.h"
using std::string; using std::string;
@ -28,6 +29,7 @@ public:
PlayerStats() { PlayerStats() {
control = ctClosed; control = ctClosed;
factionTypeName = ""; factionTypeName = "";
personalityType = fpt_Normal;
teamIndex = 0; teamIndex = 0;
victory = false; victory = false;
kills = 0; kills = 0;
@ -40,6 +42,7 @@ public:
ControlType control; ControlType control;
string factionTypeName; string factionTypeName;
FactionPersonalityType personalityType;
int teamIndex; int teamIndex;
bool victory; bool victory;
int kills; int kills;
@ -76,8 +79,8 @@ public:
string getDescription() const {return description;} string getDescription() const {return description;}
int getThisFactionIndex() const {return thisFactionIndex;} int getThisFactionIndex() const {return thisFactionIndex;}
int getFactionCount() const {return factionCount;} int getFactionCount() const {return factionCount;}
const string &getFactionTypeName(int factionIndex) const {return playerStats[factionIndex].factionTypeName;} const string &getFactionTypeName(int factionIndex) const {return playerStats[factionIndex].factionTypeName;}
FactionPersonalityType getPersonalityType(int factionIndex) const { return playerStats[factionIndex].personalityType;}
ControlType getControl(int factionIndex) const {return playerStats[factionIndex].control;} ControlType getControl(int factionIndex) const {return playerStats[factionIndex].control;}
bool getVictory(int factionIndex) const {return playerStats[factionIndex].victory;} bool getVictory(int factionIndex) const {return playerStats[factionIndex].victory;}
int getTeam(int factionIndex) const {return playerStats[factionIndex].teamIndex;} int getTeam(int factionIndex) const {return playerStats[factionIndex].teamIndex;}
@ -90,6 +93,7 @@ public:
void setDescription(const string& description) {this->description = description;} void setDescription(const string& description) {this->description = description;}
void setFactionTypeName(int playerIndex, const string& factionTypeName) {playerStats[playerIndex].factionTypeName= factionTypeName;} void setFactionTypeName(int playerIndex, const string& factionTypeName) {playerStats[playerIndex].factionTypeName= factionTypeName;}
void setPersonalityType(int playerIndex, FactionPersonalityType value) { playerStats[playerIndex].personalityType = value;}
void setControl(int playerIndex, ControlType control) {playerStats[playerIndex].control= control;} void setControl(int playerIndex, ControlType control) {playerStats[playerIndex].control= control;}
void setTeam(int playerIndex, int teamIndex) {playerStats[playerIndex].teamIndex= teamIndex;} void setTeam(int playerIndex, int teamIndex) {playerStats[playerIndex].teamIndex= teamIndex;}
void setVictorious(int playerIndex); void setVictorious(int playerIndex);
@ -99,6 +103,7 @@ public:
void harvest(int harvesterFactionIndex, int amount); void harvest(int harvesterFactionIndex, int amount);
void setPlayerName(int playerIndex, string value) {playerStats[playerIndex].playerName = value; } void setPlayerName(int playerIndex, string value) {playerStats[playerIndex].playerName = value; }
void setPlayerColor(int playerIndex, Vec3f value) {playerStats[playerIndex].playerColor = value; } void setPlayerColor(int playerIndex, Vec3f value) {playerStats[playerIndex].playerColor = value; }
}; };
}}//end namespace }}//end namespace

View File

@ -96,7 +96,11 @@ void BattleEnd::render(){
int score= kills*100 + unitsProduced*50 + resourcesHarvested/10; int score= kills*100 + unitsProduced*50 + resourcesHarvested/10;
string controlString; string controlString;
switch(stats.getControl(i)){ if(stats.getPersonalityType(i) == fpt_Observer) {
controlString= lang.get("ObserverOnly");
}
else {
switch(stats.getControl(i)) {
case ctCpuEasy: case ctCpuEasy:
controlString= lang.get("CpuEasy"); controlString= lang.get("CpuEasy");
break; break;
@ -115,9 +119,11 @@ void BattleEnd::render(){
case ctHuman: case ctHuman:
controlString= lang.get("Human"); controlString= lang.get("Human");
break; break;
default: default:
assert(false); assert(false);
}; };
}
Vec3f color = stats.getPlayerColor(i); Vec3f color = stats.getPlayerColor(i);
@ -127,7 +133,13 @@ void BattleEnd::render(){
else { else {
textRenderer->render((lang.get("Player")+" "+intToStr(i+1)).c_str(), textX, bm+400,false, &color); textRenderer->render((lang.get("Player")+" "+intToStr(i+1)).c_str(), textX, bm+400,false, &color);
} }
if(stats.getPersonalityType(i) == fpt_Observer) {
textRenderer->render(lang.get("GameOver").c_str(), textX, bm+360);
}
else {
textRenderer->render(stats.getVictory(i)? lang.get("Victory").c_str(): lang.get("Defeat").c_str(), textX, bm+360); textRenderer->render(stats.getVictory(i)? lang.get("Victory").c_str(): lang.get("Defeat").c_str(), textX, bm+360);
}
textRenderer->render(controlString, textX, bm+320); textRenderer->render(controlString, textX, bm+320);
textRenderer->render(stats.getFactionTypeName(i), textX, bm+280); textRenderer->render(stats.getFactionTypeName(i), textX, bm+280);
textRenderer->render(intToStr(team).c_str(), textX, bm+240); textRenderer->render(intToStr(team).c_str(), textX, bm+240);

View File

@ -946,6 +946,10 @@ bool MenuStateConnectedGame::loadFactions(const GameSettings *gameSettings, bool
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
else { else {
// Add special Observer Faction
Lang &lang= Lang::getInstance();
results.push_back(formatString(lang.get("ObserverOnly")));
factionFiles= results; factionFiles= results;
for(int i= 0; i<results.size(); ++i){ for(int i= 0; i<results.size(); ++i){
results[i]= formatString(results[i]); results[i]= formatString(results[i]);

View File

@ -1895,17 +1895,22 @@ void MenuStateCustomGame::reloadFactions(){
if(results.size() == 0) { if(results.size() == 0) {
throw runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"); throw runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]");
} }
// Add special Observer Faction
Lang &lang= Lang::getInstance();
results.push_back(formatString(lang.get("ObserverOnly")));
factionFiles= results; factionFiles= results;
for(int i= 0; i<results.size(); ++i){ for(int i= 0; i<results.size(); ++i){
results[i]= formatString(results[i]); results[i]= formatString(results[i]);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"Tech [%s] has faction [%s]\n",techTreeFiles[listBoxTechTree.getSelectedItemIndex()].c_str(),results[i].c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"Tech [%s] has faction [%s]\n",techTreeFiles[listBoxTechTree.getSelectedItemIndex()].c_str(),results[i].c_str());
} }
for(int i=0; i<GameConstants::maxPlayers; ++i){ for(int i=0; i<GameConstants::maxPlayers; ++i){
listBoxFactions[i].setItems(results); listBoxFactions[i].setItems(results);
listBoxFactions[i].setSelectedItemIndex(i % results.size()); listBoxFactions[i].setSelectedItemIndex(i % results.size());
} }
} }
void MenuStateCustomGame::updateControlers(){ void MenuStateCustomGame::updateControlers(){

View File

@ -31,7 +31,8 @@ namespace Glest{ namespace Game{
// ====================================================== // ======================================================
FactionType::FactionType(){ FactionType::FactionType(){
music= NULL; music = NULL;
personalityType = fpt_Normal;
} }
//load a faction, given a directory //load a faction, given a directory
@ -41,8 +42,15 @@ void FactionType::load(const string &dir, const TechTree *techTree, Checksum* ch
name= lastDir(dir); name= lastDir(dir);
// Add special Observer Faction
Lang &lang= Lang::getInstance();
if(name == formatString(lang.get("ObserverOnly"))) {
personalityType = fpt_Observer;
}
Logger::getInstance().add("Faction type: "+ formatString(name), true); Logger::getInstance().add("Faction type: "+ formatString(name), true);
if(personalityType == fpt_Normal) {
// a1) preload units // a1) preload units
string unitsPath= dir + "/units/*."; string unitsPath= dir + "/units/*.";
vector<string> unitFilenames; vector<string> unitFilenames;
@ -132,7 +140,7 @@ void FactionType::load(const string &dir, const TechTree *techTree, Checksum* ch
music= new StrSound(); music= new StrSound();
music->open(dir+"/"+musicNode->getAttribute("path")->getRestrictedValue()); music->open(dir+"/"+musicNode->getAttribute("path")->getRestrictedValue());
} }
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }

View File

@ -26,6 +26,11 @@ namespace Glest{ namespace Game{
/// Each of the possible factions the user can select /// Each of the possible factions the user can select
// ===================================================== // =====================================================
enum FactionPersonalityType {
fpt_Normal,
fpt_Observer
};
class FactionType{ class FactionType{
private: private:
typedef pair<const UnitType*, int> PairPUnitTypeInt; typedef pair<const UnitType*, int> PairPUnitTypeInt;
@ -41,6 +46,7 @@ private:
StartingUnits startingUnits; StartingUnits startingUnits;
Resources startingResources; Resources startingResources;
StrSound *music; StrSound *music;
FactionPersonalityType personalityType;
public: public:
//init //init
@ -63,6 +69,9 @@ public:
const UpgradeType *getUpgradeType(const string &name) const; const UpgradeType *getUpgradeType(const string &name) const;
int getStartingResourceAmount(const ResourceType *resourceType) const; int getStartingResourceAmount(const ResourceType *resourceType) const;
FactionPersonalityType getPersonalityType() const { return personalityType;}
void setPersonalityType(FactionPersonalityType value) { personalityType = value;}
std::string toString() const; std::string toString() const;
std::vector<std::string> validateFactionType(); std::vector<std::string> validateFactionType();
std::vector<std::string> validateFactionTypeResourceTypes(vector<ResourceType> &resourceTypes); std::vector<std::string> validateFactionTypeResourceTypes(vector<ResourceType> &resourceTypes);

View File

@ -868,6 +868,7 @@ void World::initFactionTypes(GameSettings *gs){
stats.setTeam(i, gs->getTeam(i)); stats.setTeam(i, gs->getTeam(i));
stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i))); stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i)));
stats.setPersonalityType(i, getFaction(i)->getType()->getPersonalityType());
stats.setControl(i, gs->getFactionControl(i)); stats.setControl(i, gs->getFactionControl(i));
stats.setPlayerName(i,gs->getNetworkPlayerName(i)); stats.setPlayerName(i,gs->getNetworkPlayerName(i));
stats.setPlayerColor(i,getFaction(i)->getTexture()->getPixmap()->getPixel3f(0, 0)); stats.setPlayerColor(i,getFaction(i)->getTexture()->getPixmap()->getPixel3f(0, 0));