2010-03-12 07:42:55 +00:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2010-03-19 18:58:46 +00:00
// Copyright (C) 2001-2008 Marti<74> o Figueroa
2010-03-12 07:42:55 +00:00
//
// 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 <algorithm>
# include <cassert>
# include "config.h"
# include "faction.h"
# include "unit.h"
# include "game.h"
# include "logger.h"
# include "sound_renderer.h"
# include "game_settings.h"
2010-05-03 06:25:54 +00:00
# include "cache_manager.h"
2010-07-13 05:33:43 +00:00
# include "route_planner.h"
2010-05-20 20:19:34 +00:00
# include <iostream>
2010-07-13 05:33:43 +00:00
2010-03-12 07:42:55 +00:00
# include "leak_dumper.h"
using namespace Shared : : Graphics ;
using namespace Shared : : Util ;
namespace Glest { namespace Game {
// =====================================================
// class World
// =====================================================
const float World : : airHeight = 5.f ;
2010-07-16 22:15:09 +00:00
// This limit is to keep RAM use under control while offering better performance.
2010-09-09 01:44:25 +00:00
int MaxExploredCellsLookupItemCache = 9500 ;
2010-07-17 06:33:40 +00:00
time_t ExploredCellsLookupItem : : lastDebug = 0 ;
2010-03-12 07:42:55 +00:00
// ===================== PUBLIC ========================
World : : World ( ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
Config & config = Config : : getInstance ( ) ;
2010-09-17 04:00:48 +00:00
staggeredFactionUpdates = config . getBool ( " StaggeredFactionUpdates " , " false " ) ;
2010-07-16 22:15:09 +00:00
ExploredCellsLookupItemCache . clear ( ) ;
2010-07-17 01:00:31 +00:00
ExploredCellsLookupItemCacheTimer . clear ( ) ;
2010-07-16 22:17:36 +00:00
ExploredCellsLookupItemCacheTimerCount = 0 ;
2010-08-25 23:55:59 +00:00
FowAlphaCellsLookupItemCache . clear ( ) ;
2010-07-16 22:15:09 +00:00
2010-05-03 06:25:54 +00:00
techTree = NULL ;
2010-04-23 02:48:56 +00:00
fogOfWarOverride = false ;
2010-03-12 07:42:55 +00:00
fogOfWarSmoothing = config . getBool ( " FogOfWarSmoothing " ) ;
fogOfWarSmoothingFrameSkip = config . getInt ( " FogOfWarSmoothingFrameSkip " ) ;
2010-07-17 01:00:31 +00:00
MaxExploredCellsLookupItemCache = config . getInt ( " MaxExploredCellsLookupItemCache " , intToStr ( MaxExploredCellsLookupItemCache ) . c_str ( ) ) ;
2010-07-13 05:33:43 +00:00
routePlanner = 0 ;
cartographer = 0 ;
2010-03-12 07:42:55 +00:00
frameCount = 0 ;
2010-05-31 09:24:44 +00:00
//nextUnitId= 0;
2010-03-12 07:42:55 +00:00
scriptManager = NULL ;
this - > game = NULL ;
2010-03-13 21:10:45 +00:00
2010-05-03 06:25:54 +00:00
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__ ) ;
2010-07-16 22:15:09 +00:00
ExploredCellsLookupItemCache . clear ( ) ;
2010-07-17 01:00:31 +00:00
ExploredCellsLookupItemCacheTimer . clear ( ) ;
2010-08-25 23:55:59 +00:00
FowAlphaCellsLookupItemCache . clear ( ) ;
2010-07-16 22:15:09 +00:00
2010-08-04 20:07:39 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
for ( int i = 0 ; i < factions . size ( ) ; + + i ) {
factions [ i ] . end ( ) ;
}
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
factions . clear ( ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-05-03 06:25:54 +00:00
delete techTree ;
techTree = NULL ;
2010-08-04 16:56:24 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-13 05:33:43 +00:00
delete routePlanner ;
routePlanner = 0 ;
2010-08-04 16:56:24 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-13 05:33:43 +00:00
delete cartographer ;
cartographer = 0 ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
void World : : end ( ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
Logger : : getInstance ( ) . add ( " World " , true ) ;
2010-07-16 22:15:09 +00:00
ExploredCellsLookupItemCache . clear ( ) ;
2010-07-17 01:00:31 +00:00
ExploredCellsLookupItemCacheTimer . clear ( ) ;
2010-08-25 23:55:59 +00:00
FowAlphaCellsLookupItemCache . clear ( ) ;
2010-07-16 22:15:09 +00:00
2010-03-12 07:42:55 +00:00
for ( int i = 0 ; i < factions . size ( ) ; + + i ) {
factions [ i ] . end ( ) ;
}
2010-08-04 20:07:39 +00:00
factions . clear ( ) ;
2010-04-23 02:48:56 +00:00
fogOfWarOverride = false ;
2010-03-12 07:42:55 +00:00
//stats will be deleted by BattleEnd
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
// ========================== init ===============================================
2010-04-23 02:48:56 +00:00
void World : : setFogOfWar ( bool value ) {
fogOfWar = value ;
fogOfWarOverride = true ;
if ( game ! = NULL & & game - > getGameSettings ( ) ! = NULL ) {
game - > getGameSettings ( ) - > setFogOfWar ( fogOfWar ) ;
initCells ( fogOfWar ) ; //must be done after knowing faction number and dimensions
2010-05-17 16:02:47 +00:00
//initMinimap();
minimap . setFogOfWar ( fogOfWar ) ;
computeFow ( ) ;
2010-04-23 02:48:56 +00:00
}
}
2010-03-12 07:42:55 +00:00
void World : : init ( Game * game , bool createUnits ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-16 22:15:09 +00:00
ExploredCellsLookupItemCache . clear ( ) ;
2010-07-17 01:00:31 +00:00
ExploredCellsLookupItemCacheTimer . clear ( ) ;
2010-08-25 23:55:59 +00:00
FowAlphaCellsLookupItemCache . clear ( ) ;
2010-07-16 22:15:09 +00:00
this - > game = game ;
2010-03-12 07:42:55 +00:00
scriptManager = game - > getScriptManager ( ) ;
2010-03-27 07:09:34 +00:00
GameSettings * gs = game - > getGameSettings ( ) ;
2010-04-23 02:48:56 +00:00
if ( fogOfWarOverride = = false ) {
fogOfWar = gs - > getFogOfWar ( ) ;
}
2010-12-09 20:41:11 +00:00
2010-03-27 07:09:34 +00:00
initFactionTypes ( gs ) ;
initCells ( fogOfWar ) ; //must be done after knowing faction number and dimensions
2010-03-12 07:42:55 +00:00
initMap ( ) ;
initSplattedTextures ( ) ;
2010-08-07 03:26:38 +00:00
// must be done after initMap()
if ( gs - > getPathFinderType ( ) ! = pfBasic ) {
routePlanner = new RoutePlanner ( this ) ;
cartographer = new Cartographer ( this ) ;
}
2010-07-13 05:33:43 +00:00
unitUpdater . init ( game ) ;
2010-03-12 07:42:55 +00:00
//minimap must be init after sum computation
initMinimap ( ) ;
if ( createUnits ) {
initUnits ( ) ;
}
2010-03-27 07:09:34 +00:00
//initExplorationState(); ... was only for !fog-of-war, now handled in initCells()
2010-03-12 07:42:55 +00:00
computeFow ( ) ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
//load tileset
2010-03-18 21:26:40 +00:00
void World : : loadTileset ( const vector < string > pathList , const string & tilesetName , Checksum * checksum ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-18 21:26:40 +00:00
tileset . loadTileset ( pathList , tilesetName , checksum ) ;
2010-05-27 23:46:38 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-18 21:26:40 +00:00
timeFlow . init ( & tileset ) ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-18 21:26:40 +00:00
}
2010-03-12 07:42:55 +00:00
void World : : loadTileset ( const string & dir , Checksum * checksum ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
tileset . load ( dir , checksum ) ;
2010-05-27 23:46:38 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
timeFlow . init ( & tileset ) ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
//load tech
2010-03-18 21:26:40 +00:00
void World : : loadTech ( const vector < string > pathList , const string & techName , set < string > & factions , Checksum * checksum ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
/*
std : : map < string , TechTree * > & techCache = Shared : : PlatformCommon : : CacheManager : : getCachedItem < std : : map < string , TechTree * > > ( " 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;
2010-03-12 07:42:55 +00:00
}
2010-07-30 07:51:39 +00:00
std : : vector < std : : string > World : : validateFactionTypes ( ) {
return techTree - > validateFactionTypes ( ) ;
}
std : : vector < std : : string > World : : validateResourceTypes ( ) {
return techTree - > validateResourceTypes ( ) ;
}
2010-03-12 07:42:55 +00:00
//load map
void World : : loadMap ( const string & path , Checksum * checksum ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
checksum - > addFile ( path ) ;
2010-05-03 06:25:54 +00:00
map . load ( path , techTree , & tileset ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
//load map
void World : : loadScenario ( const string & path , Checksum * checksum ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
checksum - > addFile ( path ) ;
scenario . load ( path ) ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
// ==================== misc ====================
2010-08-21 18:50:56 +00:00
void World : : updateAllFactionUnits ( ) {
2010-08-29 04:45:15 +00:00
scriptManager - > onTimerTriggerEvent ( ) ;
2010-03-12 07:42:55 +00:00
//units
2010-11-01 16:44:05 +00:00
int factionCount = getFactionCount ( ) ;
for ( int i = 0 ; i < factionCount ; + + i ) {
Faction * faction = getFaction ( i ) ;
if ( faction = = NULL ) {
throw runtime_error ( " faction == NULL " ) ;
}
int unitCount = faction - > getUnitCount ( ) ;
2010-11-07 03:27:06 +00:00
2010-11-01 16:44:05 +00:00
for ( int j = 0 ; j < unitCount ; + + j ) {
Unit * unit = faction - > getUnit ( j ) ;
if ( unit = = NULL ) {
throw runtime_error ( " unit == NULL " ) ;
}
unitUpdater . updateUnit ( unit ) ;
2010-03-12 07:42:55 +00:00
}
}
2010-08-21 18:50:56 +00:00
}
2010-03-12 07:42:55 +00:00
2010-08-21 18:50:56 +00:00
void World : : underTakeDeadFactionUnits ( ) {
2010-08-24 01:21:34 +00:00
int factionIdxToTick = - 1 ;
if ( staggeredFactionUpdates = = true ) {
factionIdxToTick = tickFactionIndex ( ) ;
if ( factionIdxToTick < 0 ) {
return ;
}
}
2010-11-01 16:44:05 +00:00
int factionCount = getFactionCount ( ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] factionIdxToTick = %d, factionCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , factionIdxToTick , factionCount ) ;
2010-08-24 01:21:34 +00:00
2010-03-12 07:42:55 +00:00
//undertake the dead
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < factionCount ; + + i ) {
2010-08-24 01:21:34 +00:00
if ( factionIdxToTick = = - 1 | | factionIdxToTick = = i ) {
2010-11-01 16:44:05 +00:00
Faction * faction = getFaction ( i ) ;
if ( faction = = NULL ) {
throw runtime_error ( " faction == NULL " ) ;
}
int unitCount = faction - > getUnitCount ( ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] factionIdxToTick = %d, i = %d, unitCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , factionIdxToTick , i , unitCount ) ;
for ( int j = unitCount - 1 ; j > = 0 ; j - - ) {
Unit * unit = faction - > getUnit ( j ) ;
2010-08-24 01:21:34 +00:00
2010-11-01 16:44:05 +00:00
if ( unit = = NULL ) {
throw runtime_error ( " unit == NULL " ) ;
}
if ( unit - > getToBeUndertaken ( ) = = true ) {
2010-08-24 01:21:34 +00:00
unit - > undertake ( ) ;
delete unit ;
//j--;
}
2010-03-12 07:42:55 +00:00
}
}
}
2010-08-21 18:50:56 +00:00
}
2010-03-12 07:42:55 +00:00
2010-08-21 18:50:56 +00:00
void World : : updateAllFactionConsumableCosts ( ) {
2010-03-12 07:42:55 +00:00
//food costs
2010-11-01 16:44:05 +00:00
int resourceTypeCount = techTree - > getResourceTypeCount ( ) ;
int factionCount = getFactionCount ( ) ;
for ( int i = 0 ; i < resourceTypeCount ; + + i ) {
const ResourceType * rt = techTree - > getResourceType ( i ) ;
if ( rt ! = NULL & & rt - > getClass ( ) = = rcConsumable & & frameCount % ( rt - > getInterval ( ) * GameConstants : : updateFps ) = = 0 ) {
for ( int j = 0 ; j < factionCount ; + + j ) {
Faction * faction = getFaction ( j ) ;
if ( faction = = NULL ) {
throw runtime_error ( " faction == NULL " ) ;
}
faction - > applyCostsOnInterval ( rt ) ;
2010-03-12 07:42:55 +00:00
}
}
}
2010-08-21 18:50:56 +00:00
}
void World : : update ( ) {
+ + frameCount ;
//time
timeFlow . update ( ) ;
//water effects
2010-12-19 22:33:08 +00:00
waterEffects . update ( 1.0f ) ;
2010-12-23 20:22:40 +00:00
// attack effects
2010-12-19 22:33:08 +00:00
attackEffects . update ( 0.25f ) ;
2010-08-21 18:50:56 +00:00
2010-08-24 01:21:34 +00:00
//bool needToUpdateUnits = true;
//if(staggeredFactionUpdates == true) {
// needToUpdateUnits = (frameCount % (GameConstants::updateFps / GameConstants::maxPlayers) == 0);
//}
2010-08-21 18:50:56 +00:00
2010-08-24 01:21:34 +00:00
//if(needToUpdateUnits == true) {
// SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] needToUpdateUnits = %d, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,needToUpdateUnits,frameCount);
2010-08-24 23:15:33 +00:00
//units
updateAllFactionUnits ( ) ;
2010-08-24 01:21:34 +00:00
2010-08-24 23:15:33 +00:00
//undertake the dead
underTakeDeadFactionUnits ( ) ;
2010-08-24 01:21:34 +00:00
//}
2010-08-21 18:50:56 +00:00
//food costs
updateAllFactionConsumableCosts ( ) ;
2010-03-12 07:42:55 +00:00
//fow smoothing
2010-08-21 18:50:56 +00:00
if ( fogOfWarSmoothing & & ( ( frameCount + 1 ) % ( fogOfWarSmoothingFrameSkip + 1 ) ) = = 0 ) {
float fogFactor = static_cast < float > ( frameCount % GameConstants : : updateFps ) / GameConstants : : updateFps ;
2010-03-12 07:42:55 +00:00
minimap . updateFowTex ( clamp ( fogFactor , 0.f , 1.f ) ) ;
}
//tick
2010-08-24 02:49:55 +00:00
bool needToTick = canTickWorld ( ) ;
2010-08-23 19:49:00 +00:00
if ( needToTick = = true ) {
2010-03-12 07:42:55 +00:00
tick ( ) ;
}
}
2010-08-24 02:49:55 +00:00
bool World : : canTickWorld ( ) const {
//tick
bool needToTick = ( frameCount % GameConstants : : updateFps = = 0 ) ;
if ( staggeredFactionUpdates = = true ) {
needToTick = ( frameCount % ( GameConstants : : updateFps / GameConstants : : maxPlayers ) = = 0 ) ;
}
return needToTick ;
}
2010-08-24 01:21:34 +00:00
int World : : getUpdateFps ( int factionIndex ) const {
int result = GameConstants : : updateFps ;
//if(factionIndex != -1 && staggeredFactionUpdates == true) {
// result = (GameConstants::updateFps / GameConstants::maxPlayers);
//}
return result ;
}
2010-08-23 09:53:04 +00:00
bool World : : canTickFaction ( int factionIdx ) {
2010-08-23 14:48:33 +00:00
int factionUpdateInterval = ( GameConstants : : updateFps / GameConstants : : maxPlayers ) ;
int expectedFactionIdx = ( frameCount / factionUpdateInterval ) - 1 ;
2010-08-23 09:53:04 +00:00
if ( expectedFactionIdx > = GameConstants : : maxPlayers ) {
expectedFactionIdx = expectedFactionIdx % GameConstants : : maxPlayers ;
2010-03-12 07:42:55 +00:00
}
2010-08-23 09:53:04 +00:00
bool result = ( expectedFactionIdx = = factionIdx ) ;
2010-03-12 07:42:55 +00:00
2010-08-23 14:48:33 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] factionIdx = %d, frameCount = %d, GameConstants::updateFps = %d, expectedFactionIdx = %d, factionUpdateInterval = %d, result = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , factionIdx , frameCount , GameConstants : : updateFps , expectedFactionIdx , factionUpdateInterval , result ) ;
2010-08-23 09:53:04 +00:00
return result ;
}
2010-08-23 14:48:33 +00:00
int World : : tickFactionIndex ( ) {
2010-08-23 09:53:04 +00:00
int factionIdxToTick = - 1 ;
for ( int i = 0 ; i < getFactionCount ( ) ; + + i ) {
if ( canTickFaction ( i ) = = true ) {
factionIdxToTick = i ;
break ;
2010-03-12 07:42:55 +00:00
}
}
2010-08-23 14:48:33 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] factionIdxToTick = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , factionIdxToTick ) ;
return factionIdxToTick ;
}
void World : : tick ( ) {
2010-08-23 19:35:55 +00:00
int factionIdxToTick = - 1 ;
2010-08-23 19:49:00 +00:00
if ( staggeredFactionUpdates = = true ) {
2010-08-24 01:21:34 +00:00
factionIdxToTick = tickFactionIndex ( ) ;
2010-08-23 19:49:00 +00:00
if ( factionIdxToTick < 0 ) {
return ;
}
}
2010-08-23 14:48:33 +00:00
computeFow ( factionIdxToTick ) ;
2010-08-23 09:53:04 +00:00
2010-08-23 19:35:55 +00:00
if ( factionIdxToTick = = - 1 | | factionIdxToTick = = 0 ) {
2010-08-23 14:48:33 +00:00
if ( fogOfWarSmoothing = = false ) {
minimap . updateFowTex ( 1.f ) ;
}
2010-08-23 09:53:04 +00:00
}
//increase hp
2010-08-23 19:35:55 +00:00
//int i = factionIdxToTick;
2010-11-01 16:44:05 +00:00
int factionCount = getFactionCount ( ) ;
for ( int i = 0 ; i < factionCount ; + + i ) {
2010-08-23 19:35:55 +00:00
if ( factionIdxToTick = = - 1 | | i = = factionIdxToTick ) {
2010-11-01 16:44:05 +00:00
Faction * faction = getFaction ( i ) ;
if ( faction = = NULL ) {
throw runtime_error ( " faction == NULL " ) ;
}
int unitCount = faction - > getUnitCount ( ) ;
for ( int j = 0 ; j < unitCount ; + + j ) {
Unit * unit = faction - > getUnit ( j ) ;
if ( unit = = NULL ) {
throw runtime_error ( " unit == NULL " ) ;
}
unit - > tick ( ) ;
2010-08-23 09:53:04 +00:00
}
2010-08-23 19:35:55 +00:00
}
}
2010-03-12 07:42:55 +00:00
//compute resources balance
2010-08-23 19:35:55 +00:00
//int k = factionIdxToTick;
2010-11-01 16:44:05 +00:00
factionCount = getFactionCount ( ) ;
for ( int k = 0 ; k < factionCount ; + + k ) {
2010-08-23 19:35:55 +00:00
if ( factionIdxToTick = = - 1 | | k = = factionIdxToTick ) {
2010-08-23 09:53:04 +00:00
Faction * faction = getFaction ( k ) ;
2010-11-01 16:44:05 +00:00
if ( faction = = NULL ) {
throw runtime_error ( " faction == NULL " ) ;
}
2010-08-23 09:53:04 +00:00
//for each resource
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < techTree - > getResourceTypeCount ( ) ; + + i ) {
2010-08-23 09:53:04 +00:00
const ResourceType * rt = techTree - > getResourceType ( i ) ;
//if consumable
2010-11-01 16:44:05 +00:00
if ( rt ! = NULL & & rt - > getClass ( ) = = rcConsumable ) {
2010-08-23 09:53:04 +00:00
int balance = 0 ;
2010-11-01 16:44:05 +00:00
for ( int j = 0 ; j < faction - > getUnitCount ( ) ; + + j ) {
2010-08-23 09:53:04 +00:00
//if unit operative and has this cost
const Unit * u = faction - > getUnit ( j ) ;
2010-11-01 16:44:05 +00:00
if ( u ! = NULL & & u - > isOperative ( ) ) {
2010-08-23 09:53:04 +00:00
const Resource * r = u - > getType ( ) - > getCost ( rt ) ;
2010-11-01 16:44:05 +00:00
if ( r ! = NULL ) {
balance - = u - > getType ( ) - > getCost ( rt ) - > getAmount ( ) ;
2010-08-23 09:53:04 +00:00
}
2010-03-12 07:42:55 +00:00
}
}
2010-08-23 09:53:04 +00:00
faction - > setResourceBalance ( rt , balance ) ;
2010-03-12 07:42:55 +00:00
}
}
2010-08-23 19:35:55 +00:00
}
}
2010-08-23 09:53:04 +00:00
2010-08-07 03:26:38 +00:00
if ( cartographer ! = NULL ) {
cartographer - > tick ( ) ;
}
2010-03-12 07:42:55 +00:00
}
2010-10-19 04:38:55 +00:00
Unit * World : : findUnitById ( int id ) const {
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < getFactionCount ( ) ; + + i ) {
2010-10-19 04:38:55 +00:00
const Faction * faction = getFaction ( i ) ;
2010-07-14 06:59:55 +00:00
Unit * unit = faction - > findUnit ( id ) ;
if ( unit ! = NULL ) {
return unit ;
}
2010-03-12 07:42:55 +00:00
}
return NULL ;
}
2010-11-01 16:44:05 +00:00
const UnitType * World : : findUnitTypeById ( const FactionType * factionType , int id ) {
if ( factionType = = NULL ) {
throw runtime_error ( " factionType == NULL " ) ;
}
for ( int i = 0 ; i < factionType - > getUnitTypeCount ( ) ; + + i ) {
const UnitType * unitType = factionType - > getUnitType ( i ) ;
if ( unitType ! = NULL & & unitType - > getId ( ) = = id ) {
2010-03-12 07:42:55 +00:00
return unitType ;
}
}
return NULL ;
}
2010-11-01 16:44:05 +00:00
//looks for a place for a unit around a start location, returns true if succeded
bool World : : placeUnit ( const Vec2i & startLoc , int radius , Unit * unit , bool spaciated ) {
if ( unit = = NULL ) {
throw runtime_error ( " unit == NULL " ) ;
}
bool freeSpace = false ;
2010-03-12 07:42:55 +00:00
int size = unit - > getType ( ) - > getSize ( ) ;
Field currField = unit - > getCurrField ( ) ;
2010-11-01 16:44:05 +00:00
for ( int r = 1 ; r < radius ; r + + ) {
for ( int i = - r ; i < r ; + + i ) {
for ( int j = - r ; j < r ; + + j ) {
Vec2i pos = Vec2i ( i , j ) + startLoc ;
if ( spaciated ) {
const int spacing = 2 ;
2010-03-12 07:42:55 +00:00
freeSpace = map . isFreeCells ( pos - Vec2i ( spacing ) , size + spacing * 2 , currField ) ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
freeSpace = map . isFreeCells ( pos , size , currField ) ;
}
2010-11-01 16:44:05 +00:00
if ( freeSpace ) {
2010-03-12 07:42:55 +00:00
unit - > setPos ( pos ) ;
unit - > setMeetingPos ( pos - Vec2i ( 1 ) ) ;
return true ;
}
}
}
}
return false ;
}
//clears a unit old position from map and places new position
2010-11-01 16:44:05 +00:00
void World : : moveUnitCells ( Unit * unit ) {
2010-11-09 09:06:52 +00:00
if ( unit = = NULL ) {
2010-11-01 16:44:05 +00:00
throw runtime_error ( " unit == NULL " ) ;
}
2010-03-12 07:42:55 +00:00
Vec2i newPos = unit - > getTargetPos ( ) ;
//newPos must be free or the same pos as current
2010-12-23 20:22:40 +00:00
//assert(map.getCell(unit->getPos())->getUnit(unit->getCurrField())==unit || map.isFreeCell(newPos, unit->getCurrField()));
2010-11-09 09:06:52 +00:00
2010-11-01 16:44:05 +00:00
// Only change cell placement in map if the new position is different
2010-08-25 00:29:56 +00:00
// from the old one
if ( newPos ! = unit - > getPos ( ) ) {
map . clearUnitCells ( unit , unit - > getPos ( ) ) ;
map . putUnitCells ( unit , newPos ) ;
}
2010-10-21 20:31:09 +00:00
// Add resources close by to the faction's cache
unit - > getFaction ( ) - > addCloseResourceTargetToCache ( newPos ) ;
2010-03-12 07:42:55 +00:00
//water splash
2010-11-01 16:44:05 +00:00
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 ) {
2010-03-12 07:42:55 +00:00
waterEffects . addWaterSplash (
2010-05-07 08:01:14 +00:00
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 ( ) ) ;
2010-03-12 07:42:55 +00:00
}
}
}
2010-08-29 04:45:15 +00:00
scriptManager - > onCellTriggerEvent ( unit ) ;
2010-03-12 07:42:55 +00:00
}
2010-12-19 22:33:08 +00:00
void World : : addAttackEffects ( const Unit * unit )
{
attackEffects . addWaterSplash (
Vec2f ( unit - > getPos ( ) . x , unit - > getPos ( ) . y ) , 1 ) ;
}
2010-03-12 07:42:55 +00:00
//returns the nearest unit that can store a type of resource given a position and a faction
2010-11-01 16:44:05 +00:00
Unit * World : : nearestStore ( const Vec2i & pos , int factionIndex , const ResourceType * rt ) {
2010-03-12 07:42:55 +00:00
float currDist = infinity ;
Unit * currUnit = NULL ;
2010-11-01 16:44:05 +00:00
if ( factionIndex > = getFactionCount ( ) ) {
throw runtime_error ( " factionIndex >= getFactionCount() " ) ;
}
for ( int i = 0 ; i < getFaction ( factionIndex ) - > getUnitCount ( ) ; + + i ) {
2010-03-12 07:42:55 +00:00
Unit * u = getFaction ( factionIndex ) - > getUnit ( i ) ;
2010-11-01 16:44:05 +00:00
if ( u ! = NULL ) {
float tmpDist = u - > getPos ( ) . dist ( pos ) ;
if ( tmpDist < currDist & & u - > getType ( ) - > getStore ( rt ) > 0 & & u - > isOperative ( ) ) {
currDist = tmpDist ;
currUnit = u ;
}
}
2010-03-12 07:42:55 +00:00
}
return currUnit ;
}
2010-11-01 16:44:05 +00:00
bool World : : toRenderUnit ( const Unit * unit , const Quad2i & visibleQuad ) const {
if ( unit = = NULL ) {
throw runtime_error ( " unit == NULL " ) ;
}
//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 ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
bool World : : toRenderUnit ( const Unit * unit ) const {
if ( unit = = NULL ) {
throw runtime_error ( " unit == NULL " ) ;
}
2010-03-12 07:42:55 +00:00
2010-12-24 08:43:09 +00:00
if ( showWorldForPlayer ( thisFactionIndex ) = = true ) {
return true ;
}
2010-03-12 07:42:55 +00:00
return
2010-06-16 07:18:06 +00:00
( map . getSurfaceCell ( Map : : toSurfCoords ( unit - > getCenteredPos ( ) ) ) - > isVisible ( thisTeamIndex ) & &
map . getSurfaceCell ( Map : : toSurfCoords ( unit - > getCenteredPos ( ) ) ) - > isExplored ( thisTeamIndex ) ) | |
2010-03-12 07:42:55 +00:00
( unit - > getCurrSkill ( ) - > getClass ( ) = = scAttack & &
2010-06-16 07:18:06 +00:00
map . getSurfaceCell ( Map : : toSurfCoords ( unit - > getTargetPos ( ) ) ) - > isVisible ( thisTeamIndex ) & &
map . getSurfaceCell ( Map : : toSurfCoords ( unit - > getTargetPos ( ) ) ) - > isExplored ( thisTeamIndex ) ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
void World : : createUnit ( const string & unitName , int factionIndex , const Vec2i & pos ) {
2010-05-01 10:46:56 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unitName [%s] factionIndex = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , unitName . c_str ( ) , factionIndex ) ;
2010-11-01 16:44:05 +00:00
if ( factionIndex < factions . size ( ) ) {
2010-03-12 07:42:55 +00:00
Faction * faction = & factions [ factionIndex ] ;
2010-05-29 09:38:00 +00:00
if ( faction - > getIndex ( ) ! = factionIndex ) {
throw runtime_error ( " faction->getIndex() ! = factionIndex " ) ;
}
2010-03-12 07:42:55 +00:00
const FactionType * ft = faction - > getType ( ) ;
const UnitType * ut = ft - > getUnitType ( unitName ) ;
2010-07-21 18:21:40 +00:00
UnitPathInterface * newpath = NULL ;
switch ( game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
newpath = new UnitPathBasic ( ) ;
break ;
case pfRoutePlanner :
newpath = new UnitPath ( ) ;
break ;
2010-07-21 20:40:11 +00:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 18:21:40 +00:00
}
Unit * unit = new Unit ( getNextUnitId ( faction ) , newpath , pos , ut , faction , & map , CardinalDir : : NORTH ) ;
2010-03-12 07:42:55 +00:00
2010-05-29 09:38:00 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unit created for unit [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > toString ( ) . c_str ( ) ) ;
2010-11-01 16:44:05 +00:00
if ( placeUnit ( pos , generationArea , unit , true ) ) {
2010-03-12 07:42:55 +00:00
unit - > create ( true ) ;
unit - > born ( ) ;
scriptManager - > onUnitCreated ( unit ) ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Unit cant be placed " ) ;
}
2010-05-29 09:38:00 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unit created for unit [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > toString ( ) . c_str ( ) ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Invalid faction index in createUnitAtPosition: " + intToStr ( factionIndex ) ) ;
}
2010-05-01 10:46:56 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
void World : : giveResource ( const string & resourceName , int factionIndex , int amount ) {
if ( factionIndex < factions . size ( ) ) {
2010-03-12 07:42:55 +00:00
Faction * faction = & factions [ factionIndex ] ;
2010-05-03 06:25:54 +00:00
const ResourceType * rt = techTree - > getResourceType ( resourceName ) ;
2010-03-12 07:42:55 +00:00
faction - > incResourceAmount ( rt , amount ) ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Invalid faction index in giveResource: " + intToStr ( factionIndex ) ) ;
}
}
2010-11-01 16:44:05 +00:00
void World : : givePositionCommand ( int unitId , const string & commandName , const Vec2i & pos ) {
2010-03-12 07:42:55 +00:00
Unit * unit = findUnitById ( unitId ) ;
2010-11-01 16:44:05 +00:00
if ( unit ! = NULL ) {
2010-03-12 07:42:55 +00:00
CommandClass cc ;
2010-11-01 16:44:05 +00:00
if ( commandName = = " move " ) {
2010-03-12 07:42:55 +00:00
cc = ccMove ;
}
2010-11-01 16:44:05 +00:00
else if ( commandName = = " attack " ) {
2010-03-12 07:42:55 +00:00
cc = ccAttack ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Invalid position commmand: " + commandName ) ;
}
2010-05-01 09:27:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] cc = %d Unit [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , cc , unit - > getFullName ( ) . c_str ( ) ) ;
2010-03-12 07:42:55 +00:00
unit - > giveCommand ( new Command ( unit - > getType ( ) - > getFirstCtOfClass ( cc ) , pos ) ) ;
2010-05-01 09:27:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
else {
throw runtime_error ( " Invalid unitId index in givePositionCommand: " + intToStr ( unitId ) + " commandName = " + commandName ) ;
}
2010-03-12 07:42:55 +00:00
}
2010-08-28 08:06:32 +00:00
void World : : giveAttackCommand ( int unitId , int unitToAttackId ) {
Unit * unit = findUnitById ( unitId ) ;
2010-11-01 16:44:05 +00:00
if ( unit ! = NULL ) {
2010-08-28 08:06:32 +00:00
Unit * targetUnit = findUnitById ( unitToAttackId ) ;
if ( targetUnit ! = NULL ) {
2010-11-01 16:44:05 +00:00
const CommandType * ct = unit - > getType ( ) - > getFirstAttackCommand ( targetUnit - > getCurrField ( ) ) ;
2010-08-28 08:06:32 +00:00
if ( ct ! = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] Unit [%s] is attacking [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > getFullName ( ) . c_str ( ) , targetUnit - > getFullName ( ) . c_str ( ) ) ;
unit - > giveCommand ( new Command ( ct , targetUnit ) ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2010-11-01 16:44:05 +00:00
else {
throw runtime_error ( " Invalid ct in giveAttackCommand: " + intToStr ( unitId ) + " unitToAttackId = " + intToStr ( unitToAttackId ) ) ;
}
}
else {
throw runtime_error ( " Invalid unitToAttackId index in giveAttackCommand: " + intToStr ( unitId ) + " unitToAttackId = " + intToStr ( unitToAttackId ) ) ;
2010-08-28 08:06:32 +00:00
}
}
2010-11-01 16:44:05 +00:00
else {
throw runtime_error ( " Invalid unitId index in giveAttackCommand: " + intToStr ( unitId ) + " unitToAttackId = " + intToStr ( unitToAttackId ) ) ;
}
2010-08-28 08:06:32 +00:00
}
2010-11-01 16:44:05 +00:00
void World : : giveProductionCommand ( int unitId , const string & producedName ) {
2010-03-12 07:42:55 +00:00
Unit * unit = findUnitById ( unitId ) ;
2010-11-01 16:44:05 +00:00
if ( unit ! = NULL ) {
2010-03-12 07:42:55 +00:00
const UnitType * ut = unit - > getType ( ) ;
//Search for a command that can produce the unit
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < ut - > getCommandTypeCount ( ) ; + + i ) {
2010-03-12 07:42:55 +00:00
const CommandType * ct = ut - > getCommandType ( i ) ;
2010-11-01 16:44:05 +00:00
if ( ct ! = NULL & & ct - > getClass ( ) = = ccProduce ) {
2010-03-12 07:42:55 +00:00
const ProduceCommandType * pct = static_cast < const ProduceCommandType * > ( ct ) ;
2010-11-01 16:44:05 +00:00
if ( pct ! = NULL & & pct - > getProducedUnit ( ) - > getName ( ) = = producedName ) {
2010-05-01 09:27:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-01 16:44:05 +00:00
2010-03-12 07:42:55 +00:00
unit - > giveCommand ( new Command ( pct ) ) ;
2010-11-01 16:44:05 +00:00
2010-05-01 09:27:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
break ;
}
}
}
}
2010-11-01 16:44:05 +00:00
else {
throw runtime_error ( " Invalid unitId index in giveProductionCommand: " + intToStr ( unitId ) + " producedName = " + producedName ) ;
}
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
void World : : giveUpgradeCommand ( int unitId , const string & upgradeName ) {
2010-03-12 07:42:55 +00:00
Unit * unit = findUnitById ( unitId ) ;
2010-11-01 16:44:05 +00:00
if ( unit ! = NULL ) {
2010-03-12 07:42:55 +00:00
const UnitType * ut = unit - > getType ( ) ;
//Search for a command that can produce the unit
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < ut - > getCommandTypeCount ( ) ; + + i ) {
2010-03-12 07:42:55 +00:00
const CommandType * ct = ut - > getCommandType ( i ) ;
2010-11-01 16:44:05 +00:00
if ( ct ! = NULL & & ct - > getClass ( ) = = ccUpgrade ) {
2010-03-12 07:42:55 +00:00
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( ct ) ;
2010-11-01 16:44:05 +00:00
if ( uct ! = NULL & & uct - > getProducedUpgrade ( ) - > getName ( ) = = upgradeName ) {
2010-05-01 09:27:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-01 16:44:05 +00:00
2010-03-12 07:42:55 +00:00
unit - > giveCommand ( new Command ( uct ) ) ;
2010-11-01 16:44:05 +00:00
2010-05-01 09:27:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
break ;
}
}
}
}
2010-11-01 16:44:05 +00:00
else {
throw runtime_error ( " Invalid unitId index in giveUpgradeCommand: " + intToStr ( unitId ) + " upgradeName = " + upgradeName ) ;
}
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
int World : : getResourceAmount ( const string & resourceName , int factionIndex ) {
if ( factionIndex < factions . size ( ) ) {
2010-03-12 07:42:55 +00:00
Faction * faction = & factions [ factionIndex ] ;
2010-05-03 06:25:54 +00:00
const ResourceType * rt = techTree - > getResourceType ( resourceName ) ;
2010-03-12 07:42:55 +00:00
return faction - > getResource ( rt ) - > getAmount ( ) ;
}
2010-11-01 16:44:05 +00:00
else {
throw runtime_error ( " Invalid faction index in giveResource: " + intToStr ( factionIndex ) + " resourceName = " + resourceName ) ;
2010-03-12 07:42:55 +00:00
}
}
2010-11-01 16:44:05 +00:00
Vec2i World : : getStartLocation ( int factionIndex ) {
if ( factionIndex < factions . size ( ) ) {
2010-03-12 07:42:55 +00:00
Faction * faction = & factions [ factionIndex ] ;
return map . getStartLocation ( faction - > getStartLocationIndex ( ) ) ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Invalid faction index in getStartLocation: " + intToStr ( factionIndex ) ) ;
}
}
2010-11-01 16:44:05 +00:00
Vec2i World : : getUnitPosition ( int unitId ) {
2010-03-12 07:42:55 +00:00
Unit * unit = findUnitById ( unitId ) ;
2010-11-01 16:44:05 +00:00
if ( unit = = NULL ) {
throw runtime_error ( " Can not find unit to get position unitId = " + intToStr ( unitId ) ) ;
2010-03-12 07:42:55 +00:00
}
return unit - > getPos ( ) ;
}
2010-11-01 16:44:05 +00:00
int World : : getUnitFactionIndex ( int unitId ) {
2010-03-12 07:42:55 +00:00
Unit * unit = findUnitById ( unitId ) ;
2010-11-01 16:44:05 +00:00
if ( unit = = NULL ) {
throw runtime_error ( " Can not find Faction unit to get position unitId = " + intToStr ( unitId ) ) ;
2010-03-12 07:42:55 +00:00
}
return unit - > getFactionIndex ( ) ;
}
2010-11-01 16:44:05 +00:00
int World : : getUnitCount ( int factionIndex ) {
if ( factionIndex < factions . size ( ) ) {
2010-03-12 07:42:55 +00:00
Faction * faction = & factions [ factionIndex ] ;
int count = 0 ;
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < faction - > getUnitCount ( ) ; + + i ) {
2010-03-12 07:42:55 +00:00
const Unit * unit = faction - > getUnit ( i ) ;
2010-11-01 16:44:05 +00:00
if ( unit ! = NULL & & unit - > isAlive ( ) ) {
2010-03-12 07:42:55 +00:00
+ + count ;
}
}
return count ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Invalid faction index in getUnitCount: " + intToStr ( factionIndex ) ) ;
}
}
2010-11-01 16:44:05 +00:00
int World : : getUnitCountOfType ( int factionIndex , const string & typeName ) {
if ( factionIndex < factions . size ( ) ) {
2010-03-12 07:42:55 +00:00
Faction * faction = & factions [ factionIndex ] ;
int count = 0 ;
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < faction - > getUnitCount ( ) ; + + i ) {
2010-03-12 07:42:55 +00:00
const Unit * unit = faction - > getUnit ( i ) ;
2010-11-01 16:44:05 +00:00
if ( unit ! = NULL & & unit - > isAlive ( ) & & unit - > getType ( ) - > getName ( ) = = typeName ) {
2010-03-12 07:42:55 +00:00
+ + count ;
}
}
return count ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " Invalid faction index in getUnitCountOfType: " + intToStr ( factionIndex ) ) ;
}
}
// ==================== PRIVATE ====================
// ==================== private init ====================
//init basic cell state
2010-11-01 16:44:05 +00:00
void World : : initCells ( bool fogOfWar ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
Logger : : getInstance ( ) . add ( " State cells " , true ) ;
2010-09-04 00:32:56 +00:00
for ( int i = 0 ; i < map . getSurfaceW ( ) ; + + i ) {
for ( int j = 0 ; j < map . getSurfaceH ( ) ; + + j ) {
2010-03-12 07:42:55 +00:00
SurfaceCell * sc = map . getSurfaceCell ( i , j ) ;
2010-11-01 16:44:05 +00:00
if ( sc = = NULL ) {
throw runtime_error ( " sc == NULL " ) ;
}
2010-03-12 07:42:55 +00:00
sc - > setFowTexCoord ( Vec2f (
i / ( next2Power ( map . getSurfaceW ( ) ) - 1.f ) ,
j / ( next2Power ( map . getSurfaceH ( ) ) - 1.f ) ) ) ;
2010-04-23 04:29:11 +00:00
for ( int k = 0 ; k < GameConstants : : maxPlayers ; k + + ) {
2010-12-19 08:04:25 +00:00
sc - > setExplored ( k , ( game - > getGameSettings ( ) - > getFlagTypes1 ( ) & ft1_show_map_resources ) = = ft1_show_map_resources ) ;
2010-04-23 04:29:11 +00:00
sc - > setVisible ( k , ! fogOfWar ) ;
2010-03-27 07:09:34 +00:00
}
2010-09-04 00:32:56 +00:00
for ( int k = GameConstants : : maxPlayers ; k < GameConstants : : maxPlayers + GameConstants : : specialFactions ; k + + ) {
sc - > setExplored ( k , true ) ;
sc - > setVisible ( k , true ) ;
}
2010-03-12 07:42:55 +00:00
}
}
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
//init surface textures
2010-11-01 16:44:05 +00:00
void World : : initSplattedTextures ( ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < map . getSurfaceW ( ) - 1 ; + + i ) {
for ( int j = 0 ; j < map . getSurfaceH ( ) - 1 ; + + j ) {
2010-03-12 07:42:55 +00:00
Vec2f coord ;
2010-09-10 08:51:32 +00:00
const Texture2D * texture = NULL ;
2010-03-12 07:42:55 +00:00
SurfaceCell * sc00 = map . getSurfaceCell ( i , j ) ;
SurfaceCell * sc10 = map . getSurfaceCell ( i + 1 , j ) ;
SurfaceCell * sc01 = map . getSurfaceCell ( i , j + 1 ) ;
SurfaceCell * sc11 = map . getSurfaceCell ( i + 1 , j + 1 ) ;
2010-11-01 16:44:05 +00:00
if ( sc00 = = NULL ) {
throw runtime_error ( " sc00 == NULL " ) ;
}
if ( sc10 = = NULL ) {
throw runtime_error ( " sc10 == NULL " ) ;
}
if ( sc01 = = NULL ) {
throw runtime_error ( " sc01 == NULL " ) ;
}
if ( sc11 = = NULL ) {
throw runtime_error ( " sc11 == NULL " ) ;
}
tileset . addSurfTex ( sc00 - > getSurfaceType ( ) ,
sc10 - > getSurfaceType ( ) ,
sc01 - > getSurfaceType ( ) ,
sc11 - > getSurfaceType ( ) ,
coord , texture ) ;
2010-03-12 07:42:55 +00:00
sc00 - > setSurfTexCoord ( coord ) ;
sc00 - > setSurfaceTexture ( texture ) ;
}
}
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
//creates each faction looking at each faction name contained in GameSettings
2010-11-01 16:44:05 +00:00
void World : : initFactionTypes ( GameSettings * gs ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
Logger : : getInstance ( ) . add ( " Faction types " , true ) ;
2010-11-01 16:44:05 +00:00
if ( gs = = NULL ) {
throw runtime_error ( " gs == NULL " ) ;
}
if ( gs - > getFactionCount ( ) > map . getMaxPlayers ( ) ) {
2010-03-12 07:42:55 +00:00
throw runtime_error ( " This map only supports " + intToStr ( map . getMaxPlayers ( ) ) + " players " ) ;
}
//create stats
stats . init ( gs - > getFactionCount ( ) , gs - > getThisFactionIndex ( ) , gs - > getDescription ( ) ) ;
2010-09-12 05:05:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
//create factions
this - > thisFactionIndex = gs - > getThisFactionIndex ( ) ;
factions . resize ( gs - > getFactionCount ( ) ) ;
2010-09-12 05:05:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] factions.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , factions . size ( ) ) ;
for ( int i = 0 ; i < factions . size ( ) ; + + i ) {
2010-10-28 00:51:25 +00:00
FactionType * ft = techTree - > getTypeByName ( gs - > getFactionTypeName ( i ) ) ;
2010-11-01 16:44:05 +00:00
if ( ft = = NULL ) {
throw runtime_error ( " ft == NULL " ) ;
}
factions [ i ] . init ( ft , gs - > getFactionControl ( i ) , techTree , game , i , gs - > getTeam ( i ) ,
gs - > getStartLocationIndex ( i ) , i = = thisFactionIndex , gs - > getDefaultResources ( ) ) ;
2010-03-12 07:42:55 +00:00
stats . setTeam ( i , gs - > getTeam ( i ) ) ;
stats . setFactionTypeName ( i , formatString ( gs - > getFactionTypeName ( i ) ) ) ;
2010-09-03 07:12:40 +00:00
stats . setPersonalityType ( i , getFaction ( i ) - > getType ( ) - > getPersonalityType ( ) ) ;
2010-03-12 07:42:55 +00:00
stats . setControl ( i , gs - > getFactionControl ( i ) ) ;
2010-11-25 22:45:08 +00:00
stats . setResourceMultiplier ( i , ( gs - > getResourceMultiplierIndex ( i ) + 5 ) * 0.1f ) ;
2010-06-24 01:23:18 +00:00
stats . setPlayerName ( i , gs - > getNetworkPlayerName ( i ) ) ;
2010-11-09 09:06:52 +00:00
stats . setPlayerColor ( i , getFaction ( i ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
2010-03-12 07:42:55 +00:00
}
2010-12-09 20:41:11 +00:00
2010-09-12 05:05:08 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( factions . size ( ) > 0 ) {
thisTeamIndex = getFaction ( thisFactionIndex ) - > getTeam ( ) ;
}
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
void World : : initMinimap ( ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-01 16:44:05 +00:00
minimap . init ( map . getW ( ) , map . getH ( ) , this , game - > getGameSettings ( ) - > getFogOfWar ( ) ) ;
2010-03-12 07:42:55 +00:00
Logger : : getInstance ( ) . add ( " Compute minimap surface " , true ) ;
2010-11-01 16:44:05 +00:00
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
//place units randomly aroud start location
2010-11-01 16:44:05 +00:00
void World : : initUnits ( ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
Logger : : getInstance ( ) . add ( " Generate elements " , true ) ;
//put starting units
2010-11-01 16:44:05 +00:00
for ( int i = 0 ; i < getFactionCount ( ) ; + + i ) {
2010-03-12 07:42:55 +00:00
Faction * f = & factions [ i ] ;
const FactionType * ft = f - > getType ( ) ;
2010-11-01 16:44:05 +00:00
for ( int j = 0 ; j < ft - > getStartingUnitCount ( ) ; + + j ) {
2010-03-12 07:42:55 +00:00
const UnitType * ut = ft - > getStartingUnit ( j ) ;
int initNumber = ft - > getStartingUnitAmount ( j ) ;
2010-11-01 16:44:05 +00:00
for ( int l = 0 ; l < initNumber ; l + + ) {
2010-07-21 18:21:40 +00:00
UnitPathInterface * newpath = NULL ;
switch ( game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
newpath = new UnitPathBasic ( ) ;
break ;
case pfRoutePlanner :
newpath = new UnitPath ( ) ;
break ;
2010-07-21 20:40:11 +00:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 18:21:40 +00:00
}
Unit * unit = new Unit ( getNextUnitId ( f ) , newpath , Vec2i ( 0 ) , ut , f , & map , CardinalDir : : NORTH ) ;
2010-03-12 07:42:55 +00:00
int startLocationIndex = f - > getStartLocationIndex ( ) ;
2010-11-01 16:44:05 +00:00
if ( placeUnit ( map . getStartLocation ( startLocationIndex ) , generationArea , unit , true ) ) {
2010-03-12 07:42:55 +00:00
unit - > create ( true ) ;
unit - > born ( ) ;
}
2010-11-01 16:44:05 +00:00
else {
2010-03-12 07:42:55 +00:00
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 ) ) ;
}
2010-07-13 05:33:43 +00:00
if ( unit - > getType ( ) - > hasSkillClass ( scBeBuilt ) ) {
2010-08-07 03:26:38 +00:00
map . flatternTerrain ( unit ) ;
if ( cartographer ! = NULL ) {
cartographer - > updateMapMetrics ( unit - > getPos ( ) , unit - > getType ( ) - > getSize ( ) ) ;
}
2010-03-12 07:42:55 +00:00
}
2010-05-29 09:38:00 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unit created for unit [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > toString ( ) . c_str ( ) ) ;
2010-03-12 07:42:55 +00:00
}
}
}
map . computeNormals ( ) ;
map . computeInterpolatedHeights ( ) ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
2010-11-01 16:44:05 +00:00
void World : : initMap ( ) {
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
map . init ( ) ;
2010-05-03 06:25:54 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 07:42:55 +00:00
}
// ==================== exploration ====================
2010-11-01 16:44:05 +00:00
void World : : exploreCells ( const Vec2i & newPos , int sightRange , int teamIndex ) {
2010-08-24 23:36:23 +00:00
bool cacheLookupPosResult = false ;
bool cacheLookupSightResult = false ;
2010-12-24 08:43:09 +00:00
// cache lookup of previously calculated cells + sight range
2010-07-17 06:33:40 +00:00
if ( MaxExploredCellsLookupItemCache > 0 ) {
if ( difftime ( time ( NULL ) , ExploredCellsLookupItem : : lastDebug ) > = 10 ) {
ExploredCellsLookupItem : : lastDebug = time ( NULL ) ;
//printf("In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,ExploredCellsLookupItemCache.size());
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , ExploredCellsLookupItemCache . size ( ) ) ;
2010-09-09 05:42:19 +00:00
SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , ExploredCellsLookupItemCache . size ( ) ) ;
2010-07-17 06:33:40 +00:00
}
2010-07-16 22:15:09 +00:00
2010-08-24 23:15:33 +00:00
// Ok we limit the cache size due to possible RAM constraints when
2010-07-17 06:33:40 +00:00
// the threshold is met
bool MaxExploredCellsLookupItemCacheTriggered = false ;
if ( ExploredCellsLookupItemCache . size ( ) > = MaxExploredCellsLookupItemCache ) {
MaxExploredCellsLookupItemCacheTriggered = true ;
// Snag the oldest entry in the list
std : : map < int , ExploredCellsLookupKey > : : reverse_iterator purgeItem = ExploredCellsLookupItemCacheTimer . rbegin ( ) ;
2010-07-16 22:15:09 +00:00
2010-08-24 23:15:33 +00:00
ExploredCellsLookupItemCache [ purgeItem - > second . pos ] . erase ( purgeItem - > second . sightRange ) ;
2010-07-16 22:15:09 +00:00
2010-07-17 06:33:40 +00:00
if ( ExploredCellsLookupItemCache [ purgeItem - > second . pos ] . size ( ) = = 0 ) {
ExploredCellsLookupItemCache . erase ( purgeItem - > second . pos ) ;
}
ExploredCellsLookupItemCacheTimer . erase ( purgeItem - > first ) ;
2010-07-16 22:15:09 +00:00
}
2010-08-24 23:15:33 +00:00
// Check the cache for the pos, sightrange and use from
2010-07-17 06:33:40 +00:00
// cache if already found
2010-08-24 23:15:33 +00:00
std : : map < Vec2i , std : : map < int , ExploredCellsLookupItem > > : : iterator iterFind = ExploredCellsLookupItemCache . find ( newPos ) ;
2010-07-17 06:33:40 +00:00
if ( iterFind ! = ExploredCellsLookupItemCache . end ( ) ) {
2010-08-24 23:36:23 +00:00
cacheLookupPosResult = true ;
2010-08-24 23:15:33 +00:00
std : : map < int , ExploredCellsLookupItem > : : iterator iterFind2 = iterFind - > second . find ( sightRange ) ;
2010-07-17 06:33:40 +00:00
if ( iterFind2 ! = iterFind - > second . end ( ) ) {
2010-08-24 23:36:23 +00:00
cacheLookupSightResult = true ;
2010-07-16 22:15:09 +00:00
2010-08-24 23:15:33 +00:00
std : : vector < SurfaceCell * > & cellList = iterFind2 - > second . exploredCellList ;
for ( int idx2 = 0 ; idx2 < cellList . size ( ) ; + + idx2 ) {
SurfaceCell * sc = cellList [ idx2 ] ;
sc - > setExplored ( teamIndex , true ) ;
}
cellList = iterFind2 - > second . visibleCellList ;
for ( int idx2 = 0 ; idx2 < cellList . size ( ) ; + + idx2 ) {
SurfaceCell * sc = cellList [ idx2 ] ;
sc - > setVisible ( teamIndex , true ) ;
}
2010-07-16 22:15:09 +00:00
2010-08-24 23:15:33 +00:00
// Only start worrying about updating the cache timer if we
// have hit the threshold
if ( MaxExploredCellsLookupItemCacheTriggered = = true ) {
// Remove the old timer entry since the search key id is stale
ExploredCellsLookupItemCacheTimer . erase ( iterFind2 - > second . ExploredCellsLookupItemCacheTimerCountIndex ) ;
iterFind2 - > second . ExploredCellsLookupItemCacheTimerCountIndex = ExploredCellsLookupItemCacheTimerCount + + ;
2010-07-16 22:15:09 +00:00
2010-08-24 23:15:33 +00:00
ExploredCellsLookupKey lookupKey ;
lookupKey . pos = newPos ;
lookupKey . sightRange = sightRange ;
lookupKey . teamIndex = teamIndex ;
2010-07-16 22:15:09 +00:00
2010-08-24 23:15:33 +00:00
// Add a new search key since we just used this item
ExploredCellsLookupItemCacheTimer [ iterFind2 - > second . ExploredCellsLookupItemCacheTimerCountIndex ] = lookupKey ;
2010-07-17 06:33:40 +00:00
}
2010-08-24 23:15:33 +00:00
return ;
2010-07-14 06:59:55 +00:00
}
}
}
2010-03-12 07:42:55 +00:00
Vec2i newSurfPos = Map : : toSurfCoords ( newPos ) ;
int surfSightRange = sightRange / Map : : cellScale + 1 ;
2010-07-16 22:15:09 +00:00
// Explore, this code is quite expensive when we have lots of units
2010-07-17 01:00:31 +00:00
ExploredCellsLookupItem item ;
2010-09-09 05:42:19 +00:00
int loopCount = 0 ;
2010-08-24 23:15:33 +00:00
for ( int i = - surfSightRange - indirectSightRange - 1 ; i < = surfSightRange + indirectSightRange + 1 ; + + i ) {
for ( int j = - surfSightRange - indirectSightRange - 1 ; j < = surfSightRange + indirectSightRange + 1 ; + + j ) {
2010-09-09 05:42:19 +00:00
loopCount + + ;
Vec2i currRelPos = Vec2i ( i , j ) ;
2010-03-12 07:42:55 +00:00
Vec2i currPos = newSurfPos + currRelPos ;
if ( map . isInsideSurface ( currPos ) ) {
SurfaceCell * sc = map . getSurfaceCell ( currPos ) ;
//explore
2010-09-09 05:42:19 +00:00
//if(Vec2i(0).dist(currRelPos) < surfSightRange + indirectSightRange + 1) {
if ( currRelPos . length ( ) < surfSightRange + indirectSightRange + 1 ) {
2010-03-12 07:42:55 +00:00
sc - > setExplored ( teamIndex , true ) ;
2010-07-14 06:59:55 +00:00
item . exploredCellList . push_back ( sc ) ;
2010-03-12 07:42:55 +00:00
}
//visible
2010-09-09 05:42:19 +00:00
//if(Vec2i(0).dist(currRelPos) < surfSightRange) {
if ( currRelPos . length ( ) < surfSightRange ) {
2010-03-12 07:42:55 +00:00
sc - > setVisible ( teamIndex , true ) ;
2010-07-14 06:59:55 +00:00
item . visibleCellList . push_back ( sc ) ;
2010-03-12 07:42:55 +00:00
}
}
}
}
2010-07-14 06:59:55 +00:00
2010-07-16 22:15:09 +00:00
// Ok update our caches with the latest info for this position, sight and team
2010-07-17 06:33:40 +00:00
if ( MaxExploredCellsLookupItemCache > 0 ) {
if ( item . exploredCellList . size ( ) > 0 | | item . visibleCellList . size ( ) > 0 ) {
//ExploredCellsLookupItemCache.push_back(item);
item . ExploredCellsLookupItemCacheTimerCountIndex = ExploredCellsLookupItemCacheTimerCount + + ;
2010-08-24 23:15:33 +00:00
ExploredCellsLookupItemCache [ newPos ] [ sightRange ] = item ;
2010-07-17 06:33:40 +00:00
ExploredCellsLookupKey lookupKey ;
lookupKey . pos = newPos ;
lookupKey . sightRange = sightRange ;
lookupKey . teamIndex = teamIndex ;
ExploredCellsLookupItemCacheTimer [ item . ExploredCellsLookupItemCacheTimerCountIndex ] = lookupKey ;
}
2010-07-14 06:59:55 +00:00
}
2010-03-12 07:42:55 +00:00
}
2010-12-24 08:43:09 +00:00
bool World : : showWorldForPlayer ( int factionIndex ) const {
bool ret = false ;
if ( factionIndex = = thisFactionIndex ) {
// Player is an Observer
if ( thisTeamIndex = = GameConstants : : maxPlayers - 1 + fpt_Observer ) {
ret = true ;
}
// Game over and not a network game
else if ( game - > getGameOver ( ) = = true & &
game - > getGameSettings ( ) - > isNetworkGame ( ) = = false ) {
ret = true ;
}
// Game is over but playing a Network game so check if we can
// turn off fog of war?
else if ( game - > getGameOver ( ) = = true & &
game - > getGameSettings ( ) - > isNetworkGame ( ) = = true & &
game - > getGameSettings ( ) - > getEnableObserverModeAtEndGame ( ) = = true ) {
ret = true ;
// If the player has at least 1 Unit alive that is mobile (can move)
// then we cannot turn off fog of war
for ( int i = 0 ; i < getFaction ( factionIndex ) - > getUnitCount ( ) ; + + i ) {
Unit * unit = getFaction ( factionIndex ) - > getUnit ( i ) ;
if ( unit ! = NULL & & unit - > isAlive ( ) & & unit - > getType ( ) - > isMobile ( ) = = true ) {
ret = false ;
break ;
}
}
}
}
return ret ;
}
2010-03-12 07:42:55 +00:00
//computes the fog of war texture, contained in the minimap
2010-08-23 14:48:33 +00:00
void World : : computeFow ( int factionIdxToTick ) {
2010-08-24 23:15:33 +00:00
minimap . resetFowTex ( ) ;
2010-03-12 07:42:55 +00:00
//reset cells
2010-08-23 14:48:33 +00:00
if ( factionIdxToTick = = - 1 | | factionIdxToTick = = this - > thisFactionIndex ) {
2010-09-04 00:32:56 +00:00
for ( int i = 0 ; i < map . getSurfaceW ( ) ; + + i ) {
for ( int j = 0 ; j < map . getSurfaceH ( ) ; + + j ) {
for ( int k = 0 ; k < GameConstants : : maxPlayers + GameConstants : : specialFactions ; + + k ) {
if ( fogOfWar | | k ! = thisTeamIndex ) {
2010-12-24 08:43:09 +00:00
if ( showWorldForPlayer ( k ) = = true ) {
//map.getSurfaceCell(i, j)->setVisible(k, true);
//map.getSurfaceCell(i, j)->setExplored(k, true);
2010-09-04 00:32:56 +00:00
const Vec2i pos ( i , j ) ;
2010-09-04 01:32:50 +00:00
Vec2i surfPos = pos ;
2010-09-04 00:32:56 +00:00
//compute max alpha
float maxAlpha = 0.0f ;
2010-12-24 08:43:09 +00:00
if ( surfPos . x > 1 & & surfPos . y > 1 & &
surfPos . x < map . getSurfaceW ( ) - 2 & &
surfPos . y < map . getSurfaceH ( ) - 2 ) {
2010-09-04 00:32:56 +00:00
maxAlpha = 1.f ;
}
2010-12-24 08:43:09 +00:00
else if ( surfPos . x > 0 & & surfPos . y > 0 & &
surfPos . x < map . getSurfaceW ( ) - 1 & &
surfPos . y < map . getSurfaceH ( ) - 1 ) {
2010-09-04 00:32:56 +00:00
maxAlpha = 0.3f ;
}
//compute alpha
float alpha = maxAlpha ;
minimap . incFowTextureAlphaSurface ( surfPos , alpha ) ;
}
else {
map . getSurfaceCell ( i , j ) - > setVisible ( k , false ) ;
}
2010-08-23 14:48:33 +00:00
}
2010-03-12 07:42:55 +00:00
}
}
}
}
2010-09-15 23:32:29 +00:00
else {
// Deal with observers
for ( int i = 0 ; i < map . getSurfaceW ( ) ; + + i ) {
for ( int j = 0 ; j < map . getSurfaceH ( ) ; + + j ) {
for ( int k = 0 ; k < GameConstants : : maxPlayers + GameConstants : : specialFactions ; + + k ) {
if ( fogOfWar | | k ! = thisTeamIndex ) {
if ( k = = thisTeamIndex & & thisTeamIndex = = GameConstants : : maxPlayers - 1 + fpt_Observer ) {
2010-12-24 08:43:09 +00:00
//map.getSurfaceCell(i, j)->setVisible(k, true);
//map.getSurfaceCell(i, j)->setExplored(k, true);
2010-09-15 23:32:29 +00:00
const Vec2i pos ( i , j ) ;
Vec2i surfPos = pos ;
//compute max alpha
float maxAlpha = 0.0f ;
2010-12-24 08:43:09 +00:00
if ( surfPos . x > 1 & & surfPos . y > 1 & &
surfPos . x < map . getSurfaceW ( ) - 2 & &
surfPos . y < map . getSurfaceH ( ) - 2 ) {
2010-09-15 23:32:29 +00:00
maxAlpha = 1.f ;
}
2010-12-24 08:43:09 +00:00
else if ( surfPos . x > 0 & & surfPos . y > 0 & &
surfPos . x < map . getSurfaceW ( ) - 1 & &
surfPos . y < map . getSurfaceH ( ) - 1 ) {
2010-09-15 23:32:29 +00:00
maxAlpha = 0.3f ;
}
//compute alpha
float alpha = maxAlpha ;
minimap . incFowTextureAlphaSurface ( surfPos , alpha ) ;
}
}
}
}
}
}
2010-03-12 07:42:55 +00:00
//compute cells
2010-08-23 14:48:33 +00:00
for ( int i = 0 ; i < getFactionCount ( ) ; + + i ) {
if ( factionIdxToTick = = - 1 | | factionIdxToTick = = this - > thisFactionIndex ) {
for ( int j = 0 ; j < getFaction ( i ) - > getUnitCount ( ) ; + + j ) {
Unit * unit = getFaction ( i ) - > getUnit ( j ) ;
2010-03-12 07:42:55 +00:00
2010-08-23 14:48:33 +00:00
//exploration
2010-09-09 01:44:25 +00:00
unit - > exploreCells ( ) ;
2010-03-12 07:42:55 +00:00
}
}
}
//fire
2010-08-23 14:48:33 +00:00
for ( int i = 0 ; i < getFactionCount ( ) ; + + i ) {
if ( factionIdxToTick = = - 1 | | factionIdxToTick = = this - > thisFactionIndex ) {
for ( int j = 0 ; j < getFaction ( i ) - > getUnitCount ( ) ; + + j ) {
Unit * unit = getFaction ( i ) - > getUnit ( j ) ;
//fire
ParticleSystem * fire = unit - > getFire ( ) ;
2010-12-24 08:43:09 +00:00
if ( fire ! = NULL ) {
bool cellVisible = showWorldForPlayer ( thisFactionIndex ) ;
if ( cellVisible = = false ) {
cellVisible = map . getSurfaceCell ( Map : : toSurfCoords ( unit - > getPos ( ) ) ) - > isVisible ( thisTeamIndex ) ;
}
fire - > setActive ( cellVisible ) ;
2010-08-23 14:48:33 +00:00
}
2010-03-12 07:42:55 +00:00
}
}
}
//compute texture
2010-08-23 15:10:37 +00:00
if ( fogOfWar ) {
for ( int i = 0 ; i < getFactionCount ( ) ; + + i ) {
2010-08-25 23:55:59 +00:00
Faction * faction = getFaction ( i ) ;
2010-09-04 00:32:56 +00:00
if ( faction - > getTeam ( ) = = thisTeamIndex ) {
//if(thisTeamIndex == GameConstants::maxPlayers + fpt_Observer) {
2010-08-25 23:55:59 +00:00
for ( int j = 0 ; j < faction - > getUnitCount ( ) ; + + j ) {
const Unit * unit = faction - > getUnit ( j ) ;
if ( unit - > isOperative ( ) ) {
int sightRange = unit - > getType ( ) - > getSight ( ) ;
bool foundInCache = false ;
std : : map < Vec2i , std : : map < int , FowAlphaCellsLookupItem > > : : iterator iterMap = FowAlphaCellsLookupItemCache . find ( unit - > getPos ( ) ) ;
if ( iterMap ! = FowAlphaCellsLookupItemCache . end ( ) ) {
std : : map < int , FowAlphaCellsLookupItem > : : iterator iterMap2 = iterMap - > second . find ( sightRange ) ;
if ( iterMap2 ! = iterMap - > second . end ( ) ) {
foundInCache = true ;
FowAlphaCellsLookupItem & cellList = iterMap2 - > second ;
for ( int k = 0 ; k < cellList . surfPosList . size ( ) ; + + k ) {
Vec2i & surfPos = cellList . surfPosList [ k ] ;
float & alpha = cellList . alphaList [ k ] ;
minimap . incFowTextureAlphaSurface ( surfPos , alpha ) ;
}
}
}
if ( foundInCache = = false ) {
FowAlphaCellsLookupItem itemCache ;
2010-08-23 15:10:37 +00:00
//iterate through all cells
PosCircularIterator pci ( & map , unit - > getPos ( ) , sightRange + indirectSightRange ) ;
while ( pci . next ( ) ) {
const Vec2i pos = pci . getPos ( ) ;
Vec2i surfPos = Map : : toSurfCoords ( pos ) ;
//compute max alpha
float maxAlpha = 0.0f ;
if ( surfPos . x > 1 & & surfPos . y > 1 & & surfPos . x < map . getSurfaceW ( ) - 2 & & surfPos . y < map . getSurfaceH ( ) - 2 ) {
maxAlpha = 1.f ;
}
else if ( surfPos . x > 0 & & surfPos . y > 0 & & surfPos . x < map . getSurfaceW ( ) - 1 & & surfPos . y < map . getSurfaceH ( ) - 1 ) {
maxAlpha = 0.3f ;
}
//compute alpha
float alpha = maxAlpha ;
float dist = unit - > getPos ( ) . dist ( pos ) ;
if ( dist > sightRange ) {
alpha = clamp ( 1.f - ( dist - sightRange ) / ( indirectSightRange ) , 0.f , maxAlpha ) ;
}
minimap . incFowTextureAlphaSurface ( surfPos , alpha ) ;
2010-08-25 23:55:59 +00:00
itemCache . surfPosList . push_back ( surfPos ) ;
itemCache . alphaList . push_back ( alpha ) ;
}
if ( itemCache . surfPosList . size ( ) > 0 ) {
FowAlphaCellsLookupItemCache [ unit - > getPos ( ) ] [ sightRange ] = itemCache ;
2010-08-23 14:48:33 +00:00
}
2010-03-12 07:42:55 +00:00
}
}
}
2010-08-25 23:55:59 +00:00
}
2010-08-23 15:10:37 +00:00
}
2010-03-12 07:42:55 +00:00
}
}
2010-12-19 08:04:25 +00:00
const GameSettings * World : : getGameSettings ( ) const {
return ( game ! = NULL ? game - > getReadOnlyGameSettings ( ) : NULL ) ;
}
2010-08-23 14:48:33 +00:00
// WARNING! This id is critical! Make sure it fits inside the network packet
2010-05-31 09:45:54 +00:00
// (currently cannot be larger than 2,147,483,647)
// Make sure each faction has their own unique section of id #'s for proper
// multi-platform play
// Calculates the unit unit ID for each faction
//
2010-05-31 09:24:44 +00:00
int World : : getNextUnitId ( Faction * faction ) {
if ( mapFactionNextUnitId . find ( faction - > getIndex ( ) ) = = mapFactionNextUnitId . end ( ) ) {
2010-05-31 09:45:54 +00:00
mapFactionNextUnitId [ faction - > getIndex ( ) ] = faction - > getIndex ( ) * 100000 ;
2010-05-31 09:24:44 +00:00
}
return mapFactionNextUnitId [ faction - > getIndex ( ) ] + + ;
}
2010-05-20 20:19:34 +00:00
std : : string World : : DumpWorldToLog ( bool consoleBasicInfoOnly ) const {
2010-12-09 20:41:11 +00:00
2010-05-18 03:53:57 +00:00
string debugWorldLogFile = Config : : getInstance ( ) . getString ( " DebugWorldLogFile " , " debugWorld.log " ) ;
2010-12-09 20:41:11 +00:00
if ( getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) ! = " " ) {
debugWorldLogFile = getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) + debugWorldLogFile ;
2010-05-20 20:19:34 +00:00
}
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 ;
2010-12-09 20:41:11 +00:00
2010-05-20 20:19:34 +00:00
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 {
2010-05-18 03:53:57 +00:00
2010-05-20 20:19:34 +00:00
std : : ofstream logFile ;
logFile . open ( debugWorldLogFile . c_str ( ) , ios_base : : out | ios_base : : trunc ) ;
2010-05-18 03:53:57 +00:00
2010-05-20 20:19:34 +00:00
logFile < < " World debug information: " < < std : : endl ;
logFile < < " ======================== " < < std : : endl ;
2010-05-18 03:53:57 +00:00
2010-05-20 20:19:34 +00:00
//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 ;
}
2010-05-18 03:53:57 +00:00
2010-05-20 20:19:34 +00:00
//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 ;
}
2010-05-18 03:53:57 +00:00
}
}
2010-05-20 20:19:34 +00:00
logFile . close ( ) ;
}
2010-05-18 03:53:57 +00:00
return debugWorldLogFile ;
}
2010-03-12 07:42:55 +00:00
} } //end namespace