// ============================================================== // This file is part of Glest (www.glest.org) // // Copyright (C) 2001-2008 Marti�o Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #include "world.h" #include #include #include "config.h" #include "faction.h" #include "unit.h" #include "game.h" #include "logger.h" #include "sound_renderer.h" #include "game_settings.h" #include "cache_manager.h" #include #include "leak_dumper.h" using namespace Shared::Graphics; using namespace Shared::Util; namespace Glest{ namespace Game{ // ===================================================== // class World // ===================================================== const float World::airHeight= 5.f; // ===================== PUBLIC ======================== World::World(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Config &config= Config::getInstance(); techTree = NULL; fogOfWarOverride = false; fogOfWarSmoothing= config.getBool("FogOfWarSmoothing"); fogOfWarSmoothingFrameSkip= config.getInt("FogOfWarSmoothingFrameSkip"); frameCount= 0; //nextUnitId= 0; scriptManager= NULL; this->game = NULL; allowRotateUnits = Config::getInstance().getBool("AllowRotateUnits","0"); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } World::~World() { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete techTree; techTree = NULL; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void World::end(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Logger::getInstance().add("World", true); for(int i= 0; igetGameSettings() != NULL) { game->getGameSettings()->setFogOfWar(fogOfWar); initCells(fogOfWar); //must be done after knowing faction number and dimensions //initMinimap(); minimap.setFogOfWar(fogOfWar); computeFow(); } } void World::init(Game *game, bool createUnits){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); this->game = game; scriptManager= game->getScriptManager(); unitUpdater.init(game); GameSettings *gs = game->getGameSettings(); if(fogOfWarOverride == false) { fogOfWar = gs->getFogOfWar(); } initFactionTypes(gs); initCells(fogOfWar); //must be done after knowing faction number and dimensions initMap(); initSplattedTextures(); //minimap must be init after sum computation initMinimap(); if(createUnits){ initUnits(); } //initExplorationState(); ... was only for !fog-of-war, now handled in initCells() computeFow(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } //load tileset void World::loadTileset(const vector pathList, const string &tilesetName, Checksum* checksum) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); tileset.loadTileset(pathList, tilesetName, checksum); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); timeFlow.init(&tileset); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void World::loadTileset(const string &dir, Checksum *checksum){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); tileset.load(dir, checksum); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); timeFlow.init(&tileset); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } //load tech void World::loadTech(const vector pathList, const string &techName, set &factions, Checksum *checksum){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); /* std::map &techCache = Shared::PlatformCommon::CacheManager::getCachedItem< std::map >("techCache"); if(techCache.find(techName) != techCache.end()) { techTree = new TechTree(); *techTree = *techCache[techName]; return; } */ techTree = new TechTree(); techTree->loadTech(pathList, techName, factions, checksum); //techCache[techName] = techTree; } //load map void World::loadMap(const string &path, Checksum *checksum){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); checksum->addFile(path); map.load(path, techTree, &tileset); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } //load map void World::loadScenario(const string &path, Checksum *checksum){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); checksum->addFile(path); scenario.load(path); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } // ==================== misc ==================== void World::update(){ ++frameCount; //time timeFlow.update(); //water effects waterEffects.update(); //units for(int i=0; igetUnitCount(); ++j){ unitUpdater.updateUnit(getFaction(i)->getUnit(j)); } } //undertake the dead for(int i=0; igetUnitCount(); for(int j= unitCount - 1; j >= 0; j--){ Unit *unit= getFaction(i)->getUnit(j); if(unit->getToBeUndertaken()) { unit->undertake(); delete unit; //j--; } } } //food costs for(int i=0; igetResourceTypeCount(); ++i){ const ResourceType *rt= techTree->getResourceType(i); if(rt->getClass()==rcConsumable && frameCount % (rt->getInterval()*GameConstants::updateFps)==0){ for(int i=0; iapplyCostsOnInterval(); } } } //fow smoothing if(fogOfWarSmoothing && ((frameCount+1) % (fogOfWarSmoothingFrameSkip+1))==0){ float fogFactor= static_cast(frameCount%GameConstants::updateFps)/GameConstants::updateFps; minimap.updateFowTex(clamp(fogFactor, 0.f, 1.f)); } //tick if(frameCount%GameConstants::updateFps==0){ computeFow(); tick(); } } void World::tick(){ if(!fogOfWarSmoothing){ minimap.updateFowTex(1.f); } //increase hp for(int i=0; igetUnitCount(); ++j){ getFaction(i)->getUnit(j)->tick(); } } //compute resources balance for(int k=0; kgetResourceTypeCount(); ++i){ const ResourceType *rt= techTree->getResourceType(i); //if consumable if(rt->getClass()==rcConsumable){ int balance= 0; for(int j=0; jgetUnitCount(); ++j){ //if unit operative and has this cost const Unit *u= faction->getUnit(j); if(u->isOperative()){ const Resource *r= u->getType()->getCost(rt); if(r!=NULL){ balance-= u->getType()->getCost(rt)->getAmount(); } } } faction->setResourceBalance(rt, balance); } } } } Unit* World::findUnitById(int id){ for(int i= 0; igetUnitCount(); ++j){ Unit* unit= faction->getUnit(j); if(unit->getId()==id){ return unit; } } } return NULL; } const UnitType* World::findUnitTypeById(const FactionType* factionType, int id){ for(int i= 0; igetUnitTypeCount(); ++i){ const UnitType* unitType= factionType->getUnitType(i); if(unitType->getId()==id){ return unitType; } } return NULL; } //looks for a place for a unit around a start lociacion, returns true if succeded bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated){ bool freeSpace; int size= unit->getType()->getSize(); Field currField= unit->getCurrField(); for(int r=1; rsetPos(pos); unit->setMeetingPos(pos-Vec2i(1)); return true; } } } } return false; } //clears a unit old position from map and places new position void World::moveUnitCells(Unit *unit){ Vec2i newPos= unit->getTargetPos(); //newPos must be free or the same pos as current assert(map.getCell(unit->getPos())->getUnit(unit->getCurrField())==unit || map.isFreeCell(newPos, unit->getCurrField())); map.clearUnitCells(unit, unit->getPos()); map.putUnitCells(unit, newPos); //water splash if(tileset.getWaterEffects() && unit->getCurrField()==fLand){ if(map.getSubmerged(map.getCell(unit->getLastPos()))){ int unitSize=unit->getType()->getSize(); for(int i=0; i<3; ++i){ waterEffects.addWaterSplash( Vec2f(unit->getLastPos().x+(float)unitSize/2.0f+random.randRange(-0.9f, -0.1f), unit->getLastPos().y+random.randRange(-0.9f, -0.1f)+(float)unitSize/2.0f), unit->getType()->getSize()); } } } } //returns the nearest unit that can store a type of resource given a position and a faction Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt){ float currDist= infinity; Unit *currUnit= NULL; for(int i=0; igetUnitCount(); ++i){ Unit *u= getFaction(factionIndex)->getUnit(i); float tmpDist= u->getPos().dist(pos); if(tmpDistgetType()->getStore(rt)>0 && u->isOperative()){ currDist= tmpDist; currUnit= u; } } return currUnit; } bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const{ //a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell return visibleQuad.isInside(unit->getPos()) && toRenderUnit(unit); } bool World::toRenderUnit(const Unit *unit) const{ return map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isVisible(thisTeamIndex) || (unit->getCurrSkill()->getClass()==scAttack && map.getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->isVisible(thisTeamIndex)); } void World::createUnit(const string &unitName, int factionIndex, const Vec2i &pos){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitName [%s] factionIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,unitName.c_str(),factionIndex); if(factionIndexgetIndex() != factionIndex) { throw runtime_error("faction->getIndex() != factionIndex"); } const FactionType* ft= faction->getType(); const UnitType* ut= ft->getUnitType(unitName); Unit* unit= new Unit(getNextUnitId(faction), pos, ut, faction, &map, CardinalDir::NORTH); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); if(placeUnit(pos, generationArea, unit, true)){ unit->create(true); unit->born(); scriptManager->onUnitCreated(unit); } else{ throw runtime_error("Unit cant be placed"); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); } else { throw runtime_error("Invalid faction index in createUnitAtPosition: " + intToStr(factionIndex)); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void World::giveResource(const string &resourceName, int factionIndex, int amount){ if(factionIndexgetResourceType(resourceName); faction->incResourceAmount(rt, amount); } else { throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex)); } } void World::givePositionCommand(int unitId, const string &commandName, const Vec2i &pos){ Unit* unit= findUnitById(unitId); if(unit!=NULL){ CommandClass cc; if(commandName=="move"){ cc= ccMove; } else if(commandName=="attack"){ cc= ccAttack; } else{ throw runtime_error("Invalid position commmand: " + commandName); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"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 )); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } } void World::giveProductionCommand(int unitId, const string &producedName){ Unit *unit= findUnitById(unitId); if(unit!=NULL){ const UnitType *ut= unit->getType(); //Search for a command that can produce the unit for(int i= 0; igetCommandTypeCount(); ++i){ const CommandType* ct= ut->getCommandType(i); if(ct->getClass()==ccProduce){ const ProduceCommandType *pct= static_cast(ct); if(pct->getProducedUnit()->getName()==producedName){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); unit->giveCommand(new Command(pct)); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); break; } } } } } void World::giveUpgradeCommand(int unitId, const string &upgradeName){ Unit *unit= findUnitById(unitId); if(unit!=NULL){ const UnitType *ut= unit->getType(); //Search for a command that can produce the unit for(int i= 0; igetCommandTypeCount(); ++i){ const CommandType* ct= ut->getCommandType(i); if(ct->getClass()==ccUpgrade){ const UpgradeCommandType *uct= static_cast(ct); if(uct->getProducedUpgrade()->getName()==upgradeName){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); unit->giveCommand(new Command(uct)); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); break; } } } } } int World::getResourceAmount(const string &resourceName, int factionIndex){ if(factionIndexgetResourceType(resourceName); return faction->getResource(rt)->getAmount(); } else { throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex)); } } Vec2i World::getStartLocation(int factionIndex){ if(factionIndexgetStartLocationIndex()); } else { throw runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex)); } } Vec2i World::getUnitPosition(int unitId){ Unit* unit= findUnitById(unitId); if(unit==NULL){ throw runtime_error("Can not find unit to get position"); } return unit->getPos(); } int World::getUnitFactionIndex(int unitId){ Unit* unit= findUnitById(unitId); if(unit==NULL){ throw runtime_error("Can not find unit to get position"); } return unit->getFactionIndex(); } int World::getUnitCount(int factionIndex){ if(factionIndexgetUnitCount(); ++i){ const Unit* unit= faction->getUnit(i); if(unit->isAlive()){ ++count; } } return count; } else { throw runtime_error("Invalid faction index in getUnitCount: " + intToStr(factionIndex)); } } int World::getUnitCountOfType(int factionIndex, const string &typeName){ if(factionIndexgetUnitCount(); ++i){ const Unit* unit= faction->getUnit(i); if(unit->isAlive() && unit->getType()->getName()==typeName){ ++count; } } return count; } else { throw runtime_error("Invalid faction index in getUnitCountOfType: " + intToStr(factionIndex)); } } // ==================== PRIVATE ==================== // ==================== private init ==================== //init basic cell state void World::initCells(bool fogOfWar){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Logger::getInstance().add("State cells", true); for(int i=0; isetFowTexCoord(Vec2f( i/(next2Power(map.getSurfaceW())-1.f), j/(next2Power(map.getSurfaceH())-1.f))); for (int k = 0; k < GameConstants::maxPlayers; k++) { sc->setExplored(k, !fogOfWar); sc->setVisible(k, !fogOfWar); } } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } //init surface textures void World::initSplattedTextures(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); for(int i=0; igetSurfaceType(), sc10->getSurfaceType(), sc01->getSurfaceType(), sc11->getSurfaceType(), coord, texture); sc00->setSurfTexCoord(coord); sc00->setSurfaceTexture(texture); } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } //creates each faction looking at each faction name contained in GameSettings void World::initFactionTypes(GameSettings *gs){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Logger::getInstance().add("Faction types", true); if(gs->getFactionCount() > map.getMaxPlayers()){ throw runtime_error("This map only supports "+intToStr(map.getMaxPlayers())+" players"); } //create stats stats.init(gs->getFactionCount(), gs->getThisFactionIndex(), gs->getDescription()); //create factions this->thisFactionIndex= gs->getThisFactionIndex(); factions.resize(gs->getFactionCount()); for(int i=0; igetType(gs->getFactionTypeName(i)); factions[i].init( ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i), gs->getStartLocationIndex(i), i==thisFactionIndex, gs->getDefaultResources()); stats.setTeam(i, gs->getTeam(i)); stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i))); stats.setControl(i, gs->getFactionControl(i)); } thisTeamIndex= getFaction(thisFactionIndex)->getTeam(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void World::initMinimap(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); minimap.init(map.getW(), map.getH(), this, game->getGameSettings()->getFogOfWar()); Logger::getInstance().add("Compute minimap surface", true); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } //place units randomly aroud start location void World::initUnits(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Logger::getInstance().add("Generate elements", true); //put starting units for(int i=0; igetType(); for(int j=0; jgetStartingUnitCount(); ++j){ const UnitType *ut= ft->getStartingUnit(j); int initNumber= ft->getStartingUnitAmount(j); for(int l=0; lgetStartLocationIndex(); if(placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)){ unit->create(true); unit->born(); } else{ throw runtime_error("Unit cant be placed, this error is caused because there is no enough place to put the units near its start location, make a better map: "+unit->getType()->getName() + " Faction: "+intToStr(i)); } if(unit->getType()->hasSkillClass(scBeBuilt)){ map.flatternTerrain(unit); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); } } } map.computeNormals(); map.computeInterpolatedHeights(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void World::initMap(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); map.init(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } // ==================== exploration ==================== void World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex){ Vec2i newSurfPos= Map::toSurfCoords(newPos); int surfSightRange= sightRange/Map::cellScale+1; //explore for(int i=-surfSightRange-indirectSightRange-1; i<=surfSightRange+indirectSightRange+1; ++i){ for(int j=-surfSightRange-indirectSightRange-1; j<=surfSightRange+indirectSightRange+1; ++j){ Vec2i currRelPos= Vec2i(i, j); Vec2i currPos= newSurfPos + currRelPos; if(map.isInsideSurface(currPos)){ SurfaceCell *sc= map.getSurfaceCell(currPos); //explore if(Vec2i(0).dist(currRelPos) < surfSightRange+indirectSightRange+1){ sc->setExplored(teamIndex, true); } //visible if(Vec2i(0).dist(currRelPos) < surfSightRange){ sc->setVisible(teamIndex, true); } } } } } //computes the fog of war texture, contained in the minimap void World::computeFow(){ //reset texture minimap.resetFowTex(); //reset cells for(int i=0; isetVisible(k, false); } } } } //compute cells for(int i=0; igetUnitCount(); ++j){ Unit *unit= getFaction(i)->getUnit(j); //exploration if(unit->isOperative()){ exploreCells(unit->getCenteredPos(), unit->getType()->getSight(), unit->getTeam()); } } } //fire for(int i=0; igetUnitCount(); ++j){ Unit *unit= getFaction(i)->getUnit(j); //fire ParticleSystem *fire= unit->getFire(); if(fire!=NULL){ fire->setActive(map.getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(thisTeamIndex)); } } } //compute texture for(int i=0; igetTeam()==thisTeamIndex){ for(int j=0; jgetUnitCount(); ++j){ const Unit *unit= faction->getUnit(j); if(unit->isOperative()){ int sightRange= unit->getType()->getSight(); //iterate through all cells PosCircularIterator pci(&map, unit->getPos(), sightRange+indirectSightRange); while(pci.next()){ Vec2i pos= pci.getPos(); Vec2i surfPos= Map::toSurfCoords(pos); //compute max alpha float maxAlpha; if(surfPos.x>1 && surfPos.y>1 && surfPos.x0 && surfPos.y>0 && surfPos.xgetPos().dist(pos); if(dist>sightRange){ alpha= clamp(1.f-(dist-sightRange)/(indirectSightRange), 0.f, maxAlpha); } else{ alpha= maxAlpha; } minimap.incFowTextureAlphaSurface(surfPos, alpha); } } } } } } int World::getNextUnitId(Faction *faction) { if(mapFactionNextUnitId.find(faction->getIndex()) == mapFactionNextUnitId.end()) { mapFactionNextUnitId[faction->getIndex()] = faction->getIndex() * 3000; } return mapFactionNextUnitId[faction->getIndex()]++; } std::string World::DumpWorldToLog(bool consoleBasicInfoOnly) const { string debugWorldLogFile = Config::getInstance().getString("DebugWorldLogFile","debugWorld.log"); if(getGameReadWritePath() != "") { debugWorldLogFile = getGameReadWritePath() + debugWorldLogFile; } if(consoleBasicInfoOnly == true) { std::cout << "World debug information:" << std::endl; std::cout << "========================" << std::endl; //factions (and their related info) for(int i = 0; i < getFactionCount(); ++i) { std::cout << "Faction detail for index: " << i << std::endl; std::cout << "--------------------------" << std::endl; std::cout << "FactionName = " << getFaction(i)->getType()->getName() << std::endl; std::cout << "FactionIndex = " << intToStr(getFaction(i)->getIndex()) << std::endl; std::cout << "teamIndex = " << intToStr(getFaction(i)->getTeam()) << std::endl; std::cout << "startLocationIndex = " << intToStr(getFaction(i)->getStartLocationIndex()) << std::endl; std::cout << "thisFaction = " << intToStr(getFaction(i)->getThisFaction()) << std::endl; std::cout << "control = " << intToStr(getFaction(i)->getControlType()) << std::endl; } } else { std::ofstream logFile; logFile.open(debugWorldLogFile.c_str(), ios_base::out | ios_base::trunc); logFile << "World debug information:" << std::endl; logFile << "========================" << std::endl; //factions (and their related info) for(int i = 0; i < getFactionCount(); ++i) { logFile << "Faction detail for index: " << i << std::endl; logFile << "--------------------------" << std::endl; logFile << getFaction(i)->toString() << std::endl; } //undertake the dead logFile << "Undertake stats:" << std::endl; for(int i = 0; i < getFactionCount(); ++i){ logFile << "Faction: " << getFaction(i)->getType()->getName() << std::endl; int unitCount = getFaction(i)->getUnitCount(); for(int j= unitCount - 1; j >= 0; j--){ Unit *unit= getFaction(i)->getUnit(j); if(unit->getToBeUndertaken()) { logFile << "Undertake unit index = " << j << unit->getFullName() << std::endl; } } } logFile.close(); } return debugWorldLogFile; } }}//end namespace