- 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,51 +1638,21 @@ void Game::checkWinner(){
}
void Game::checkWinnerStandard(){
//lose
bool lose= false;
if(hasBuilding(world.getThisFaction()) == false) {
lose= true;
for(int i=0; i<world.getFactionCount(); ++i) {
if(world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
world.getStats()->setVictorious(i);
}
}
gameOver= true;
if(this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the poor user watch everything unfold
world.setFogOfWar(false);
// This caused too much LAG for network games
if(this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(500);
}
// END
// but don't let him cheat via teamchat
chatManager.setDisableTeamMode(true);
}
scriptManager.onGameOver(!lose);
showLoseMessageBox();
}
//win
if(lose == false) {
bool win= true;
for(int i=0; i<world.getFactionCount(); ++i) {
if(i!=world.getThisFactionIndex()){
if(hasBuilding(world.getFaction(i)) && world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
win= false;
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;
}
}
}
//if win
if(win) {
// did some team win
if(teamsAlive.size() <= 1) {
for(int i=0; i< world.getFactionCount(); ++i) {
if(world.getFaction(i)->isAlly(world.getThisFaction())) {
if(i != world.getThisFactionIndex() && teamsAlive.find(world.getFaction(i)->getTeam()) != teamsAlive.end()) {
world.getStats()->setVictorious(i);
}
}
@ -1699,11 +1669,84 @@ void Game::checkWinnerStandard(){
// END
}
scriptManager.onGameOver(win);
scriptManager.onGameOver(true);
showWinMessageBox();
}
}
else {
//lose
bool lose= false;
if(hasBuilding(world.getThisFaction()) == false) {
lose= true;
for(int i=0; i<world.getFactionCount(); ++i) {
if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) {
if(world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
world.getStats()->setVictorious(i);
}
}
}
gameOver= true;
if(this->gameSettings.getEnableObserverModeAtEndGame() == true) {
// Let the poor user watch everything unfold
world.setFogOfWar(false);
// This caused too much LAG for network games
if(this->gameSettings.isNetworkGame() == false) {
Renderer::getInstance().setPhotoMode(true);
gameCamera.setMaxHeight(500);
}
// END
// but don't let him cheat via teamchat
chatManager.setDisableTeamMode(true);
}
scriptManager.onGameOver(!lose);
showLoseMessageBox();
}
//win
if(lose == false) {
bool win= true;
for(int i = 0; i < world.getFactionCount(); ++i) {
if(i != world.getThisFactionIndex()) {
if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) {
if(hasBuilding(world.getFaction(i)) && world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
win= false;
}
}
}
}
//if win
if(win) {
for(int i=0; i< world.getFactionCount(); ++i) {
if(world.getFaction(i)->getType()->getPersonalityType() != fpt_Observer) {
if(world.getFaction(i)->isAlly(world.getThisFaction())) {
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(win);
showWinMessageBox();
}
}
}
}
void Game::checkWinnerScripted(){
@ -1794,7 +1837,13 @@ void Game::showLoseMessageBox(){
void Game::showWinMessageBox() {
Lang &lang= Lang::getInstance();
showMessageBox(lang.get("YouWin")+", "+lang.get("ExitGame?"), lang.get("BattleOver"), false);
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);
}
}
void Game::showMessageBox(const string &text, const string &header, bool toggle) {

View File

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

View File

@ -96,28 +96,34 @@ void BattleEnd::render(){
int score= kills*100 + unitsProduced*50 + resourcesHarvested/10;
string controlString;
switch(stats.getControl(i)){
case ctCpuEasy:
controlString= lang.get("CpuEasy");
break;
case ctCpu:
controlString= lang.get("Cpu");
break;
case ctCpuUltra:
controlString= lang.get("CpuUltra");
break;
case ctCpuMega:
controlString= lang.get("CpuMega");
break;
case ctNetwork:
controlString= lang.get("Network");
break;
case ctHuman:
controlString= lang.get("Human");
break;
default:
assert(false);
};
if(stats.getPersonalityType(i) == fpt_Observer) {
controlString= lang.get("ObserverOnly");
}
else {
switch(stats.getControl(i)) {
case ctCpuEasy:
controlString= lang.get("CpuEasy");
break;
case ctCpu:
controlString= lang.get("Cpu");
break;
case ctCpuUltra:
controlString= lang.get("CpuUltra");
break;
case ctCpuMega:
controlString= lang.get("CpuMega");
break;
case ctNetwork:
controlString= lang.get("Network");
break;
case ctHuman:
controlString= lang.get("Human");
break;
default:
assert(false);
};
}
Vec3f color = stats.getPlayerColor(i);
@ -127,7 +133,13 @@ void BattleEnd::render(){
else {
textRenderer->render((lang.get("Player")+" "+intToStr(i+1)).c_str(), textX, bm+400,false, &color);
}
textRenderer->render(stats.getVictory(i)? lang.get("Victory").c_str(): lang.get("Defeat").c_str(), textX, bm+360);
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(controlString, textX, bm+320);
textRenderer->render(stats.getFactionTypeName(i), textX, bm+280);
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__);
}
else {
// Add special Observer Faction
Lang &lang= Lang::getInstance();
results.push_back(formatString(lang.get("ObserverOnly")));
factionFiles= results;
for(int i= 0; i<results.size(); ++i){
results[i]= formatString(results[i]);

View File

@ -1895,17 +1895,22 @@ void MenuStateCustomGame::reloadFactions(){
if(results.size() == 0) {
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;
for(int i= 0; i<results.size(); ++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());
}
for(int i=0; i<GameConstants::maxPlayers; ++i){
listBoxFactions[i].setItems(results);
listBoxFactions[i].setSelectedItemIndex(i % results.size());
}
}
void MenuStateCustomGame::updateControlers(){

View File

@ -31,7 +31,8 @@ namespace Glest{ namespace Game{
// ======================================================
FactionType::FactionType(){
music= NULL;
music = NULL;
personalityType = fpt_Normal;
}
//load a faction, given a directory
@ -41,98 +42,105 @@ void FactionType::load(const string &dir, const TechTree *techTree, Checksum* ch
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);
// a1) preload units
string unitsPath= dir + "/units/*.";
vector<string> unitFilenames;
findAll(unitsPath, unitFilenames);
unitTypes.resize(unitFilenames.size());
for(int i=0; i<unitTypes.size(); ++i){
string str= dir + "/units/" + unitFilenames[i];
unitTypes[i].preLoad(str);
SDL_PumpEvents();
}
// a2) preload upgrades
string upgradesPath= dir + "/upgrades/*.";
vector<string> upgradeFilenames;
findAll(upgradesPath, upgradeFilenames);
upgradeTypes.resize(upgradeFilenames.size());
for(int i=0; i<upgradeTypes.size(); ++i){
string str= dir + "/upgrades/" + upgradeFilenames[i];
upgradeTypes[i].preLoad(str);
SDL_PumpEvents();
}
// b1) load units
try{
if(personalityType == fpt_Normal) {
// a1) preload units
string unitsPath= dir + "/units/*.";
vector<string> unitFilenames;
findAll(unitsPath, unitFilenames);
unitTypes.resize(unitFilenames.size());
for(int i=0; i<unitTypes.size(); ++i){
string str= dir + "/units/" + unitTypes[i].getName();
unitTypes[i].load(i, str, techTree, this, checksum);
string str= dir + "/units/" + unitFilenames[i];
unitTypes[i].preLoad(str);
SDL_PumpEvents();
}
}
catch(const exception &e){
throw runtime_error("Error loading units: "+ dir + "\n" + e.what());
}
}
// b2) load upgrades
try{
// a2) preload upgrades
string upgradesPath= dir + "/upgrades/*.";
vector<string> upgradeFilenames;
findAll(upgradesPath, upgradeFilenames);
upgradeTypes.resize(upgradeFilenames.size());
for(int i=0; i<upgradeTypes.size(); ++i){
string str= dir + "/upgrades/" + upgradeTypes[i].getName();
upgradeTypes[i].load(str, techTree, this, checksum);
string str= dir + "/upgrades/" + upgradeFilenames[i];
upgradeTypes[i].preLoad(str);
SDL_PumpEvents();
}
}
catch(const exception &e){
throw runtime_error("Error loading upgrades: "+ dir + "\n" + e.what());
}
// b1) load units
try{
for(int i=0; i<unitTypes.size(); ++i){
string str= dir + "/units/" + unitTypes[i].getName();
unitTypes[i].load(i, str, techTree, this, checksum);
SDL_PumpEvents();
}
}
catch(const exception &e){
throw runtime_error("Error loading units: "+ dir + "\n" + e.what());
}
// b2) load upgrades
try{
for(int i=0; i<upgradeTypes.size(); ++i){
string str= dir + "/upgrades/" + upgradeTypes[i].getName();
upgradeTypes[i].load(str, techTree, this, checksum);
SDL_PumpEvents();
}
}
catch(const exception &e){
throw runtime_error("Error loading upgrades: "+ dir + "\n" + e.what());
}
//open xml file
string path= dir+"/"+name+".xml";
checksum->addFile(path);
XmlTree xmlTree;
xmlTree.load(path);
const XmlNode *factionNode= xmlTree.getRootNode();
//read starting resources
const XmlNode *startingResourcesNode= factionNode->getChild("starting-resources");
startingResources.resize(startingResourcesNode->getChildCount());
for(int i=0; i<startingResources.size(); ++i){
const XmlNode *resourceNode= startingResourcesNode->getChild("resource", i);
string name= resourceNode->getAttribute("name")->getRestrictedValue();
int amount= resourceNode->getAttribute("amount")->getIntValue();
startingResources[i].init(techTree->getResourceType(name), amount);
SDL_PumpEvents();
}
//read starting units
const XmlNode *startingUnitsNode= factionNode->getChild("starting-units");
for(int i=0; i<startingUnitsNode->getChildCount(); ++i){
const XmlNode *unitNode= startingUnitsNode->getChild("unit", i);
string name= unitNode->getAttribute("name")->getRestrictedValue();
int amount= unitNode->getAttribute("amount")->getIntValue();
startingUnits.push_back(PairPUnitTypeInt(getUnitType(name), amount));
SDL_PumpEvents();
}
//read music
const XmlNode *musicNode= factionNode->getChild("music");
bool value= musicNode->getAttribute("value")->getBoolValue();
if(value){
music= new StrSound();
music->open(dir+"/"+musicNode->getAttribute("path")->getRestrictedValue());
}
}
//open xml file
string path= dir+"/"+name+".xml";
checksum->addFile(path);
XmlTree xmlTree;
xmlTree.load(path);
const XmlNode *factionNode= xmlTree.getRootNode();
//read starting resources
const XmlNode *startingResourcesNode= factionNode->getChild("starting-resources");
startingResources.resize(startingResourcesNode->getChildCount());
for(int i=0; i<startingResources.size(); ++i){
const XmlNode *resourceNode= startingResourcesNode->getChild("resource", i);
string name= resourceNode->getAttribute("name")->getRestrictedValue();
int amount= resourceNode->getAttribute("amount")->getIntValue();
startingResources[i].init(techTree->getResourceType(name), amount);
SDL_PumpEvents();
}
//read starting units
const XmlNode *startingUnitsNode= factionNode->getChild("starting-units");
for(int i=0; i<startingUnitsNode->getChildCount(); ++i){
const XmlNode *unitNode= startingUnitsNode->getChild("unit", i);
string name= unitNode->getAttribute("name")->getRestrictedValue();
int amount= unitNode->getAttribute("amount")->getIntValue();
startingUnits.push_back(PairPUnitTypeInt(getUnitType(name), amount));
SDL_PumpEvents();
}
//read music
const XmlNode *musicNode= factionNode->getChild("music");
bool value= musicNode->getAttribute("value")->getBoolValue();
if(value){
music= new StrSound();
music->open(dir+"/"+musicNode->getAttribute("path")->getRestrictedValue());
}
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
// =====================================================
enum FactionPersonalityType {
fpt_Normal,
fpt_Observer
};
class FactionType{
private:
typedef pair<const UnitType*, int> PairPUnitTypeInt;
@ -41,6 +46,7 @@ private:
StartingUnits startingUnits;
Resources startingResources;
StrSound *music;
FactionPersonalityType personalityType;
public:
//init
@ -63,6 +69,9 @@ public:
const UpgradeType *getUpgradeType(const string &name) const;
int getStartingResourceAmount(const ResourceType *resourceType) const;
FactionPersonalityType getPersonalityType() const { return personalityType;}
void setPersonalityType(FactionPersonalityType value) { personalityType = value;}
std::string toString() const;
std::vector<std::string> validateFactionType();
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.setFactionTypeName(i, formatString(gs->getFactionTypeName(i)));
stats.setPersonalityType(i, getFaction(i)->getType()->getPersonalityType());
stats.setControl(i, gs->getFactionControl(i));
stats.setPlayerName(i,gs->getNetworkPlayerName(i));
stats.setPlayerColor(i,getFaction(i)->getTexture()->getPixmap()->getPixel3f(0, 0));