2010-03-19 19:58:46 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2011-12-14 08:40:48 +01:00
// Copyright (C) 2001-2008 Martiño Figueroa
2010-03-19 19:58:46 +01: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 "faction.h"
# include <algorithm>
# include <cassert>
# include "resource_type.h"
# include "unit.h"
# include "util.h"
# include "sound_renderer.h"
# include "renderer.h"
# include "tech_tree.h"
# include "game.h"
2010-11-01 17:44:05 +01:00
# include "config.h"
2011-03-21 02:03:14 +01:00
# include "randomgen.h"
2010-11-01 17:44:05 +01:00
# include "leak_dumper.h"
2010-03-19 19:58:46 +01:00
using namespace Shared : : Util ;
2011-03-21 02:03:14 +01:00
using Shared : : Util : : RandomGen ;
2010-03-19 19:58:46 +01:00
2011-03-18 04:53:06 +01:00
namespace Glest { namespace Game {
2011-09-25 06:07:59 +02:00
bool CommandGroupUnitSorterId : : operator ( ) ( const int l , const int r ) {
const Unit * lUnit = faction - > findUnit ( l ) ;
const Unit * rUnit = faction - > findUnit ( r ) ;
if ( ! lUnit ) {
printf ( " Error lUnit == NULL for id = %d factionIndex = %d \n " , l , faction - > getIndex ( ) ) ;
2013-11-19 07:14:06 +01:00
for ( unsigned int i = 0 ; i < ( unsigned int ) faction - > getUnitCount ( ) ; + + i ) {
2013-06-13 10:55:48 +02:00
printf ( " %u / %d id = %d [%s] \n " , i , faction - > getUnitCount ( ) , faction - > getUnit ( i ) - > getId ( ) , faction - > getUnit ( i ) - > getType ( ) - > getName ( false ) . c_str ( ) ) ;
2011-09-25 06:07:59 +02:00
}
}
if ( ! rUnit ) {
printf ( " Error rUnit == NULL for id = %d factionIndex = %d \n " , r , faction - > getIndex ( ) ) ;
2013-11-19 07:14:06 +01:00
for ( unsigned int i = 0 ; i < ( unsigned int ) faction - > getUnitCount ( ) ; + + i ) {
2013-06-13 10:55:48 +02:00
printf ( " %u / %d id = %d [%s] \n " , i , faction - > getUnitCount ( ) , faction - > getUnit ( i ) - > getId ( ) , faction - > getUnit ( i ) - > getType ( ) - > getName ( false ) . c_str ( ) ) ;
2011-09-25 06:07:59 +02:00
}
}
CommandGroupUnitSorter sorter ;
return sorter . compare ( lUnit , rUnit ) ;
}
2011-09-23 20:54:35 +02:00
bool CommandGroupUnitSorter : : operator ( ) ( const Unit * l , const Unit * r ) {
2011-09-25 06:07:59 +02:00
return compare ( l , r ) ;
}
bool CommandGroupUnitSorter : : compare ( const Unit * l , const Unit * r ) {
//printf("l [%p] r [%p] <>",l,r);
2011-09-21 08:51:28 +02:00
if ( ! l ) {
printf ( " Error l == NULL \n " ) ;
}
if ( ! r ) {
printf ( " Error r == NULL \n " ) ;
}
assert ( l & & r ) ;
2011-09-22 22:42:06 +02:00
if ( l = = NULL | | r = = NULL )
printf ( " Unit l [%s - %d] r [%s - %d] \n " ,
2013-06-13 10:55:48 +02:00
( l ! = NULL ? l - > getType ( ) - > getName ( false ) . c_str ( ) : " null " ) ,
2011-09-22 22:42:06 +02:00
( l ! = NULL ? l - > getId ( ) : - 1 ) ,
2013-06-13 10:55:48 +02:00
( r ! = NULL ? r - > getType ( ) - > getName ( false ) . c_str ( ) : " null " ) ,
2011-09-22 22:42:06 +02:00
( r ! = NULL ? r - > getId ( ) : - 1 ) ) ;
2011-09-21 08:51:28 +02:00
2011-09-09 19:49:10 +02:00
bool result = false ;
2011-09-25 06:07:59 +02:00
// If comparer is null or dead
2011-09-22 22:42:06 +02:00
if ( r = = NULL | | r - > isAlive ( ) = = false ) {
2011-09-09 22:30:13 +02:00
// if source is null or dead also
2011-09-22 22:42:06 +02:00
if ( ( l = = NULL | | l - > isAlive ( ) = = false ) ) {
2011-09-09 22:30:13 +02:00
return false ;
}
return true ;
}
2011-09-22 22:42:06 +02:00
else if ( ( l = = NULL | | l - > isAlive ( ) = = false ) ) {
2011-09-09 22:30:13 +02:00
return false ;
}
2011-07-05 17:43:39 +02:00
2011-09-22 22:42:06 +02:00
// const Command *command= l->getCurrrentCommandThreadSafe();
// const Command *commandPeer = r->getCurrrentCommandThreadSafe();
const Command * command = l - > getCurrCommand ( ) ;
const Command * commandPeer = r - > getCurrCommand ( ) ;
2011-07-06 08:38:56 +02:00
//Command *command= this->unit->getCurrCommand();
2011-09-09 19:49:10 +02:00
// Are we moving or attacking
2011-09-25 06:07:59 +02:00
if ( command ! = NULL & & command - > getCommandType ( ) ! = NULL & &
2011-07-05 06:37:35 +02:00
( command - > getCommandType ( ) - > getClass ( ) = = ccMove | |
command - > getCommandType ( ) - > getClass ( ) = = ccAttack ) & &
command - > getUnitCommandGroupId ( ) > 0 ) {
int curCommandGroupId = command - > getUnitCommandGroupId ( ) ;
2011-09-09 19:49:10 +02:00
//Command *commandPeer = j.unit->getCurrrentCommandThreadSafe();
2011-07-06 08:38:56 +02:00
//Command *commandPeer = j.unit->getCurrCommand();
2011-09-09 19:49:10 +02:00
// is comparer a valid command
2011-09-25 06:07:59 +02:00
if ( commandPeer = = NULL | | commandPeer - > getCommandType ( ) = = NULL ) {
2011-09-09 19:49:10 +02:00
result = true ;
2011-07-05 06:37:35 +02:00
}
2011-09-09 19:49:10 +02:00
// is comparer command the same type?
2011-07-05 06:37:35 +02:00
else if ( commandPeer - > getCommandType ( ) - > getClass ( ) ! =
command - > getCommandType ( ) - > getClass ( ) ) {
2011-09-09 19:49:10 +02:00
result = true ;
2011-07-05 06:37:35 +02:00
}
2011-09-09 19:49:10 +02:00
// is comparer command groupid invalid?
2011-07-05 06:37:35 +02:00
else if ( commandPeer - > getUnitCommandGroupId ( ) < 0 ) {
2011-09-09 19:49:10 +02:00
result = true ;
2011-07-05 06:37:35 +02:00
}
2011-09-09 19:49:10 +02:00
// If comparer command group id is less than current group id
else if ( curCommandGroupId ! = commandPeer - > getUnitCommandGroupId ( ) ) {
result = curCommandGroupId < commandPeer - > getUnitCommandGroupId ( ) ;
2011-07-05 06:37:35 +02:00
}
else {
2013-10-03 02:17:51 +02:00
float unitDist = l - > getCenteredPos ( ) . dist ( command - > getPos ( ) ) ;
float unitDistPeer = r - > getCenteredPos ( ) . dist ( commandPeer - > getPos ( ) ) ;
2011-07-05 06:37:35 +02:00
2011-09-09 19:49:10 +02:00
// Closest unit in commandgroup
result = ( unitDist < unitDistPeer ) ;
}
}
2011-09-22 22:42:06 +02:00
else if ( command = = NULL & & commandPeer ! = NULL ) {
2011-09-09 19:49:10 +02:00
result = false ;
}
// else if(command == NULL && j.unit->getCurrrentCommandThreadSafe() == NULL) {
// return this->unit->getId() < j.unit->getId();
// }
else {
//Command *commandPeer = j.unit->getCurrrentCommandThreadSafe();
2012-10-06 09:06:40 +02:00
//if( commandPeer != NULL && commandPeer->getCommandType() != NULL &&
// (commandPeer->getCommandType()->getClass() != ccMove &&
// commandPeer->getCommandType()->getClass() != ccAttack)) {
2011-09-22 22:42:06 +02:00
result = ( l - > getId ( ) < r - > getId ( ) ) ;
2012-10-06 09:06:40 +02:00
//}
//else {
// result = (l->getId() < r->getId());
//}
2011-07-05 06:37:35 +02:00
}
2011-09-09 19:49:10 +02:00
//printf("Sorting, unit [%d - %s] cmd [%s] | unit2 [%d - %s] cmd [%s] result = %d\n",this->unit->getId(),this->unit->getFullName().c_str(),(this->unit->getCurrCommand() == NULL ? "NULL" : this->unit->getCurrCommand()->toString().c_str()),j.unit->getId(),j.unit->getFullName().c_str(),(j.unit->getCurrCommand() == NULL ? "NULL" : j.unit->getCurrCommand()->toString().c_str()),result);
return result ;
2011-07-05 06:37:35 +02:00
}
2011-09-22 22:42:06 +02:00
void Faction : : sortUnitsByCommandGroups ( ) {
2011-09-25 06:07:59 +02:00
MutexSafeWrapper safeMutex ( unitsMutex , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
//printf("====== sortUnitsByCommandGroups for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size());
//for(unsigned int i = 0; i < units.size(); ++i) {
// printf("%d / %d [%p] <>",i,units.size(),&units[i]);
// // printf("i = %d [%p]\n",i,&units[i]);
// if(Unit::isUnitDeleted(units[i]) == true) {
// printf("i = %d [%p]\n",i,&units[i]);
2012-04-14 23:21:09 +02:00
// throw megaglest_runtime_error("unit already deleted!");
2011-09-25 06:07:59 +02:00
// }
//}
//printf("\nSorting\n");
//std::sort(units.begin(),units.end(),CommandGroupUnitSorter());
//printf("====== Done sorting for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size());
2013-11-19 07:14:06 +01:00
//unsigned int originalUnitSize = (unsigned int)units.size();
2011-09-28 08:57:42 +02:00
2011-09-25 06:07:59 +02:00
std : : vector < int > unitIds ;
for ( unsigned int i = 0 ; i < units . size ( ) ; + + i ) {
int unitId = units [ i ] - > getId ( ) ;
if ( this - > findUnit ( unitId ) = = NULL ) {
2013-06-13 10:55:48 +02:00
printf ( " #1 Error unitId not found for id = %d [%s] factionIndex = %d \n " , unitId , units [ i ] - > getType ( ) - > getName ( false ) . c_str ( ) , this - > getIndex ( ) ) ;
2011-09-25 06:07:59 +02:00
for ( unsigned int j = 0 ; j < units . size ( ) ; + + j ) {
2013-06-13 10:55:48 +02:00
printf ( " %u / %d id = %d [%s] \n " , j , ( int ) units . size ( ) , units [ j ] - > getId ( ) , units [ j ] - > getType ( ) - > getName ( false ) . c_str ( ) ) ;
2011-09-25 06:07:59 +02:00
}
}
unitIds . push_back ( unitId ) ;
}
CommandGroupUnitSorterId sorter ;
sorter . faction = this ;
std : : stable_sort ( unitIds . begin ( ) , unitIds . end ( ) , sorter ) ;
units . clear ( ) ;
for ( unsigned int i = 0 ; i < unitIds . size ( ) ; + + i ) {
int unitId = unitIds [ i ] ;
if ( this - > findUnit ( unitId ) = = NULL ) {
printf ( " #2 Error unitId not found for id = %d factionIndex = %d \n " , unitId , this - > getIndex ( ) ) ;
for ( unsigned int j = 0 ; j < units . size ( ) ; + + j ) {
2013-06-13 10:55:48 +02:00
printf ( " %u / %d id = %d [%s] \n " , j , ( int ) units . size ( ) , units [ j ] - > getId ( ) , units [ j ] - > getType ( ) - > getName ( false ) . c_str ( ) ) ;
2011-09-25 06:07:59 +02:00
}
}
units . push_back ( this - > findUnit ( unitId ) ) ;
}
2013-11-19 07:56:09 +01:00
//assert(originalUnitSize == units.size());
2011-09-22 22:42:06 +02:00
}
2011-03-18 04:53:06 +01:00
// =====================================================
// class FactionThread
// =====================================================
FactionThread : : FactionThread ( Faction * faction ) : BaseThread ( ) {
2013-12-25 07:27:44 +01:00
this - > triggerIdMutex = new Mutex ( CODE_AT_LINE ) ;
2011-03-18 04:53:06 +01:00
this - > faction = faction ;
2013-01-10 22:16:28 +01:00
this - > masterController = NULL ;
2013-05-21 22:28:42 +02:00
uniqueID = " FactionThread " ;
2011-03-18 04:53:06 +01:00
}
2011-12-02 17:07:59 +01:00
FactionThread : : ~ FactionThread ( ) {
2013-02-04 09:30:43 +01:00
this - > faction = NULL ;
this - > masterController = NULL ;
delete this - > triggerIdMutex ;
this - > triggerIdMutex = NULL ;
2011-12-02 17:07:59 +01:00
}
2011-03-18 04:53:06 +01:00
void FactionThread : : setQuitStatus ( bool value ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] Line: %d value = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , value ) ;
2011-03-18 04:53:06 +01:00
BaseThread : : setQuitStatus ( value ) ;
if ( value = = true ) {
2011-09-22 22:42:06 +02:00
signalPathfinder ( - 1 ) ;
2011-03-18 04:53:06 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] Line: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
}
2011-09-22 22:42:06 +02:00
void FactionThread : : signalPathfinder ( int frameIndex ) {
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
2011-03-18 04:53:06 +01:00
this - > frameIndex . first = frameIndex ;
this - > frameIndex . second = false ;
2011-07-05 06:37:35 +02:00
2011-03-18 04:53:06 +01:00
safeMutex . ReleaseLock ( ) ;
}
semTaskSignalled . signal ( ) ;
}
void FactionThread : : setTaskCompleted ( int frameIndex ) {
if ( frameIndex > = 0 ) {
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
2011-03-18 04:53:06 +01:00
if ( this - > frameIndex . first = = frameIndex ) {
this - > frameIndex . second = true ;
}
safeMutex . ReleaseLock ( ) ;
}
}
bool FactionThread : : canShutdown ( bool deleteSelfIfShutdownDelayed ) {
bool ret = ( getExecutingTask ( ) = = false ) ;
if ( ret = = false & & deleteSelfIfShutdownDelayed = = true ) {
setDeleteSelfOnExecutionDone ( deleteSelfIfShutdownDelayed ) ;
2013-06-04 02:31:41 +02:00
deleteSelfIfRequired ( ) ;
2011-03-18 04:53:06 +01:00
signalQuit ( ) ;
}
return ret ;
}
bool FactionThread : : isSignalPathfinderCompleted ( int frameIndex ) {
if ( getRunningStatus ( ) = = false ) {
return true ;
}
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
2011-03-18 04:53:06 +01:00
//bool result = (event != NULL ? event->eventCompleted : true);
2013-06-15 03:43:44 +02:00
bool result = ( this - > frameIndex . first = = frameIndex & & this - > frameIndex . second = = true ) ;
2011-03-18 04:53:06 +01:00
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second);
safeMutex . ReleaseLock ( ) ;
return result ;
}
void FactionThread : : execute ( ) {
2013-11-06 03:14:49 +01:00
string codeLocation = " 1 " ;
2011-03-18 04:53:06 +01:00
RunningStatusSafeWrapper runningStatus ( this ) ;
try {
//setRunningStatus(true);
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] ****************** STARTING worker thread this = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , this ) ;
2012-05-10 01:56:14 +02:00
bool minorDebugPerformance = false ;
Chrono chrono ;
2013-11-06 03:14:49 +01:00
codeLocation = " 2 " ;
2011-09-01 03:11:23 +02:00
//unsigned int idx = 0;
2011-03-18 04:53:06 +01:00
for ( ; this - > faction ! = NULL ; ) {
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
break ;
}
semTaskSignalled . waitTillSignalled ( ) ;
2013-11-06 03:14:49 +01:00
codeLocation = " 3 " ;
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
static string masterSlaveOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MasterSlaveThreadControllerSafeWrapper safeMasterController ( masterController , 20000 , masterSlaveOwnerId ) ;
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2011-03-18 04:53:06 +01:00
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
break ;
}
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
2013-02-04 09:30:43 +01:00
bool executeTask = ( this - > frameIndex . first > = 0 ) ;
2013-06-15 03:43:44 +02:00
int currentTriggeredFrameIndex = this - > frameIndex . first ;
2011-03-18 04:53:06 +01:00
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask);
safeMutex . ReleaseLock ( ) ;
2013-11-06 03:14:49 +01:00
codeLocation = " 5 " ;
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2011-03-18 04:53:06 +01:00
if ( executeTask = = true ) {
2013-11-06 03:14:49 +01:00
codeLocation = " 6 " ;
2011-03-18 04:53:06 +01:00
ExecutingTaskSafeWrapper safeExecutingTaskMutex ( this ) ;
2013-02-04 09:30:43 +01:00
if ( this - > faction = = NULL ) {
throw megaglest_runtime_error ( " this->faction == NULL " ) ;
}
World * world = this - > faction - > getWorld ( ) ;
if ( world = = NULL ) {
throw megaglest_runtime_error ( " world == NULL " ) ;
}
2011-03-18 04:53:06 +01:00
2013-11-06 03:14:49 +01:00
codeLocation = " 7 " ;
2011-12-02 17:07:59 +01:00
//Config &config= Config::getInstance();
2011-10-26 02:30:58 +02:00
//bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true");
2017-10-10 04:09:36 +02:00
//bool sortedUnitsAllowed = false;
//if(sortedUnitsAllowed == true) {
2018-04-11 01:52:25 +02:00
/// TODO: Why does this cause an OOS?
//this->faction->sortUnitsByCommandGroups();
2017-10-10 04:09:36 +02:00
//}
2011-09-25 06:07:59 +02:00
2013-11-06 03:14:49 +01:00
codeLocation = " 8 " ;
2013-02-04 09:30:43 +01:00
static string mutexOwnerId2 = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( faction - > getUnitMutex ( ) , mutexOwnerId2 ) ;
2012-05-10 01:56:14 +02:00
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
if ( minorDebugPerformance ) chrono . start ( ) ;
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2013-11-06 03:14:49 +01:00
codeLocation = " 9 " ;
2013-02-04 09:30:43 +01:00
int unitCount = this - > faction - > getUnitCount ( ) ;
2011-09-22 22:42:06 +02:00
for ( int j = 0 ; j < unitCount ; + + j ) {
2013-11-06 03:14:49 +01:00
codeLocation = " 10 " ;
2013-02-04 09:30:43 +01:00
Unit * unit = this - > faction - > getUnit ( j ) ;
2011-09-22 22:42:06 +02:00
if ( unit = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " unit == NULL " ) ;
2011-07-05 06:37:35 +02:00
}
2011-09-22 22:42:06 +02:00
2013-11-06 03:14:49 +01:00
codeLocation = " 11 " ;
2012-05-10 01:56:14 +02:00
int64 elapsed1 = 0 ;
if ( minorDebugPerformance ) elapsed1 = chrono . getMillis ( ) ;
2011-09-22 22:42:06 +02:00
bool update = unit - > needToUpdate ( ) ;
2012-05-10 01:56:14 +02:00
2013-11-06 03:14:49 +01:00
codeLocation = " 12 " ;
2013-06-13 03:37:15 +02:00
if ( minorDebugPerformance & & ( chrono . getMillis ( ) - elapsed1 ) > = 1 ) printf ( " Faction [%d - %s] #1-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs \n " , faction - > getStartLocationIndex ( ) , faction - > getType ( ) - > getName ( false ) . c_str ( ) , currentTriggeredFrameIndex , faction - > getUnitPathfindingListCount ( ) , j , unitCount , ( long long int ) chrono . getMillis ( ) - elapsed1 ) ;
2012-05-10 01:56:14 +02:00
2011-09-22 22:42:06 +02:00
//update = true;
2013-11-06 03:14:49 +01:00
if ( update = = true )
{
codeLocation = " 13 " ;
2013-05-23 02:33:30 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2013-06-03 16:50:50 +02:00
int64 updateProgressValue = unit - > getUpdateProgress ( ) ;
int64 speed = unit - > getCurrSkill ( ) - > getTotalSpeed ( unit - > getTotalUpgrade ( ) ) ;
int64 df = unit - > getDiagonalFactor ( ) ;
int64 hf = unit - > getHeightFactor ( ) ;
2013-05-25 02:02:49 +02:00
bool changedActiveCommand = unit - > isChangedActiveCommand ( ) ;
2013-05-23 02:33:30 +02:00
char szBuf [ 8096 ] = " " ;
2013-11-17 10:03:57 +01:00
snprintf ( szBuf , 8096 , " unit->needToUpdate() returned: %d updateProgressValue: %lld speed: %lld changedActiveCommand: %d df: %lld hf: %lld " , update , ( long long int ) updateProgressValue , ( long long int ) speed , changedActiveCommand , ( long long int ) df , ( long long int ) hf ) ;
2013-05-23 02:33:30 +02:00
unit - > logSynchDataThreaded ( __FILE__ , __LINE__ , szBuf ) ;
}
2012-05-10 01:56:14 +02:00
int64 elapsed2 = 0 ;
if ( minorDebugPerformance ) elapsed2 = chrono . getMillis ( ) ;
2013-02-04 09:30:43 +01:00
if ( world - > getUnitUpdater ( ) = = NULL ) {
throw megaglest_runtime_error ( " world->getUnitUpdater() = = NULL " ) ;
}
2013-11-14 14:22:55 +01:00
2013-02-04 09:30:43 +01:00
world - > getUnitUpdater ( ) - > updateUnitCommand ( unit , currentTriggeredFrameIndex ) ;
2013-11-06 03:14:49 +01:00
codeLocation = " 15 " ;
2013-06-13 03:37:15 +02:00
if ( minorDebugPerformance & & ( chrono . getMillis ( ) - elapsed2 ) > = 1 ) printf ( " Faction [%d - %s] #2-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs \n " , faction - > getStartLocationIndex ( ) , faction - > getType ( ) - > getName ( false ) . c_str ( ) , currentTriggeredFrameIndex , faction - > getUnitPathfindingListCount ( ) , j , unitCount , ( long long int ) chrono . getMillis ( ) - elapsed2 ) ;
2011-03-18 04:53:06 +01:00
}
2013-06-02 07:57:51 +02:00
else {
2013-11-06 03:14:49 +01:00
codeLocation = " 16 " ;
2013-06-02 07:57:51 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2013-06-03 16:50:50 +02:00
int64 updateProgressValue = unit - > getUpdateProgress ( ) ;
int64 speed = unit - > getCurrSkill ( ) - > getTotalSpeed ( unit - > getTotalUpgrade ( ) ) ;
int64 df = unit - > getDiagonalFactor ( ) ;
int64 hf = unit - > getHeightFactor ( ) ;
2013-06-02 07:57:51 +02:00
bool changedActiveCommand = unit - > isChangedActiveCommand ( ) ;
char szBuf [ 8096 ] = " " ;
2013-11-17 10:03:57 +01:00
snprintf ( szBuf , 8096 , " unit->needToUpdate() returned: %d updateProgressValue: %lld speed: %lld changedActiveCommand: %d df: %lld hf: %lld " , update , ( long long int ) updateProgressValue , ( long long int ) speed , changedActiveCommand , ( long long int ) df , ( long long int ) hf ) ;
2013-06-02 07:57:51 +02:00
unit - > logSynchDataThreaded ( __FILE__ , __LINE__ , szBuf ) ;
}
}
2011-03-18 04:53:06 +01:00
}
2012-05-10 01:56:14 +02:00
2013-11-06 03:14:49 +01:00
codeLocation = " 17 " ;
2013-06-13 03:37:15 +02:00
if ( minorDebugPerformance & & chrono . getMillis ( ) > = 1 ) printf ( " Faction [%d - %s] threaded updates on frame: %d for [%d] units took [%lld] msecs \n " , faction - > getStartLocationIndex ( ) , faction - > getType ( ) - > getName ( false ) . c_str ( ) , currentTriggeredFrameIndex , faction - > getUnitPathfindingListCount ( ) , ( long long int ) chrono . getMillis ( ) ) ;
2012-05-10 01:56:14 +02:00
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2011-09-25 06:07:59 +02:00
safeMutex . ReleaseLock ( ) ;
2011-03-18 04:53:06 +01:00
2013-11-06 03:14:49 +01:00
codeLocation = " 18 " ;
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2013-02-04 09:30:43 +01:00
setTaskCompleted ( currentTriggeredFrameIndex ) ;
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2011-03-18 04:53:06 +01:00
}
2013-01-10 22:16:28 +01:00
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2013-11-06 03:14:49 +01:00
codeLocation = " 19 " ;
2011-03-18 04:53:06 +01:00
if ( getQuitStatus ( ) = = true ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
break ;
}
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] ****************** ENDING worker thread this = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , this ) ;
}
catch ( const exception & ex ) {
//setRunningStatus(false);
2013-11-06 03:14:49 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Loc [%s] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , codeLocation . c_str ( ) , ex . what ( ) ) ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( ex . what ( ) ) ;
2011-03-18 04:53:06 +01:00
}
2013-02-04 09:30:43 +01:00
catch ( . . . ) {
char szBuf [ 8096 ] = " " ;
2013-11-06 03:14:49 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] UNKNOWN error Loc [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , codeLocation . c_str ( ) ) ;
2013-02-04 09:30:43 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , szBuf ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] Line: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-03-18 04:53:06 +01:00
}
2010-03-19 19:58:46 +01:00
// =====================================================
// class Faction
// =====================================================
2010-08-04 18:56:24 +02:00
Faction : : Faction ( ) {
2012-10-06 09:06:40 +02:00
init ( ) ;
}
void Faction : : init ( ) {
2013-12-25 07:27:44 +01:00
unitsMutex = new Mutex ( CODE_AT_LINE ) ;
2010-08-04 18:56:24 +02:00
texture = NULL ;
2010-12-01 00:32:39 +01:00
//lastResourceTargettListPurge = 0;
2010-11-09 10:06:52 +01:00
cachingDisabled = false ;
2011-02-15 04:32:14 +01:00
factionDisconnectHandled = false ;
2011-03-18 04:53:06 +01:00
workerThread = NULL ;
2011-09-01 03:11:23 +02:00
world = NULL ;
scriptManager = NULL ;
factionType = NULL ;
index = 0 ;
teamIndex = 0 ;
startLocationIndex = 0 ;
thisFaction = false ;
2011-12-02 17:07:59 +01:00
currentSwitchTeamVoteFactionIndex = - 1 ;
2014-01-28 04:03:52 +01:00
allowSharedTeamUnits = false ;
2012-03-13 00:08:22 +01:00
loadWorldNode = NULL ;
techTree = NULL ;
2012-03-30 07:53:33 +02:00
2012-10-06 04:10:23 +02:00
control = ctClosed ;
2012-03-30 07:53:33 +02:00
overridePersonalityType = fpt_EndCount ;
2013-06-15 03:43:44 +02:00
upgradeManager = UpgradeManager ( ) ;
2010-08-04 18:56:24 +02:00
}
Faction : : ~ Faction ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-04 18:56:24 +02:00
2011-09-01 03:11:23 +02:00
//Renderer &renderer= Renderer::getInstance();
2010-08-04 18:56:24 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-04 18:56:24 +02:00
//renderer.endTexture(rsGame,texture);
//texture->end();
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-04 18:56:24 +02:00
2011-03-18 04:53:06 +01:00
if ( workerThread ! = NULL ) {
workerThread - > signalQuit ( ) ;
if ( workerThread - > shutdownAndWait ( ) = = true ) {
delete workerThread ;
}
workerThread = NULL ;
}
2011-09-28 08:57:42 +02:00
MutexSafeWrapper safeMutex ( unitsMutex , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
deleteValues ( units . begin ( ) , units . end ( ) ) ;
units . clear ( ) ;
safeMutex . ReleaseLock ( ) ;
2010-08-04 18:56:24 +02:00
//delete texture;
texture = NULL ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-09-25 06:07:59 +02:00
delete unitsMutex ;
unitsMutex = NULL ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2011-09-28 08:57:42 +02:00
void Faction : : end ( ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( workerThread ! = NULL ) {
workerThread - > signalQuit ( ) ;
if ( workerThread - > shutdownAndWait ( ) = = true ) {
delete workerThread ;
}
workerThread = NULL ;
}
MutexSafeWrapper safeMutex ( unitsMutex , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
deleteValues ( units . begin ( ) , units . end ( ) ) ;
units . clear ( ) ;
safeMutex . ReleaseLock ( ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2013-11-11 09:28:15 +01:00
void Faction : : notifyUnitAliveStatusChange ( const Unit * unit ) {
if ( unit ! = NULL ) {
if ( unit - > isAlive ( ) = = true ) {
2013-11-13 20:00:33 +01:00
aliveUnitListCache [ unit - > getId ( ) ] = unit ;
2013-11-11 09:28:15 +01:00
if ( unit - > getType ( ) - > isMobile ( ) = = true ) {
2013-11-13 20:00:33 +01:00
mobileUnitListCache [ unit - > getId ( ) ] = unit ;
2013-11-11 09:28:15 +01:00
}
}
else {
2013-11-13 20:00:33 +01:00
aliveUnitListCache . erase ( unit - > getId ( ) ) ;
mobileUnitListCache . erase ( unit - > getId ( ) ) ;
beingBuiltUnitListCache . erase ( unit - > getId ( ) ) ;
2013-11-11 09:28:15 +01:00
}
}
}
void Faction : : notifyUnitTypeChange ( const Unit * unit , const UnitType * newType ) {
if ( unit ! = NULL ) {
if ( unit - > getType ( ) - > isMobile ( ) = = true ) {
2013-11-13 20:00:33 +01:00
mobileUnitListCache . erase ( unit - > getId ( ) ) ;
2013-11-11 09:28:15 +01:00
}
if ( newType ! = NULL & & newType - > isMobile ( ) = = true ) {
2013-11-13 20:00:33 +01:00
mobileUnitListCache [ unit - > getId ( ) ] = unit ;
2013-11-11 09:28:15 +01:00
}
}
}
void Faction : : notifyUnitSkillTypeChange ( const Unit * unit , const SkillType * newType ) {
if ( unit ! = NULL ) {
if ( unit - > isBeingBuilt ( ) = = true ) {
2013-11-13 20:00:33 +01:00
beingBuiltUnitListCache . erase ( unit - > getId ( ) ) ;
2013-11-11 09:28:15 +01:00
}
if ( newType ! = NULL & & newType - > getClass ( ) = = scBeBuilt ) {
2013-11-13 20:00:33 +01:00
beingBuiltUnitListCache [ unit - > getId ( ) ] = unit ;
2013-11-11 09:28:15 +01:00
}
}
}
bool Faction : : hasAliveUnits ( bool filterMobileUnits , bool filterBuiltUnits ) const {
bool result = false ;
2013-11-13 20:00:33 +01:00
if ( aliveUnitListCache . empty ( ) = = false ) {
2013-11-11 09:28:15 +01:00
if ( filterMobileUnits = = true ) {
2013-11-13 20:00:33 +01:00
result = ( mobileUnitListCache . empty ( ) = = false ) ;
2013-11-11 09:28:15 +01:00
}
else {
result = true ;
}
if ( result = = true & & filterBuiltUnits = = true ) {
2013-11-13 20:00:33 +01:00
result = ( beingBuiltUnitListCache . empty ( ) = = true ) ;
2013-11-11 09:28:15 +01:00
}
}
return result ;
}
2012-03-30 07:53:33 +02:00
FactionPersonalityType Faction : : getPersonalityType ( ) const {
if ( overridePersonalityType ! = fpt_EndCount ) {
return overridePersonalityType ;
}
return factionType - > getPersonalityType ( ) ;
}
2012-03-31 07:54:24 +02:00
int Faction : : getAIBehaviorStaticOverideValue ( AIBehaviorStaticValueCategory type ) const {
return factionType - > getAIBehaviorStaticOverideValue ( type ) ;
}
2012-03-31 21:50:45 +02:00
void Faction : : addUnitToMovingList ( int unitId ) {
unitsMovingList [ unitId ] = getWorld ( ) - > getFrameCount ( ) ;
}
void Faction : : removeUnitFromMovingList ( int unitId ) {
unitsMovingList . erase ( unitId ) ;
}
2017-10-10 05:21:14 +02:00
//int Faction::getUnitMovingListCount() {
// return (int)unitsMovingList.size();
//}
2012-03-31 21:50:45 +02:00
void Faction : : addUnitToPathfindingList ( int unitId ) {
2012-05-10 01:56:14 +02:00
//printf("ADD (1) Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size());
2012-03-31 21:50:45 +02:00
unitsPathfindingList [ unitId ] = getWorld ( ) - > getFrameCount ( ) ;
2012-05-10 01:56:14 +02:00
//printf("ADD (2) Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size());
2012-03-31 21:50:45 +02:00
}
2017-10-10 05:21:14 +02:00
//void Faction::removeUnitFromPathfindingList(int unitId) {
// unitsPathfindingList.erase(unitId);
//}
2012-03-31 21:50:45 +02:00
int Faction : : getUnitPathfindingListCount ( ) {
2012-05-10 01:56:14 +02:00
//printf("GET Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size());
2013-11-02 12:04:52 +01:00
return ( int ) unitsPathfindingList . size ( ) ;
2012-03-31 21:50:45 +02:00
}
void Faction : : clearUnitsPathfinding ( ) {
2012-05-10 01:56:14 +02:00
//printf("CLEAR Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size());
2013-01-03 18:30:59 +01:00
if ( unitsPathfindingList . empty ( ) = = false ) {
unitsPathfindingList . clear ( ) ;
}
2012-03-31 21:50:45 +02:00
}
bool Faction : : canUnitsPathfind ( ) {
bool result = true ;
if ( control = = ctCpuEasy | | control = = ctCpu | |
control = = ctCpuUltra | | control = = ctCpuMega ) {
//printf("AI player for faction index: %d (%s) current pathfinding: %d\n",index,factionType->getName().c_str(),getUnitPathfindingListCount());
const int MAX_UNITS_PATHFINDING_PER_FRAME = 10 ;
result = ( getUnitPathfindingListCount ( ) < = MAX_UNITS_PATHFINDING_PER_FRAME ) ;
if ( result = = false ) {
//printf("WARNING limited AI player for faction index: %d (%s) current pathfinding: %d\n",index,factionType->getName().c_str(),getUnitPathfindingListCount());
}
}
return result ;
}
2012-03-31 07:54:24 +02:00
2014-11-12 15:14:52 +01:00
void Faction : : setLockedUnitForFaction ( const UnitType * ut , bool lock ) {
if ( lock ) {
2014-11-12 21:31:01 +01:00
lockedUnits . insert ( ut ) ;
2014-11-12 15:14:52 +01:00
} else {
std : : set < const UnitType * > : : iterator it ;
2014-11-12 21:31:01 +01:00
it = lockedUnits . find ( ut ) ;
if ( it ! = lockedUnits . end ( ) ) {
lockedUnits . erase ( it ) ;
2014-11-12 15:14:52 +01:00
}
}
}
2011-09-22 22:42:06 +02:00
void Faction : : signalWorkerThread ( int frameIndex ) {
2011-03-18 04:53:06 +01:00
if ( workerThread ! = NULL ) {
2011-09-22 22:42:06 +02:00
workerThread - > signalPathfinder ( frameIndex ) ;
2011-03-18 04:53:06 +01:00
}
}
bool Faction : : isWorkerThreadSignalCompleted ( int frameIndex ) {
if ( workerThread ! = NULL ) {
return workerThread - > isSignalPathfinderCompleted ( frameIndex ) ;
}
return true ;
}
2010-03-19 19:58:46 +01:00
void Faction : : init (
2010-10-28 02:51:25 +02:00
FactionType * factionType , ControlType control , TechTree * techTree , Game * game ,
2012-03-13 00:08:22 +01:00
int factionIndex , int teamIndex , int startLocationIndex , bool thisFaction , bool giveResources ,
const XmlNode * loadWorldNode )
2010-03-19 19:58:46 +01:00
{
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-05-03 08:25:54 +02:00
2012-03-13 00:08:22 +01:00
this - > techTree = techTree ;
this - > loadWorldNode = loadWorldNode ;
2010-03-19 19:58:46 +01:00
this - > control = control ;
this - > factionType = factionType ;
this - > startLocationIndex = startLocationIndex ;
this - > index = factionIndex ;
this - > teamIndex = teamIndex ;
this - > thisFaction = thisFaction ;
this - > world = game - > getWorld ( ) ;
this - > scriptManager = game - > getScriptManager ( ) ;
2013-05-21 02:38:35 +02:00
//cachingDisabled = (Config::getInstance().getBool("DisableCaching","false") == true);
cachingDisabled = false ;
2010-03-19 19:58:46 +01:00
resources . resize ( techTree - > getResourceTypeCount ( ) ) ;
store . resize ( techTree - > getResourceTypeCount ( ) ) ;
2012-03-13 00:08:22 +01:00
if ( loadWorldNode = = NULL ) {
2014-01-28 03:55:08 +01:00
for ( int index = 0 ; index < techTree - > getResourceTypeCount ( ) ; + + index ) {
const ResourceType * rt = techTree - > getResourceType ( index ) ;
int resourceAmount = giveResources ? factionType - > getStartingResourceAmount ( rt ) : 0 ;
resources [ index ] . init ( rt , resourceAmount ) ;
store [ index ] . init ( rt , 0 ) ;
this - > world - > initTeamResource ( rt , this - > teamIndex , 0 ) ;
2012-03-13 00:08:22 +01:00
}
2010-03-19 19:58:46 +01:00
}
2015-01-13 18:51:32 +01:00
//initialize cache
for ( int index = 0 ; index < techTree - > getResourceTypeCount ( ) ; + + index ) {
const ResourceType * rt = techTree - > getResourceType ( index ) ;
this - > updateUnitTypeWithResourceCostCache ( rt ) ;
}
2010-03-19 19:58:46 +01:00
texture = Renderer : : getInstance ( ) . newTexture2D ( rsGame ) ;
2010-12-09 21:41:11 +01:00
string data_path = getGameReadWritePath ( GameConstants : : path_data_CacheLookupKey ) ;
2011-09-27 07:29:57 +02:00
if ( texture ) {
2011-12-15 00:01:13 +01:00
string playerTexture = getGameCustomCoreDataPath ( data_path , " data/core/faction_textures/faction " + intToStr ( startLocationIndex ) + " .tga " ) ;
texture - > load ( playerTexture ) ;
2011-09-27 07:29:57 +02:00
}
2010-05-03 08:25:54 +02:00
2012-03-13 00:08:22 +01:00
if ( loadWorldNode ! = NULL ) {
2012-03-13 16:21:25 +01:00
loadGame ( loadWorldNode , this - > index , game - > getGameSettings ( ) , game - > getWorld ( ) ) ;
2012-03-13 00:08:22 +01:00
}
2013-05-21 02:38:35 +02:00
if ( game - > getGameSettings ( ) - > getPathFinderType ( ) = = pfBasic ) {
2011-03-18 04:53:06 +01:00
if ( workerThread ! = NULL ) {
workerThread - > signalQuit ( ) ;
if ( workerThread - > shutdownAndWait ( ) = = true ) {
delete workerThread ;
}
workerThread = NULL ;
}
2013-01-23 15:51:28 +01:00
static string mutexOwnerId = string ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-03-18 04:53:06 +01:00
this - > workerThread = new FactionThread ( this ) ;
2013-01-23 15:51:28 +01:00
this - > workerThread - > setUniqueID ( mutexOwnerId ) ;
2011-03-18 04:53:06 +01:00
this - > workerThread - > start ( ) ;
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-19 19:58:46 +01:00
}
// ================== get ==================
2014-01-28 03:55:08 +01:00
bool Faction : : hasUnitTypeWithResourceCostInCache ( const ResourceType * rt ) const {
std : : string resourceTypeName = rt - > getName ( false ) ;
std : : map < std : : string , bool > : : const_iterator iterFind = resourceTypeCostCache . find ( resourceTypeName ) ;
if ( iterFind ! = resourceTypeCostCache . end ( ) ) {
return iterFind - > second ;
}
return false ;
}
void Faction : : updateUnitTypeWithResourceCostCache ( const ResourceType * rt ) {
std : : string resourceTypeName = rt - > getName ( false ) ;
if ( resourceTypeCostCache . find ( resourceTypeName ) = = resourceTypeCostCache . end ( ) ) {
resourceTypeCostCache [ resourceTypeName ] = hasUnitTypeWithResouceCost ( rt ) ;
}
}
bool Faction : : hasUnitTypeWithResouceCost ( const ResourceType * rt ) {
for ( int factionUnitTypeIndex = 0 ;
factionUnitTypeIndex < getType ( ) - > getUnitTypeCount ( ) ;
+ + factionUnitTypeIndex ) {
const UnitType * ut = getType ( ) - > getUnitType ( factionUnitTypeIndex ) ;
if ( ut - > getCost ( rt ) ! = NULL ) {
return true ;
2010-03-19 19:58:46 +01:00
}
}
2014-01-28 03:55:08 +01:00
return false ;
}
const Resource * Faction : : getResource ( const ResourceType * rt , bool localFactionOnly ) const {
if ( localFactionOnly = = false & &
world ! = NULL & &
world - > getGame ( ) ! = NULL ) {
Game * game = world - > getGame ( ) ;
if ( game - > isFlagType1BitEnabled ( ft1_allow_shared_team_resources ) = = true ) {
return world - > getResourceForTeam ( rt , this - > getTeam ( ) ) ;
}
}
for ( int index = 0 ; index < ( int ) resources . size ( ) ; + + index ) {
if ( rt = = resources [ index ] . getType ( ) ) {
return & resources [ index ] ;
}
}
2012-03-13 00:08:22 +01:00
printf ( " ERROR cannot find resource type [%s] in list: \n " , ( rt ! = NULL ? rt - > getName ( ) . c_str ( ) : " null " ) ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
2012-03-13 00:08:22 +01:00
printf ( " Index %d [%s] " , i , resources [ i ] . getType ( ) - > getName ( ) . c_str ( ) ) ;
}
2010-03-19 19:58:46 +01:00
assert ( false ) ;
return NULL ;
}
2014-01-28 03:55:08 +01:00
int Faction : : getStoreAmount ( const ResourceType * rt , bool localFactionOnly ) const {
if ( localFactionOnly = = false & &
world ! = NULL & &
world - > getGame ( ) ! = NULL ) {
Game * game = world - > getGame ( ) ;
if ( game - > isFlagType1BitEnabled ( ft1_allow_shared_team_resources ) = = true ) {
return world - > getStoreAmountForTeam ( rt , this - > getTeam ( ) ) ;
}
}
for ( int index = 0 ; index < ( int ) store . size ( ) ; + + index ) {
if ( rt = = store [ index ] . getType ( ) ) {
return store [ index ] . getAmount ( ) ;
2010-03-19 19:58:46 +01:00
}
}
2012-03-13 00:08:22 +01:00
printf ( " ERROR cannot find store type [%s] in list: \n " , ( rt ! = NULL ? rt - > getName ( ) . c_str ( ) : " null " ) ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) store . size ( ) ; + + i ) {
2012-03-13 00:08:22 +01:00
printf ( " Index %d [%s] " , i , store [ i ] . getType ( ) - > getName ( ) . c_str ( ) ) ;
}
2010-03-19 19:58:46 +01:00
assert ( false ) ;
return 0 ;
}
2010-09-14 21:10:37 +02:00
bool Faction : : getCpuControl ( bool enableServerControlledAI , bool isNetworkGame , NetworkRole role ) const {
bool result = false ;
if ( enableServerControlledAI = = false | | isNetworkGame = = false ) {
result = ( control = = ctCpuEasy | | control = = ctCpu | | control = = ctCpuUltra | | control = = ctCpuMega ) ;
}
else {
if ( isNetworkGame = = true ) {
if ( role = = nrServer ) {
result = ( control = = ctCpuEasy | | control = = ctCpu | | control = = ctCpuUltra | | control = = ctCpuMega ) ;
}
else {
result = ( control = = ctNetworkCpuEasy | | control = = ctNetworkCpu | | control = = ctNetworkCpuUltra | | control = = ctNetworkCpuMega ) ;
}
}
}
return result ;
}
bool Faction : : getCpuControl ( ) const {
return control = = ctCpuEasy | | control = = ctCpu | | control = = ctCpuUltra | | control = = ctCpuMega | |
control = = ctNetworkCpuEasy | | control = = ctNetworkCpu | | control = = ctNetworkCpuUltra | | control = = ctNetworkCpuMega ;
2010-03-19 19:58:46 +01:00
}
// ==================== upgrade manager ====================
void Faction : : startUpgrade ( const UpgradeType * ut ) {
upgradeManager . startUpgrade ( ut , index ) ;
}
void Faction : : cancelUpgrade ( const UpgradeType * ut ) {
upgradeManager . cancelUpgrade ( ut ) ;
}
void Faction : : finishUpgrade ( const UpgradeType * ut ) {
upgradeManager . finishUpgrade ( ut ) ;
2015-11-18 21:23:27 +01:00
if ( world - > getThisFaction ( ) ! = NULL & & this - > getIndex ( ) = = world - > getThisFaction ( ) - > getIndex ( ) ) {
Console * console = world - > getGame ( ) - > getConsole ( ) ;
console - > addStdMessage ( " UpgradeFinished " , " : " + formatString ( ut - > getName ( true ) ) ) ;
}
2010-03-19 19:58:46 +01:00
for ( int i = 0 ; i < getUnitCount ( ) ; + + i ) {
getUnit ( i ) - > applyUpgrade ( ut ) ;
}
}
// ==================== reqs ====================
2010-08-22 23:09:35 +02:00
//checks if all required units and upgrades are present and maxUnitCount is within limit
2011-01-29 13:42:18 +01:00
bool Faction : : reqsOk ( const RequirableType * rt ) const {
2010-05-03 08:25:54 +02:00
assert ( rt ! = NULL ) ;
2010-03-19 19:58:46 +01:00
//required units
2011-01-29 13:42:18 +01:00
for ( int i = 0 ; i < rt - > getUnitReqCount ( ) ; + + i ) {
bool found = false ;
for ( int j = 0 ; j < getUnitCount ( ) ; + + j ) {
2010-03-19 19:58:46 +01:00
Unit * unit = getUnit ( j ) ;
const UnitType * ut = unit - > getType ( ) ;
2011-01-29 13:42:18 +01:00
if ( rt - > getUnitReq ( i ) = = ut & & unit - > isOperative ( ) ) {
2010-03-19 19:58:46 +01:00
found = true ;
break ;
}
}
2011-01-29 13:42:18 +01:00
if ( found = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugLUA ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-19 19:58:46 +01:00
return false ;
}
}
//required upgrades
2011-01-29 13:42:18 +01:00
for ( int i = 0 ; i < rt - > getUpgradeReqCount ( ) ; + + i ) {
2010-10-11 17:58:10 +02:00
if ( upgradeManager . isUpgraded ( rt - > getUpgradeReq ( i ) ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugLUA ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-19 19:58:46 +01:00
return false ;
}
}
2010-12-09 21:41:11 +01:00
2010-10-11 17:58:10 +02:00
if ( dynamic_cast < const UnitType * > ( rt ) ! = NULL ) {
2012-04-16 21:29:37 +02:00
const UnitType * producedUnitType = dynamic_cast < const UnitType * > ( rt ) ;
2010-10-11 17:58:10 +02:00
if ( producedUnitType ! = NULL & & producedUnitType - > getMaxUnitCount ( ) > 0 ) {
if ( producedUnitType - > getMaxUnitCount ( ) < = getCountForMaxUnitCount ( producedUnitType ) ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugLUA ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-10-08 21:30:53 +02:00
return false ;
}
}
2014-11-12 15:14:52 +01:00
if ( producedUnitType ! = NULL & & isUnitLocked ( producedUnitType ) ) {
return false ;
}
2010-08-22 23:09:35 +02:00
}
2010-12-09 21:41:11 +01:00
2010-03-19 19:58:46 +01:00
return true ;
2010-08-22 23:09:35 +02:00
}
2010-03-19 19:58:46 +01:00
2010-08-22 23:09:35 +02:00
int Faction : : getCountForMaxUnitCount ( const UnitType * unitType ) const {
int count = 0 ;
//calculate current unit count
for ( int j = 0 ; j < getUnitCount ( ) ; + + j ) {
Unit * unit = getUnit ( j ) ;
const UnitType * currentUt = unit - > getType ( ) ;
2020-12-09 01:46:56 +01:00
if ( unitType = = currentUt & & ( unit - > isAlive ( ) ) ) {
2010-08-22 23:09:35 +02:00
count + + ;
}
//check if there is any command active which already produces this unit
2020-12-13 03:47:50 +01:00
count = count + unit - > getCountOfProducedUnitsPreExistence ( unitType ) ;
2010-08-22 23:09:35 +02:00
}
return count ;
2010-03-19 19:58:46 +01:00
}
2010-08-22 23:09:35 +02:00
2010-11-09 10:06:52 +01:00
bool Faction : : reqsOk ( const CommandType * ct ) const {
2010-05-03 08:25:54 +02:00
assert ( ct ! = NULL ) ;
2011-01-10 07:43:47 +01:00
if ( ct = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " In [Faction::reqsOk] ct == NULL " ) ;
2011-01-10 07:43:47 +01:00
}
2010-11-09 10:06:52 +01:00
if ( ct - > getProduced ( ) ! = NULL & & reqsOk ( ct - > getProduced ( ) ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugLUA ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] reqsOk FAILED \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-19 19:58:46 +01:00
return false ;
}
2010-11-09 10:06:52 +01:00
if ( ct - > getClass ( ) = = ccUpgrade ) {
2010-03-19 19:58:46 +01:00
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( ct ) ;
2010-11-09 10:06:52 +01:00
if ( upgradeManager . isUpgradingOrUpgraded ( uct - > getProducedUpgrade ( ) ) ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugLUA ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] upgrade check FAILED \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-19 19:58:46 +01:00
return false ;
}
}
return reqsOk ( static_cast < const RequirableType * > ( ct ) ) ;
}
// ================== cost application ==================
//apply costs except static production (start building/production)
2012-03-27 05:23:03 +02:00
bool Faction : : applyCosts ( const ProducibleType * p , const CommandType * ct ) {
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2010-03-19 19:58:46 +01:00
}
2012-03-27 05:23:03 +02:00
if ( ignoreResourceCosts = = false ) {
if ( checkCosts ( p , ct ) = = false ) {
return false ;
2010-03-19 19:58:46 +01:00
}
2012-03-27 05:23:03 +02:00
assert ( p ! = NULL ) ;
//for each unit cost spend it
//pass 2, decrease resources, except negative static costs (ie: farms)
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i ) {
const Resource * r = p - > getCost ( i ) ;
if ( r = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-06-13 10:55:48 +02:00
snprintf ( szBuf , 8096 , " cannot apply costs for p [%s] %d of %d costs resource is null " , p - > getName ( false ) . c_str ( ) , i , p - > getCostCount ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2012-03-27 05:23:03 +02:00
}
const ResourceType * rt = r - > getType ( ) ;
if ( rt = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-06-13 10:55:48 +02:00
snprintf ( szBuf , 8096 , " cannot apply costs for p [%s] %d of %d costs resourcetype [%s] is null " , p - > getName ( false ) . c_str ( ) , i , p - > getCostCount ( ) , r - > getDescription ( false ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2012-03-27 05:23:03 +02:00
}
int cost = r - > getAmount ( ) ;
2013-12-14 08:04:12 +01:00
if ( ( cost > 0 | | ( rt - > getClass ( ) ! = rcStatic ) ) & & rt - > getClass ( ) ! = rcConsumable ) {
2012-03-27 05:23:03 +02:00
incResourceAmount ( rt , - ( cost ) ) ;
}
}
}
2010-03-19 19:58:46 +01:00
return true ;
}
//apply discount (when a morph ends)
void Faction : : applyDiscount ( const ProducibleType * p , int discount )
{
2010-05-03 08:25:54 +02:00
assert ( p ! = NULL ) ;
2010-03-19 19:58:46 +01:00
//increase resources
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i )
{
const ResourceType * rt = p - > getCost ( i ) - > getType ( ) ;
2010-05-03 08:25:54 +02:00
assert ( rt ! = NULL ) ;
2010-03-19 19:58:46 +01:00
int cost = p - > getCost ( i ) - > getAmount ( ) ;
if ( ( cost > 0 | | ( rt - > getClass ( ) ! = rcStatic ) ) & & rt - > getClass ( ) ! = rcConsumable )
{
incResourceAmount ( rt , cost * discount / 100 ) ;
}
}
}
//apply static production (for starting units)
2012-03-27 05:23:03 +02:00
void Faction : : applyStaticCosts ( const ProducibleType * p , const CommandType * ct ) {
2010-05-03 08:25:54 +02:00
assert ( p ! = NULL ) ;
2012-03-27 05:23:03 +02:00
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2012-03-27 05:23:03 +02:00
}
if ( ignoreResourceCosts = = false ) {
//decrease static resources
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i ) {
const ResourceType * rt = p - > getCost ( i ) - > getType ( ) ;
//assert(rt != NULL);
if ( rt = = NULL ) {
2013-06-13 10:55:48 +02:00
throw megaglest_runtime_error ( string ( __FUNCTION__ ) + " rt == NULL for ProducibleType [ " + p - > getName ( false ) + " ] index: " + intToStr ( i ) ) ;
2010-03-19 19:58:46 +01:00
}
2012-03-27 05:23:03 +02:00
if ( rt - > getClass ( ) = = rcStatic ) {
int cost = p - > getCost ( i ) - > getAmount ( ) ;
if ( cost > 0 ) {
incResourceAmount ( rt , - cost ) ;
}
}
}
}
2010-03-19 19:58:46 +01:00
}
//apply static production (when a mana source is done)
2012-03-27 05:23:03 +02:00
void Faction : : applyStaticProduction ( const ProducibleType * p , const CommandType * ct ) {
2010-05-03 08:25:54 +02:00
assert ( p ! = NULL ) ;
2012-03-27 05:23:03 +02:00
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2012-03-27 05:23:03 +02:00
}
if ( ignoreResourceCosts = = false ) {
//decrease static resources
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i ) {
const ResourceType * rt = p - > getCost ( i ) - > getType ( ) ;
assert ( rt ! = NULL ) ;
if ( rt - > getClass ( ) = = rcStatic ) {
int cost = p - > getCost ( i ) - > getAmount ( ) ;
if ( cost < 0 ) {
incResourceAmount ( rt , - cost ) ;
}
2010-03-19 19:58:46 +01:00
}
2012-03-27 05:23:03 +02:00
}
}
2010-03-19 19:58:46 +01:00
}
//deapply all costs except static production (usually when a building is cancelled)
2012-03-27 05:23:03 +02:00
void Faction : : deApplyCosts ( const ProducibleType * p , const CommandType * ct ) {
2010-05-03 08:25:54 +02:00
assert ( p ! = NULL ) ;
2010-03-19 19:58:46 +01:00
2012-03-27 05:23:03 +02:00
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2012-03-27 05:23:03 +02:00
}
if ( ignoreResourceCosts = = false ) {
//increase resources
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i ) {
const ResourceType * rt = p - > getCost ( i ) - > getType ( ) ;
assert ( rt ! = NULL ) ;
int cost = p - > getCost ( i ) - > getAmount ( ) ;
if ( ( cost > 0 | | ( rt - > getClass ( ) ! = rcStatic ) ) & & rt - > getClass ( ) ! = rcConsumable ) {
incResourceAmount ( rt , cost ) ;
}
}
}
2010-03-19 19:58:46 +01:00
}
//deapply static costs (usually when a unit dies)
2012-03-27 05:23:03 +02:00
void Faction : : deApplyStaticCosts ( const ProducibleType * p , const CommandType * ct ) {
2010-05-03 08:25:54 +02:00
assert ( p ! = NULL ) ;
2012-03-27 05:23:03 +02:00
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2012-03-27 05:23:03 +02:00
}
if ( ignoreResourceCosts = = false ) {
//decrease resources
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i ) {
const ResourceType * rt = p - > getCost ( i ) - > getType ( ) ;
assert ( rt ! = NULL ) ;
if ( rt - > getClass ( ) = = rcStatic ) {
if ( rt - > getRecoup_cost ( ) = = true ) {
int cost = p - > getCost ( i ) - > getAmount ( ) ;
incResourceAmount ( rt , cost ) ;
}
}
}
}
2010-03-19 19:58:46 +01:00
}
//deapply static costs, but not negative costs, for when building gets killed
2012-03-27 05:23:03 +02:00
void Faction : : deApplyStaticConsumption ( const ProducibleType * p , const CommandType * ct ) {
2010-05-03 08:25:54 +02:00
assert ( p ! = NULL ) ;
2012-03-27 05:23:03 +02:00
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2012-03-27 05:23:03 +02:00
}
if ( ignoreResourceCosts = = false ) {
//decrease resources
for ( int i = 0 ; i < p - > getCostCount ( ) ; + + i ) {
const ResourceType * rt = p - > getCost ( i ) - > getType ( ) ;
assert ( rt ! = NULL ) ;
if ( rt - > getClass ( ) = = rcStatic ) {
int cost = p - > getCost ( i ) - > getAmount ( ) ;
if ( cost > 0 ) {
incResourceAmount ( rt , cost ) ;
}
2010-03-19 19:58:46 +01:00
}
2012-03-27 05:23:03 +02:00
}
}
2010-03-19 19:58:46 +01:00
}
//apply resource on interval (cosumable resouces)
2021-06-18 17:25:37 +02:00
// returns true if warning sound for food etc is needed
bool Faction : : applyCostsOnInterval ( const ResourceType * rtApply ) {
2010-03-19 19:58:46 +01:00
2021-06-18 17:25:37 +02:00
bool warningSoundNeeded = false ;
2010-10-22 06:16:11 +02:00
// For each Resource type we store in the int a total consumed value, then
// a vector of units that consume the resource type
std : : map < const ResourceType * , std : : pair < int , std : : vector < Unit * > > > resourceIntervalUsage ;
// count up consumables usage for the interval
for ( int j = 0 ; j < getUnitCount ( ) ; + + j ) {
Unit * unit = getUnit ( j ) ;
if ( unit - > isOperative ( ) = = true ) {
for ( int k = 0 ; k < unit - > getType ( ) - > getCostCount ( ) ; + + k ) {
const Resource * resource = unit - > getType ( ) - > getCost ( k ) ;
2010-10-23 00:52:37 +02:00
if ( resource - > getType ( ) = = rtApply & & resource - > getType ( ) - > getClass ( ) = = rcConsumable & & resource - > getAmount ( ) ! = 0 ) {
2010-10-22 06:16:11 +02:00
if ( resourceIntervalUsage . find ( resource - > getType ( ) ) = = resourceIntervalUsage . end ( ) ) {
resourceIntervalUsage [ resource - > getType ( ) ] = make_pair < int , std : : vector < Unit * > > ( 0 , std : : vector < Unit * > ( ) ) ;
}
// Negative cost means accumulate the resource type
resourceIntervalUsage [ resource - > getType ( ) ] . first + = - resource - > getAmount ( ) ;
// If the cost > 0 then the unit is a consumer
if ( resource - > getAmount ( ) > 0 ) {
resourceIntervalUsage [ resource - > getType ( ) ] . second . push_back ( unit ) ;
}
}
}
}
}
// Apply consumable resource usage
2011-09-01 03:11:23 +02:00
if ( resourceIntervalUsage . empty ( ) = = false ) {
2010-10-22 06:16:11 +02:00
for ( std : : map < const ResourceType * , std : : pair < int , std : : vector < Unit * > > > : : iterator iter = resourceIntervalUsage . begin ( ) ;
iter ! = resourceIntervalUsage . end ( ) ;
+ + iter ) {
// Apply resource type usage to faction resource store
const ResourceType * rt = iter - > first ;
int resourceTypeUsage = iter - > second . first ;
incResourceAmount ( rt , resourceTypeUsage ) ;
2021-06-18 17:25:37 +02:00
if ( rt - > getClass ( ) = = rcConsumable ) {
const Resource * r = getResource ( rt ) ;
if ( r - > getBalance ( ) * 5 + r - > getAmount ( ) < 0 & & r - > getAmount ( ) > = 0 ) {
// warning for player and team( if shared resources or control )
bool sharedTeamResources = world - > getGame ( ) - > isFlagType1BitEnabled ( ft1_allow_shared_team_resources ) ;
bool sharedTeamUnits = world - > getGame ( ) - > isFlagType1BitEnabled ( ft1_allow_shared_team_units ) ;
bool isTeam = ( this - > getTeam ( ) = = world - > getThisTeamIndex ( ) ) ;
if ( this - > getIndex ( ) = = world - > getThisFactionIndex ( ) | | ( isTeam & & ( sharedTeamResources | | sharedTeamUnits ) ) ) {
warningSoundNeeded = true ;
}
}
}
2010-10-22 06:16:11 +02:00
// Check if we have any unit consumers
if ( getResource ( rt ) - > getAmount ( ) < 0 ) {
resetResourceAmount ( rt ) ;
// Apply consequences to consumer units of this resource type
std : : vector < Unit * > & resourceConsumers = iter - > second . second ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) resourceConsumers . size ( ) ; + + i ) {
2010-10-22 06:16:11 +02:00
Unit * unit = resourceConsumers [ i ] ;
//decrease unit hp
if ( scriptManager - > getPlayerModifiers ( this - > index ) - > getConsumeEnabled ( ) = = true ) {
2014-12-22 06:07:24 +01:00
bool decHpResult = unit - > decHp ( unit - > getType ( ) - > getTotalMaxHp ( unit - > getTotalUpgrade ( ) ) / 3 ) ;
2010-10-22 06:16:11 +02:00
if ( decHpResult ) {
2011-11-16 22:38:12 +01:00
unit - > setCauseOfDeath ( ucodStarvedResource ) ;
2012-03-31 01:38:05 +02:00
world - > getStats ( ) - > die ( unit - > getFactionIndex ( ) , unit - > getType ( ) - > getCountUnitDeathInStats ( ) ) ;
2010-10-22 06:16:11 +02:00
scriptManager - > onUnitDied ( unit ) ;
}
2014-07-20 03:28:03 +02:00
StaticSound * sound = static_cast < const DieSkillType * > ( unit - > getType ( ) - > getFirstStOfClass ( scDie ) ) - > getSound ( ) ;
2011-03-18 22:23:34 +01:00
if ( sound ! = NULL & &
2011-10-12 18:03:55 +02:00
( thisFaction = = true | | world - > showWorldForPlayer ( world - > getThisTeamIndex ( ) ) = = true ) ) {
2010-10-22 06:16:11 +02:00
SoundRenderer : : getInstance ( ) . playFx ( sound ) ;
}
}
}
}
}
}
2021-06-18 17:25:37 +02:00
return warningSoundNeeded ;
2010-03-19 19:58:46 +01:00
}
2019-10-21 00:46:06 +02:00
int Faction : : getAmountOfProducable ( const ProducibleType * pt , const CommandType * ct ) {
2010-05-03 08:25:54 +02:00
assert ( pt ! = NULL ) ;
2012-03-27 05:23:03 +02:00
bool ignoreResourceCosts = false ;
if ( ct ! = NULL & & ct - > getClass ( ) = = ccMorph ) {
const MorphCommandType * mct = dynamic_cast < const MorphCommandType * > ( ct ) ;
2013-12-14 08:04:12 +01:00
if ( mct ! = NULL ) {
ignoreResourceCosts = mct - > getIgnoreResourceRequirements ( ) ;
}
2012-03-27 05:23:03 +02:00
//printf("Checking costs = %d for commandtype:\n%s\n",ignoreResourceCosts,mct->getDesc(NULL).c_str());
}
2019-10-21 00:46:06 +02:00
int maxAmount = INT_MAX ;
2012-03-27 05:23:03 +02:00
if ( ignoreResourceCosts = = false ) {
//for each unit cost check if enough resources
for ( int i = 0 ; i < pt - > getCostCount ( ) ; + + i ) {
const ResourceType * rt = pt - > getCost ( i ) - > getType ( ) ;
int cost = pt - > getCost ( i ) - > getAmount ( ) ;
if ( cost > 0 ) {
int available = getResource ( rt ) - > getAmount ( ) ;
2019-10-21 00:46:06 +02:00
int possibleCount = available / cost ;
if ( maxAmount > possibleCount )
maxAmount = possibleCount ;
if ( maxAmount = = 0 ) {
break ;
2012-03-27 05:23:03 +02:00
}
2010-03-19 19:58:46 +01:00
}
}
2012-03-27 05:23:03 +02:00
}
2010-03-19 19:58:46 +01:00
2019-10-21 00:46:06 +02:00
return maxAmount ;
}
bool Faction : : checkCosts ( const ProducibleType * pt , const CommandType * ct ) {
return getAmountOfProducable ( pt , ct ) > 0 ;
2010-03-19 19:58:46 +01:00
}
// ================== diplomacy ==================
2010-11-09 10:06:52 +01:00
bool Faction : : isAlly ( const Faction * faction ) {
2010-05-03 08:25:54 +02:00
assert ( faction ! = NULL ) ;
2012-03-30 07:53:33 +02:00
return ( teamIndex = = faction - > getTeam ( ) | |
faction - > getTeam ( ) = = GameConstants : : maxPlayers - 1 + fpt_Observer ) ;
2010-03-19 19:58:46 +01:00
}
// ================== misc ==================
2010-11-09 10:06:52 +01:00
void Faction : : incResourceAmount ( const ResourceType * rt , int amount ) {
2015-01-02 02:45:44 +01:00
if ( world ! = NULL & & world - > getGame ( ) ! = NULL
2015-01-02 16:26:24 +01:00
& & world - > getGame ( ) - > isFlagType1BitEnabled (
2015-01-02 02:45:44 +01:00
ft1_allow_shared_team_resources ) = = true ) {
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
Resource * r = & resources [ i ] ;
if ( r - > getType ( ) = = rt ) {
r - > setAmount ( r - > getAmount ( ) + amount ) ;
if ( r - > getType ( ) - > getClass ( ) ! = rcStatic & & ( getResource ( rt , false ) - > getAmount ( ) + amount ) > getStoreAmount ( rt , false ) ) {
r - > setAmount ( getStoreAmount ( rt , false ) - ( getResource ( rt , false ) - > getAmount ( ) - r - > getAmount ( ) ) ) ;
}
return ;
}
}
} else {
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
Resource * r = & resources [ i ] ;
if ( r - > getType ( ) = = rt ) {
r - > setAmount ( r - > getAmount ( ) + amount ) ;
if ( r - > getType ( ) - > getClass ( ) ! = rcStatic & & r - > getAmount ( ) > getStoreAmount ( rt ) ) {
r - > setAmount ( getStoreAmount ( rt ) ) ;
}
return ;
2010-03-19 19:58:46 +01:00
}
}
}
assert ( false ) ;
}
void Faction : : setResourceBalance ( const ResourceType * rt , int balance ) {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
2010-03-19 19:58:46 +01:00
Resource * r = & resources [ i ] ;
if ( r - > getType ( ) = = rt ) {
r - > setBalance ( balance ) ;
return ;
}
}
assert ( false ) ;
}
2010-09-10 10:51:32 +02:00
Unit * Faction : : findUnit ( int id ) const {
UnitMap : : const_iterator itFound = unitMap . find ( id ) ;
if ( itFound = = unitMap . end ( ) ) {
2010-03-19 19:58:46 +01:00
return NULL ;
}
2010-09-10 10:51:32 +02:00
return itFound - > second ;
2010-03-19 19:58:46 +01:00
}
2011-09-25 06:07:59 +02:00
void Faction : : addUnit ( Unit * unit ) {
MutexSafeWrapper safeMutex ( unitsMutex , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-03-19 19:58:46 +01:00
units . push_back ( unit ) ;
2010-06-02 10:03:56 +02:00
unitMap [ unit - > getId ( ) ] = unit ;
2010-03-19 19:58:46 +01:00
}
void Faction : : removeUnit ( Unit * unit ) {
2011-09-25 06:07:59 +02:00
MutexSafeWrapper safeMutex ( unitsMutex , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-06-02 10:03:56 +02:00
assert ( units . size ( ) = = unitMap . size ( ) ) ;
int unitId = unit - > getId ( ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) units . size ( ) ; + + i ) {
2010-06-02 10:03:56 +02:00
if ( units [ i ] - > getId ( ) = = unitId ) {
2010-03-19 19:58:46 +01:00
units . erase ( units . begin ( ) + i ) ;
2010-06-02 10:03:56 +02:00
unitMap . erase ( unitId ) ;
assert ( units . size ( ) = = unitMap . size ( ) ) ;
2010-03-19 19:58:46 +01:00
return ;
}
}
2010-06-02 10:03:56 +02:00
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Could not remove unit from faction! " ) ;
2012-04-16 21:29:37 +02:00
//assert(false);
2010-03-19 19:58:46 +01:00
}
2015-01-17 00:06:17 +01:00
void Faction : : addStore ( const UnitType * unitType ) {
2010-05-03 08:25:54 +02:00
assert ( unitType ! = NULL ) ;
2013-10-11 04:15:49 +02:00
for ( int newUnitStoredResourceIndex = 0 ;
newUnitStoredResourceIndex < unitType - > getStoredResourceCount ( ) ;
+ + newUnitStoredResourceIndex ) {
const Resource * newUnitStoredResource = unitType - > getStoredResource ( newUnitStoredResourceIndex ) ;
for ( int currentStoredResourceIndex = 0 ;
2013-11-19 07:14:06 +01:00
currentStoredResourceIndex < ( int ) store . size ( ) ;
2013-10-11 04:15:49 +02:00
+ + currentStoredResourceIndex ) {
Resource * storedResource = & store [ currentStoredResourceIndex ] ;
if ( storedResource - > getType ( ) = = newUnitStoredResource - > getType ( ) ) {
2015-01-17 00:06:17 +01:00
storedResource - > setAmount ( storedResource - > getAmount ( ) + newUnitStoredResource - > getAmount ( ) ) ;
2010-03-19 19:58:46 +01:00
}
}
}
}
void Faction : : removeStore ( const UnitType * unitType ) {
2010-05-03 08:25:54 +02:00
assert ( unitType ! = NULL ) ;
2010-03-19 19:58:46 +01:00
for ( int i = 0 ; i < unitType - > getStoredResourceCount ( ) ; + + i ) {
const Resource * r = unitType - > getStoredResource ( i ) ;
2013-11-19 07:14:06 +01:00
for ( int j = 0 ; j < ( int ) store . size ( ) ; + + j ) {
2010-03-19 19:58:46 +01:00
Resource * storedResource = & store [ j ] ;
if ( storedResource - > getType ( ) = = r - > getType ( ) ) {
storedResource - > setAmount ( storedResource - > getAmount ( ) - r - > getAmount ( ) ) ;
}
}
}
limitResourcesToStore ( ) ;
}
2011-04-25 08:39:40 +02:00
void Faction : : limitResourcesToStore ( ) {
2015-01-02 02:45:44 +01:00
if ( world ! = NULL & & world - > getGame ( ) ! = NULL
2015-01-02 16:26:24 +01:00
& & world - > getGame ( ) - > isFlagType1BitEnabled (
2015-01-02 02:45:44 +01:00
ft1_allow_shared_team_resources ) = = true ) {
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
Resource * r = & resources [ i ] ;
const ResourceType * rt = r - > getType ( ) ;
if ( rt - > getClass ( ) ! = rcStatic & & ( getResource ( rt , false ) - > getAmount ( ) ) > getStoreAmount ( rt , false ) ) {
r - > setAmount ( getStoreAmount ( rt , false ) - ( getResource ( rt , false ) - > getAmount ( ) - r - > getAmount ( ) ) ) ;
}
}
} else {
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
Resource * r = & resources [ i ] ;
Resource * s = & store [ i ] ;
if ( r - > getType ( ) - > getClass ( ) ! = rcStatic & & r - > getAmount ( ) > s - > getAmount ( ) ) {
r - > setAmount ( s - > getAmount ( ) ) ;
}
2010-03-19 19:58:46 +01:00
}
}
}
void Faction : : resetResourceAmount ( const ResourceType * rt ) {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) resources . size ( ) ; + + i ) {
2010-03-19 19:58:46 +01:00
if ( resources [ i ] . getType ( ) = = rt ) {
resources [ i ] . setAmount ( 0 ) ;
return ;
}
}
assert ( false ) ;
}
2010-10-24 03:49:25 +02:00
bool Faction : : isResourceTargetInCache ( const Vec2i & pos , bool incrementUseCounter ) {
bool result = false ;
2010-11-09 10:06:52 +01:00
if ( cachingDisabled = = false ) {
2011-09-01 03:11:23 +02:00
if ( cacheResourceTargetList . empty ( ) = = false ) {
2010-11-01 17:44:05 +01:00
std : : map < Vec2i , int > : : iterator iter = cacheResourceTargetList . find ( pos ) ;
2010-11-09 10:06:52 +01:00
2010-11-01 17:44:05 +01:00
result = ( iter ! = cacheResourceTargetList . end ( ) ) ;
if ( result = = true & & incrementUseCounter = = true ) {
iter - > second + + ;
}
2010-10-20 09:28:27 +02:00
}
}
2010-11-09 10:06:52 +01:00
2010-10-24 03:49:25 +02:00
return result ;
}
2010-11-09 10:06:52 +01:00
void Faction : : addResourceTargetToCache ( const Vec2i & pos , bool incrementUseCounter ) {
if ( cachingDisabled = = false ) {
bool duplicateEntry = isResourceTargetInCache ( pos , incrementUseCounter ) ;
//bool duplicateEntry = false;
2010-11-01 17:44:05 +01:00
if ( duplicateEntry = = false ) {
cacheResourceTargetList [ pos ] = 1 ;
2010-12-01 00:32:39 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [addResourceTargetToCache] pos [%s]cacheResourceTargetList.size() [ " MG_SIZE_T_SPECIFIER " ] " ,
2010-12-02 00:38:03 +01:00
pos . getString ( ) . c_str ( ) , cacheResourceTargetList . size ( ) ) ;
2010-12-01 00:32:39 +01:00
//unit->logSynchData(szBuf);
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " ----------------------------------- START [%d] ------------------------------------------------ \n " , getFrameCount ( ) ) ;
2010-12-02 00:38:03 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " [%s::%d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " %s \n " , szBuf ) ;
2010-12-01 00:32:39 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " ------------------------------------ END [%d] ------------------------------------------------- \n " , getFrameCount ( ) ) ;
}
2010-11-01 17:44:05 +01:00
}
2010-10-20 09:28:27 +02:00
}
}
2010-10-21 21:26:14 +02:00
void Faction : : removeResourceTargetFromCache ( const Vec2i & pos ) {
2010-11-09 10:06:52 +01:00
if ( cachingDisabled = = false ) {
2011-09-01 03:11:23 +02:00
if ( cacheResourceTargetList . empty ( ) = = false ) {
2010-11-01 17:44:05 +01:00
std : : map < Vec2i , int > : : iterator iter = cacheResourceTargetList . find ( pos ) ;
2010-11-09 10:06:52 +01:00
2010-11-01 17:44:05 +01:00
if ( iter ! = cacheResourceTargetList . end ( ) ) {
cacheResourceTargetList . erase ( pos ) ;
2010-12-01 00:32:39 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [removeResourceTargetFromCache] pos [%s]cacheResourceTargetList.size() [ " MG_SIZE_T_SPECIFIER " ] " ,
2010-12-02 00:38:03 +01:00
pos . getString ( ) . c_str ( ) , cacheResourceTargetList . size ( ) ) ;
2010-12-01 00:32:39 +01:00
//unit->logSynchData(szBuf);
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " ----------------------------------- START [%d] ------------------------------------------------ \n " , getFrameCount ( ) ) ;
2010-12-02 00:38:03 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " [%s::%d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " %s \n " , szBuf ) ;
2010-12-01 00:32:39 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " ------------------------------------ END [%d] ------------------------------------------------- \n " , getFrameCount ( ) ) ;
}
2010-11-01 17:44:05 +01:00
}
2010-10-21 21:26:14 +02:00
}
}
}
2010-10-21 22:31:09 +02:00
void Faction : : addCloseResourceTargetToCache ( const Vec2i & pos ) {
2010-11-09 10:06:52 +01:00
if ( cachingDisabled = = false ) {
2010-11-01 17:44:05 +01:00
if ( cachedCloseResourceTargetLookupList . find ( pos ) = = cachedCloseResourceTargetLookupList . end ( ) ) {
const Map * map = world - > getMap ( ) ;
const int harvestDistance = 5 ;
2010-11-09 10:06:52 +01:00
2010-11-01 17:44:05 +01:00
for ( int j = - harvestDistance ; j < = harvestDistance ; + + j ) {
for ( int k = - harvestDistance ; k < = harvestDistance ; + + k ) {
Vec2i newPos = pos + Vec2i ( j , k ) ;
if ( isResourceTargetInCache ( newPos ) = = false ) {
if ( map - > isInside ( newPos . x , newPos . y ) ) {
Resource * r = map - > getSurfaceCell ( map - > toSurfCoords ( newPos ) ) - > getResource ( ) ;
if ( r ! = NULL ) {
2010-11-09 10:06:52 +01:00
addResourceTargetToCache ( newPos ) ;
//cacheResourceTargetList[newPos] = 1;
2010-11-01 17:44:05 +01:00
}
2010-10-26 00:02:36 +02:00
}
2010-10-24 03:49:25 +02:00
}
2010-10-21 22:31:09 +02:00
}
}
2010-10-26 00:02:36 +02:00
2010-11-01 17:44:05 +01:00
cachedCloseResourceTargetLookupList [ pos ] = true ;
}
2010-10-21 22:31:09 +02:00
}
}
2013-05-25 07:31:32 +02:00
Vec2i Faction : : getClosestResourceTypeTargetFromCache ( Unit * unit , const ResourceType * type , int frameIndex ) {
2010-10-20 09:28:27 +02:00
Vec2i result ( - 1 ) ;
2010-11-09 10:06:52 +01:00
if ( cachingDisabled = = false ) {
2011-09-01 03:11:23 +02:00
if ( cacheResourceTargetList . empty ( ) = = false ) {
2013-05-27 10:26:01 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " cacheResourceTargetList.size() [ " MG_SIZE_T_SPECIFIER " ] " , cacheResourceTargetList . size ( ) ) ;
if ( frameIndex < 0 ) {
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
else {
unit - > logSynchDataThreaded ( __FILE__ , __LINE__ , szBuf ) ;
}
}
2010-11-01 17:44:05 +01:00
std : : vector < Vec2i > deleteList ;
const int harvestDistance = 5 ;
const Map * map = world - > getMap ( ) ;
Vec2i pos = unit - > getPos ( ) ;
bool foundCloseResource = false ;
// First look immediately around the unit's position
2011-03-21 02:03:14 +01:00
// 0 means start looking leftbottom to top right
2016-05-28 01:15:27 +02:00
// if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("#1 Invalid access to Faction random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
// }
2011-03-21 02:03:14 +01:00
int tryRadius = random . randRange ( 0 , 1 ) ;
2016-05-28 01:15:27 +02:00
//int tryRadius = unit->getRandom(true)->randRange(0,1);
//int tryRadius = 0;
2011-03-21 02:03:14 +01:00
if ( tryRadius = = 0 ) {
for ( int j = - harvestDistance ; j < = harvestDistance & & foundCloseResource = = false ; + + j ) {
for ( int k = - harvestDistance ; k < = harvestDistance & & foundCloseResource = = false ; + + k ) {
Vec2i newPos = pos + Vec2i ( j , k ) ;
if ( map - > isInside ( newPos ) = = true & & isResourceTargetInCache ( newPos ) = = false ) {
const SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( newPos ) ) ;
if ( sc ! = NULL & & sc - > getResource ( ) ! = NULL ) {
const Resource * resource = sc - > getResource ( ) ;
if ( resource - > getType ( ) ! = NULL & & resource - > getType ( ) = = type ) {
if ( result . x < 0 | | unit - > getPos ( ) . dist ( newPos ) < unit - > getPos ( ) . dist ( result ) ) {
if ( unit - > isBadHarvestPos ( newPos ) = = false ) {
result = newPos ;
foundCloseResource = true ;
break ;
}
2010-11-01 17:44:05 +01:00
}
2010-10-24 08:53:30 +02:00
}
2010-10-21 21:26:14 +02:00
}
2011-03-21 02:03:14 +01:00
else {
deleteList . push_back ( newPos ) ;
}
2010-10-21 21:26:14 +02:00
}
2011-03-21 02:03:14 +01:00
}
}
}
// start looking topright to leftbottom
else {
for ( int j = harvestDistance ; j > = - harvestDistance & & foundCloseResource = = false ; - - j ) {
for ( int k = harvestDistance ; k > = - harvestDistance & & foundCloseResource = = false ; - - k ) {
Vec2i newPos = pos + Vec2i ( j , k ) ;
if ( map - > isInside ( newPos ) = = true & & isResourceTargetInCache ( newPos ) = = false ) {
const SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( newPos ) ) ;
if ( sc ! = NULL & & sc - > getResource ( ) ! = NULL ) {
const Resource * resource = sc - > getResource ( ) ;
if ( resource - > getType ( ) ! = NULL & & resource - > getType ( ) = = type ) {
if ( result . x < 0 | | unit - > getPos ( ) . dist ( newPos ) < unit - > getPos ( ) . dist ( result ) ) {
if ( unit - > isBadHarvestPos ( newPos ) = = false ) {
result = newPos ;
foundCloseResource = true ;
break ;
}
}
}
}
else {
deleteList . push_back ( newPos ) ;
}
2010-11-01 17:44:05 +01:00
}
2010-10-24 08:53:30 +02:00
}
2010-10-20 09:28:27 +02:00
}
}
2010-10-24 08:53:30 +02:00
2010-11-01 17:44:05 +01:00
if ( foundCloseResource = = false ) {
// Now check the whole cache
for ( std : : map < Vec2i , int > : : iterator iter = cacheResourceTargetList . begin ( ) ;
iter ! = cacheResourceTargetList . end ( ) & & foundCloseResource = = false ;
+ + iter ) {
const Vec2i & cache = iter - > first ;
if ( map - > isInside ( cache ) = = true ) {
const SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( cache ) ) ;
if ( sc ! = NULL & & sc - > getResource ( ) ! = NULL ) {
const Resource * resource = sc - > getResource ( ) ;
if ( resource - > getType ( ) ! = NULL & & resource - > getType ( ) = = type ) {
if ( result . x < 0 | | unit - > getPos ( ) . dist ( cache ) < unit - > getPos ( ) . dist ( result ) ) {
if ( unit - > isBadHarvestPos ( cache ) = = false ) {
result = cache ;
// Close enough to our position, no more looking
if ( unit - > getPos ( ) . dist ( result ) < = ( harvestDistance * 2 ) ) {
foundCloseResource = true ;
break ;
}
2010-10-26 17:25:38 +02:00
}
2010-10-24 08:53:30 +02:00
}
}
}
2010-11-01 17:44:05 +01:00
else {
deleteList . push_back ( cache ) ;
}
2010-10-24 08:53:30 +02:00
}
2010-10-26 17:25:38 +02:00
else {
deleteList . push_back ( cache ) ;
}
2010-10-24 08:53:30 +02:00
}
2010-10-21 23:53:08 +02:00
}
2010-11-09 10:06:52 +01:00
2011-09-01 03:11:23 +02:00
if ( deleteList . empty ( ) = = false ) {
2010-12-01 00:32:39 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [cleaning old resource targets] deleteList.size() [ " MG_SIZE_T_SPECIFIER " ] cacheResourceTargetList.size() [ " MG_SIZE_T_SPECIFIER " ] result [%s] " ,
2010-12-02 00:38:03 +01:00
deleteList . size ( ) , cacheResourceTargetList . size ( ) , result . getString ( ) . c_str ( ) ) ;
2010-12-01 00:32:39 +01:00
2013-05-25 07:31:32 +02:00
if ( frameIndex < 0 ) {
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
else {
unit - > logSynchDataThreaded ( __FILE__ , __LINE__ , szBuf ) ;
}
2010-12-01 00:32:39 +01:00
}
2013-05-25 07:31:32 +02:00
cleanupResourceTypeTargetCache ( & deleteList , frameIndex ) ;
2010-11-01 17:44:05 +01:00
}
2010-10-24 08:53:30 +02:00
}
2010-10-20 09:28:27 +02:00
}
2010-11-09 10:06:52 +01:00
2010-10-20 09:28:27 +02:00
return result ;
}
2010-12-01 00:32:39 +01:00
// CANNOT MODIFY the cache here since the AI calls this method and the AI is only controlled
// by the server for network games and it would cause out of synch since clients do not call
// this method so DO NOT modify the cache here!
2010-11-07 04:27:06 +01:00
Vec2i Faction : : getClosestResourceTypeTargetFromCache ( const Vec2i & pos , const ResourceType * type ) {
Vec2i result ( - 1 ) ;
2010-11-09 10:06:52 +01:00
if ( cachingDisabled = = false ) {
2011-09-01 03:11:23 +02:00
if ( cacheResourceTargetList . empty ( ) = = false ) {
2010-12-01 00:32:39 +01:00
//std::vector<Vec2i> deleteList;
2010-11-07 04:27:06 +01:00
const int harvestDistance = 5 ;
const Map * map = world - > getMap ( ) ;
bool foundCloseResource = false ;
2011-03-21 02:03:14 +01:00
// 0 means start looking leftbottom to top right
2016-05-28 01:15:27 +02:00
// if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("#2 Invalid access to Faction random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
// }
2011-03-21 02:03:14 +01:00
int tryRadius = random . randRange ( 0 , 1 ) ;
if ( tryRadius = = 0 ) {
// First look immediately around the given position
for ( int j = - harvestDistance ; j < = harvestDistance & & foundCloseResource = = false ; + + j ) {
for ( int k = - harvestDistance ; k < = harvestDistance & & foundCloseResource = = false ; + + k ) {
Vec2i newPos = pos + Vec2i ( j , k ) ;
if ( map - > isInside ( newPos ) = = true & & isResourceTargetInCache ( newPos ) = = false ) {
const SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( newPos ) ) ;
if ( sc ! = NULL & & sc - > getResource ( ) ! = NULL ) {
const Resource * resource = sc - > getResource ( ) ;
if ( resource - > getType ( ) ! = NULL & & resource - > getType ( ) = = type ) {
if ( result . x < 0 | | pos . dist ( newPos ) < pos . dist ( result ) ) {
result = newPos ;
foundCloseResource = true ;
break ;
}
}
}
//else {
// deleteList.push_back(newPos);
//}
}
}
}
}
else {
// First look immediately around the given position
for ( int j = harvestDistance ; j > = - harvestDistance & & foundCloseResource = = false ; - - j ) {
for ( int k = harvestDistance ; k > = - harvestDistance & & foundCloseResource = = false ; - - k ) {
Vec2i newPos = pos + Vec2i ( j , k ) ;
if ( map - > isInside ( newPos ) = = true & & isResourceTargetInCache ( newPos ) = = false ) {
const SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( newPos ) ) ;
if ( sc ! = NULL & & sc - > getResource ( ) ! = NULL ) {
const Resource * resource = sc - > getResource ( ) ;
if ( resource - > getType ( ) ! = NULL & & resource - > getType ( ) = = type ) {
if ( result . x < 0 | | pos . dist ( newPos ) < pos . dist ( result ) ) {
result = newPos ;
foundCloseResource = true ;
break ;
}
2010-11-07 04:27:06 +01:00
}
}
2011-03-21 02:03:14 +01:00
//else {
// deleteList.push_back(newPos);
//}
2010-11-07 04:27:06 +01:00
}
}
}
}
if ( foundCloseResource = = false ) {
// Now check the whole cache
for ( std : : map < Vec2i , int > : : iterator iter = cacheResourceTargetList . begin ( ) ;
iter ! = cacheResourceTargetList . end ( ) & & foundCloseResource = = false ;
+ + iter ) {
const Vec2i & cache = iter - > first ;
if ( map - > isInside ( cache ) = = true ) {
const SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( cache ) ) ;
if ( sc ! = NULL & & sc - > getResource ( ) ! = NULL ) {
const Resource * resource = sc - > getResource ( ) ;
if ( resource - > getType ( ) ! = NULL & & resource - > getType ( ) = = type ) {
if ( result . x < 0 | | pos . dist ( cache ) < pos . dist ( result ) ) {
result = cache ;
// Close enough to our position, no more looking
if ( pos . dist ( result ) < = ( harvestDistance * 2 ) ) {
foundCloseResource = true ;
break ;
}
}
}
}
2010-12-01 00:32:39 +01:00
//else {
// deleteList.push_back(cache);
//}
2010-11-07 04:27:06 +01:00
}
2010-12-01 00:32:39 +01:00
//else {
// deleteList.push_back(cache);
//}
2010-11-07 04:27:06 +01:00
}
}
}
}
2010-11-09 10:06:52 +01:00
2010-11-07 04:27:06 +01:00
return result ;
}
2013-05-25 07:31:32 +02:00
void Faction : : cleanupResourceTypeTargetCache ( std : : vector < Vec2i > * deleteListPtr , int frameIndex ) {
2010-11-09 10:06:52 +01:00
if ( cachingDisabled = = false ) {
2011-09-01 03:11:23 +02:00
if ( cacheResourceTargetList . empty ( ) = = false ) {
2010-12-01 00:32:39 +01:00
const int cleanupInterval = ( GameConstants : : updateFps * 5 ) ;
bool needToCleanup = ( getFrameCount ( ) % cleanupInterval = = 0 ) ;
if ( deleteListPtr ! = NULL | | needToCleanup = = true ) {
2010-11-01 17:44:05 +01:00
std : : vector < Vec2i > deleteList ;
if ( deleteListPtr ! = NULL ) {
deleteList = * deleteListPtr ;
}
else {
for ( std : : map < Vec2i , int > : : iterator iter = cacheResourceTargetList . begin ( ) ;
iter ! = cacheResourceTargetList . end ( ) ; + + iter ) {
const Vec2i & cache = iter - > first ;
if ( world - > getMap ( ) - > getSurfaceCell ( world - > getMap ( ) - > toSurfCoords ( cache ) ) ! = NULL ) {
Resource * resource = world - > getMap ( ) - > getSurfaceCell ( world - > getMap ( ) - > toSurfCoords ( cache ) ) - > getResource ( ) ;
if ( resource = = NULL ) {
deleteList . push_back ( cache ) ;
}
}
else {
2010-10-24 03:49:25 +02:00
deleteList . push_back ( cache ) ;
}
}
2010-10-21 23:53:08 +02:00
}
2010-11-09 10:06:52 +01:00
2011-09-01 03:11:23 +02:00
if ( deleteList . empty ( ) = = false ) {
2010-12-01 00:32:39 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2021-06-18 17:25:37 +02:00
char szBuf [ 8095 ] = " " ;
snprintf ( szBuf , 8095 , " [cleaning old resource targets] deleteList.size() [ " MG_SIZE_T_SPECIFIER " ] cacheResourceTargetList.size() [ " MG_SIZE_T_SPECIFIER " ], needToCleanup [%d] " ,
2010-12-02 00:38:03 +01:00
deleteList . size ( ) , cacheResourceTargetList . size ( ) , needToCleanup ) ;
2010-12-01 00:32:39 +01:00
//unit->logSynchData(szBuf);
2013-05-25 07:31:32 +02:00
char szBuf1 [ 8096 ] = " " ;
snprintf ( szBuf1 , 8096 , " ----------------------------------- START [%d] ------------------------------------------------ \n " , getFrameCount ( ) ) ;
string logDataText = szBuf1 ;
snprintf ( szBuf1 , 8096 , " [%s::%d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
logDataText + = szBuf1 ;
snprintf ( szBuf1 , 8096 , " %s \n " , szBuf ) ;
logDataText + = szBuf1 ;
snprintf ( szBuf1 , 8096 , " ------------------------------------ END [%d] ------------------------------------------------- \n " , getFrameCount ( ) ) ;
logDataText + = szBuf1 ;
if ( frameIndex < 0 ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " %s " , logDataText . c_str ( ) ) ;
}
else {
addWorldSynchThreadedLogList ( logDataText ) ;
}
2010-12-01 00:32:39 +01:00
}
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) deleteList . size ( ) ; + + i ) {
2010-12-01 00:32:39 +01:00
Vec2i & cache = deleteList [ i ] ;
cacheResourceTargetList . erase ( cache ) ;
}
2010-11-01 17:44:05 +01:00
}
2010-10-24 03:49:25 +02:00
}
2010-10-20 09:28:27 +02:00
}
}
}
2011-03-29 18:27:01 +02:00
//std::vector<Vec2i> Faction::findCachedPath(const Vec2i &target, Unit *unit) {
// std::vector<Vec2i> result;
// if(cachingDisabled == false) {
// if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
// // Lets find the shortest and most successful path already taken by a
// // similar sized unit
//
// bool foundCachedPath = false;
// std::vector<FactionPathSuccessCache> &cacheList = successfulPathFinderTargetList[target];
// int unitSize = unit->getType()->getSize();
// for(int i = 0; i < cacheList.size(); ++i) {
// FactionPathSuccessCache &cache = cacheList[i];
// if(cache.unitSize <= unitSize) {
// vector<std::pair<vector<Vec2i>, int> > &pathQueue = cache.pathQueue;
//
// for(int j = 0; j < pathQueue.size(); ++j) {
// // Now start at the end of the path and see how many nodes
// // until we reach a cell near the unit's current position
// std::pair<vector<Vec2i>, int> &path = pathQueue[j];
//
// for(int k = path.first.size() - 1; k >= 0; --k) {
// if(world->getMap()->canMove(unit, unit->getPos(), path.first[k]) == true) {
// if(foundCachedPath == false) {
// for(int l = k; l < path.first.size(); ++l) {
// result.push_back(path.first[l]);
// }
// }
// else {
// if(result.size() > (path.first.size() - k)) {
// for(int l = k; l < path.first.size(); ++l) {
// result.push_back(path.first[l]);
// }
// }
// }
// foundCachedPath = true;
//
// break;
// }
// }
// }
// }
// }
// }
// }
//
// return result;
//}
//void Faction::addCachedPath(const Vec2i &target, Unit *unit) {
// if(cachingDisabled == false) {
// if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
// FactionPathSuccessCache cache;
// cache.unitSize = unit->getType()->getSize();
// cache.pathQueue.push_back(make_pair<vector<Vec2i>, int>(unit->getCurrentTargetPathTaken().second,1));
// successfulPathFinderTargetList[target].push_back(cache);
// }
// else {
// bool finishedAdd = false;
// std::pair<Vec2i,std::vector<Vec2i> > currentTargetPathTaken = unit->getCurrentTargetPathTaken();
// std::vector<FactionPathSuccessCache> &cacheList = successfulPathFinderTargetList[target];
// int unitSize = unit->getType()->getSize();
//
// for(int i = 0; i < cacheList.size() && finishedAdd == false; ++i) {
// FactionPathSuccessCache &cache = cacheList[i];
// if(cache.unitSize <= unitSize) {
// vector<std::pair<vector<Vec2i>, int> > &pathQueue = cache.pathQueue;
//
// for(int j = 0; j < pathQueue.size() && finishedAdd == false; ++j) {
// // Now start at the end of the path and see how many nodes are the same
// std::pair<vector<Vec2i>, int> &path = pathQueue[j];
// int minPathSize = std::min(path.first.size(),currentTargetPathTaken.second.size());
// int intersectIndex = -1;
//
// for(int k = 0; k < minPathSize; ++k) {
// if(path.first[path.first.size() - k - 1] != currentTargetPathTaken.second[currentTargetPathTaken.second.size() - k - 1]) {
// intersectIndex = k;
// break;
// }
// }
//
// // New path is same or longer than old path so replace
// // old path with new
// if(intersectIndex + 1 == path.first.size()) {
// path.first = currentTargetPathTaken.second;
// path.second++;
// finishedAdd = true;
// }
// // Old path is same or longer than new path so
// // do nothing
// else if(intersectIndex + 1 == currentTargetPathTaken.second.size()) {
// path.second++;
// finishedAdd = true;
// }
// }
//
// // If new path is >= 10 cells add it
// if(finishedAdd == false && currentTargetPathTaken.second.size() >= 10) {
// pathQueue.push_back(make_pair<vector<Vec2i>, int>(currentTargetPathTaken.second,1));
// }
// }
// }
// }
// }
//}
2010-10-20 00:26:49 +02:00
2010-10-28 02:51:25 +02:00
void Faction : : deletePixels ( ) {
if ( factionType ! = NULL ) {
factionType - > deletePixels ( ) ;
}
}
2017-10-10 05:21:14 +02:00
//Unit * Faction::findClosestUnitWithSkillClass( const Vec2i &pos,const CommandClass &cmdClass,
// const std::vector<SkillClass> &skillClassList,
// const UnitType *unitType) {
// Unit *result = NULL;
//
///*
// std::map<CommandClass,std::map<int,int> >::iterator iterFind = cacheUnitCommandClassList.find(cmdClass);
// if(iterFind != cacheUnitCommandClassList.end()) {
// for(std::map<int,int>::iterator iter = iterFind->second.begin();
// iter != iterFind->second.end(); ++iter) {
// Unit *curUnit = findUnit(iter->second);
// if(curUnit != NULL) {
//
// const CommandType *cmdType = curUnit->getType()->getFirstCtOfClass(cmdClass);
// bool isUnitPossibleCandidate = (cmdType != NULL);
// if(skillClassList.empty() == false) {
// isUnitPossibleCandidate = false;
//
// for(int j = 0; j < skillClassList.size(); ++j) {
// SkillClass skValue = skillClassList[j];
// if(curUnit->getCurrSkill()->getClass() == skValue) {
// isUnitPossibleCandidate = true;
// break;
// }
// }
// }
//
// if(isUnitPossibleCandidate == true) {
// if(result == NULL || curUnit->getPos().dist(pos) < result->getPos().dist(pos)) {
// result = curUnit;
// }
// }
// }
// }
// }
//*/
//
// //if(result == NULL) {
// for(int i = 0; i < getUnitCount(); ++i) {
// Unit *curUnit = getUnit(i);
//
// bool isUnitPossibleCandidate = false;
//
// const CommandType *cmdType = curUnit->getType()->getFirstCtOfClass(cmdClass);
// if(cmdType != NULL) {
// const RepairCommandType *rct = dynamic_cast<const RepairCommandType *>(cmdType);
// if(rct != NULL && rct->isRepairableUnitType(unitType)) {
// isUnitPossibleCandidate = true;
// }
// }
// else {
// isUnitPossibleCandidate = false;
// }
//
// if(isUnitPossibleCandidate == true && skillClassList.empty() == false) {
// isUnitPossibleCandidate = false;
//
// for(int j = 0; j < (int)skillClassList.size(); ++j) {
// SkillClass skValue = skillClassList[j];
// if(curUnit->getCurrSkill()->getClass() == skValue) {
// isUnitPossibleCandidate = true;
// break;
// }
// }
// }
//
//
// if(isUnitPossibleCandidate == true) {
// //cacheUnitCommandClassList[cmdClass][curUnit->getId()] = curUnit->getId();
//
// if(result == NULL || curUnit->getPos().dist(pos) < result->getPos().dist(pos)) {
// result = curUnit;
// }
// }
// }
// //}
// return result;
//}
2010-11-11 09:02:50 +01:00
2010-12-01 00:32:39 +01:00
int Faction : : getFrameCount ( ) {
int frameCount = 0 ;
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
if ( game ! = NULL & & game - > getWorld ( ) ! = NULL ) {
frameCount = game - > getWorld ( ) - > getFrameCount ( ) ;
}
return frameCount ;
}
2011-09-21 08:51:28 +02:00
const SwitchTeamVote * Faction : : getFirstSwitchTeamVote ( ) const {
const SwitchTeamVote * vote = NULL ;
2011-12-02 17:07:59 +01:00
if ( switchTeamVotes . empty ( ) = = false ) {
2011-09-21 08:51:28 +02:00
for ( std : : map < int , SwitchTeamVote > : : const_iterator iterMap = switchTeamVotes . begin ( ) ;
iterMap ! = switchTeamVotes . end ( ) ; + + iterMap ) {
const SwitchTeamVote & curVote = iterMap - > second ;
if ( curVote . voted = = false ) {
vote = & curVote ;
break ;
}
}
}
return vote ;
}
SwitchTeamVote * Faction : : getSwitchTeamVote ( int factionIndex ) {
SwitchTeamVote * vote = NULL ;
if ( switchTeamVotes . find ( factionIndex ) ! = switchTeamVotes . end ( ) ) {
vote = & switchTeamVotes [ factionIndex ] ;
}
return vote ;
}
void Faction : : setSwitchTeamVote ( SwitchTeamVote & vote ) {
switchTeamVotes [ vote . factionIndex ] = vote ;
}
2011-10-04 08:49:44 +02:00
bool Faction : : canCreateUnit ( const UnitType * ut , bool checkBuild , bool checkProduce , bool checkMorph ) const {
// Now check that at least 1 other unit can produce, build or morph this unit
bool foundUnit = false ;
for ( int l = 0 ; l < this - > getUnitCount ( ) & & foundUnit = = false ; + + l ) {
const UnitType * unitType2 = this - > getUnit ( l ) - > getType ( ) ;
for ( int j = 0 ; j < unitType2 - > getCommandTypeCount ( ) & & foundUnit = = false ; + + j ) {
const CommandType * cmdType = unitType2 - > getCommandType ( j ) ;
if ( cmdType ! = NULL ) {
// Check if this is a produce command
if ( checkProduce = = true & & cmdType - > getClass ( ) = = ccProduce ) {
const ProduceCommandType * produce = dynamic_cast < const ProduceCommandType * > ( cmdType ) ;
if ( produce ! = NULL ) {
const UnitType * produceUnit = produce - > getProducedUnit ( ) ;
if ( produceUnit ! = NULL & &
ut - > getId ( ) ! = unitType2 - > getId ( ) & &
2013-06-13 10:55:48 +02:00
ut - > getName ( false ) = = produceUnit - > getName ( false ) ) {
2011-10-04 08:49:44 +02:00
foundUnit = true ;
break ;
}
}
}
// Check if this is a build command
else if ( checkBuild = = true & & cmdType - > getClass ( ) = = ccBuild ) {
const BuildCommandType * build = dynamic_cast < const BuildCommandType * > ( cmdType ) ;
2013-12-14 08:04:12 +01:00
if ( build ! = NULL ) {
for ( int k = 0 ; k < build - > getBuildingCount ( ) & & foundUnit = = false ; + + k ) {
const UnitType * buildUnit = build - > getBuilding ( k ) ;
if ( buildUnit ! = NULL & &
ut - > getId ( ) ! = unitType2 - > getId ( ) & &
ut - > getName ( false ) = = buildUnit - > getName ( false ) ) {
foundUnit = true ;
break ;
}
2011-10-04 08:49:44 +02:00
}
}
}
// Check if this is a morph command
else if ( checkMorph = = true & & cmdType - > getClass ( ) = = ccMorph ) {
const MorphCommandType * morph = dynamic_cast < const MorphCommandType * > ( cmdType ) ;
2013-12-14 08:04:12 +01:00
if ( morph ! = NULL ) {
const UnitType * morphUnit = morph - > getMorphUnit ( ) ;
2011-10-04 08:49:44 +02:00
2013-12-14 08:04:12 +01:00
if ( morphUnit ! = NULL & &
ut - > getId ( ) ! = unitType2 - > getId ( ) & &
ut - > getName ( false ) = = morphUnit - > getName ( false ) ) {
foundUnit = true ;
break ;
}
2011-10-04 08:49:44 +02:00
}
}
}
}
}
return foundUnit ;
}
2013-02-17 08:15:01 +01:00
void Faction : : clearCaches ( ) {
cacheResourceTargetList . clear ( ) ;
cachedCloseResourceTargetLookupList . clear ( ) ;
2013-11-13 20:00:33 +01:00
//aliveUnitListCache.clear();
//mobileUnitListCache.clear();
//beingBuiltUnitListCache.clear();
2013-02-17 08:15:01 +01:00
unsigned int unitCount = this - > getUnitCount ( ) ;
for ( unsigned int i = 0 ; i < unitCount ; + + i ) {
Unit * unit = this - > getUnit ( i ) ;
if ( unit ! = NULL ) {
unit - > clearCaches ( ) ;
}
}
}
2013-11-13 20:00:33 +01:00
uint64 Faction : : getCacheKBytes ( uint64 * cache1Size , uint64 * cache2Size , uint64 * cache3Size , uint64 * cache4Size , uint64 * cache5Size ) {
2011-12-02 17:07:59 +01:00
uint64 cache1Count = 0 ;
uint64 cache2Count = 0 ;
2013-11-13 20:00:33 +01:00
uint64 cache3Count = 0 ;
uint64 cache4Count = 0 ;
uint64 cache5Count = 0 ;
2011-12-02 17:07:59 +01:00
for ( std : : map < Vec2i , int > : : iterator iterMap1 = cacheResourceTargetList . begin ( ) ;
iterMap1 ! = cacheResourceTargetList . end ( ) ; + + iterMap1 ) {
cache1Count + + ;
}
for ( std : : map < Vec2i , bool > : : iterator iterMap1 = cachedCloseResourceTargetLookupList . begin ( ) ;
iterMap1 ! = cachedCloseResourceTargetLookupList . end ( ) ; + + iterMap1 ) {
cache2Count + + ;
}
2013-11-13 20:00:33 +01:00
for ( std : : map < int , const Unit * > : : iterator iterMap1 = aliveUnitListCache . begin ( ) ;
iterMap1 ! = aliveUnitListCache . end ( ) ; + + iterMap1 ) {
cache3Count + + ;
}
for ( std : : map < int , const Unit * > : : iterator iterMap1 = mobileUnitListCache . begin ( ) ;
iterMap1 ! = mobileUnitListCache . end ( ) ; + + iterMap1 ) {
cache4Count + + ;
}
for ( std : : map < int , const Unit * > : : iterator iterMap1 = beingBuiltUnitListCache . begin ( ) ;
iterMap1 ! = beingBuiltUnitListCache . end ( ) ; + + iterMap1 ) {
cache5Count + + ;
}
2011-12-02 17:07:59 +01:00
if ( cache1Size ) {
* cache1Size = cache1Count ;
}
if ( cache2Size ) {
* cache2Size = cache2Count ;
}
2013-11-13 20:00:33 +01:00
if ( cache3Size ) {
* cache3Size = cache3Count ;
}
if ( cache4Size ) {
* cache4Size = cache4Count ;
}
if ( cache5Size ) {
* cache5Size = cache5Count ;
}
2011-12-02 17:07:59 +01:00
uint64 totalBytes = cache1Count * sizeof ( int ) ;
totalBytes + = cache2Count * sizeof ( bool ) ;
2013-11-13 20:00:33 +01:00
totalBytes + = cache3Count * ( sizeof ( int ) + sizeof ( const Unit * ) ) ;
totalBytes + = cache4Count * ( sizeof ( int ) + sizeof ( const Unit * ) ) ;
totalBytes + = cache5Count * ( sizeof ( int ) + sizeof ( const Unit * ) ) ;
2011-12-02 17:07:59 +01:00
totalBytes / = 1000 ;
return totalBytes ;
}
string Faction : : getCacheStats ( ) {
string result = " " ;
int cache1Count = 0 ;
int cache2Count = 0 ;
for ( std : : map < Vec2i , int > : : iterator iterMap1 = cacheResourceTargetList . begin ( ) ;
iterMap1 ! = cacheResourceTargetList . end ( ) ; + + iterMap1 ) {
cache1Count + + ;
}
for ( std : : map < Vec2i , bool > : : iterator iterMap1 = cachedCloseResourceTargetLookupList . begin ( ) ;
iterMap1 ! = cachedCloseResourceTargetLookupList . end ( ) ; + + iterMap1 ) {
cache2Count + + ;
}
uint64 totalBytes = cache1Count * sizeof ( int ) ;
totalBytes + = cache2Count * sizeof ( bool ) ;
totalBytes / = 1000 ;
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " cache1Count [%d] cache2Count [%d] total KB: %s " , cache1Count , cache2Count , formatNumber ( totalBytes ) . c_str ( ) ) ;
2011-12-02 17:07:59 +01:00
result = szBuf ;
return result ;
}
2013-09-17 02:43:14 +02:00
std : : string Faction : : toString ( bool crcMode ) const {
2012-10-06 09:06:40 +02:00
std : : string result = " FactionIndex = " + intToStr ( this - > index ) + " \n " ;
2010-05-18 05:53:57 +02:00
result + = " teamIndex = " + intToStr ( this - > teamIndex ) + " \n " ;
result + = " startLocationIndex = " + intToStr ( this - > startLocationIndex ) + " \n " ;
2013-09-17 02:43:14 +02:00
if ( crcMode = = false ) {
result + = " thisFaction = " + intToStr ( this - > thisFaction ) + " \n " ;
result + = " control = " + intToStr ( this - > control ) + " \n " ;
}
2010-05-18 05:53:57 +02:00
2010-05-29 11:04:22 +02:00
if ( this - > factionType ! = NULL ) {
result + = this - > factionType - > toString ( ) + " \n " ;
}
2010-05-18 05:53:57 +02:00
result + = this - > upgradeManager . toString ( ) + " \n " ;
result + = " ResourceCount = " + intToStr ( resources . size ( ) ) + " \n " ;
2013-11-19 07:14:06 +01:00
for ( int idx = 0 ; idx < ( int ) resources . size ( ) ; idx + + ) {
2013-09-17 02:43:14 +02:00
result + = " index = " + intToStr ( idx ) + " " + resources [ idx ] . toString ( ) + " \n " ;
2010-05-18 05:53:57 +02:00
}
result + = " StoreCount = " + intToStr ( store . size ( ) ) + " \n " ;
2013-11-19 07:14:06 +01:00
for ( int idx = 0 ; idx < ( int ) store . size ( ) ; idx + + ) {
2013-09-17 02:43:14 +02:00
result + = " index = " + intToStr ( idx ) + " " + store [ idx ] . toString ( ) + " \n " ;
2010-05-18 05:53:57 +02:00
}
result + = " Allies = " + intToStr ( allies . size ( ) ) + " \n " ;
2013-11-19 07:14:06 +01:00
for ( int idx = 0 ; idx < ( int ) allies . size ( ) ; idx + + ) {
2013-06-13 03:37:15 +02:00
result + = " index = " + intToStr ( idx ) + " name: " + allies [ idx ] - > factionType - > getName ( false ) + " factionindex = " + intToStr ( allies [ idx ] - > index ) + " \n " ;
2010-05-18 05:53:57 +02:00
}
result + = " Units = " + intToStr ( units . size ( ) ) + " \n " ;
2013-11-19 07:14:06 +01:00
for ( int idx = 0 ; idx < ( int ) units . size ( ) ; idx + + ) {
2013-09-17 02:43:14 +02:00
result + = units [ idx ] - > toString ( crcMode ) + " \n " ;
2010-05-18 05:53:57 +02:00
}
return result ;
}
2012-03-10 04:27:25 +01:00
void Faction : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * factionNode = rootNode - > addChild ( " Faction " ) ;
upgradeManager . saveGame ( factionNode ) ;
for ( unsigned int i = 0 ; i < resources . size ( ) ; + + i ) {
Resource & resource = resources [ i ] ;
resource . saveGame ( factionNode ) ;
}
2012-03-13 00:08:22 +01:00
XmlNode * storeNode = factionNode - > addChild ( " Store " ) ;
for ( unsigned int i = 0 ; i < store . size ( ) ; + + i ) {
Resource & resource = store [ i ] ;
resource . saveGame ( storeNode ) ;
}
2012-03-10 04:27:25 +01:00
for ( unsigned int i = 0 ; i < allies . size ( ) ; + + i ) {
Faction * ally = allies [ i ] ;
XmlNode * allyNode = factionNode - > addChild ( " Ally " ) ;
2012-03-14 00:10:48 +01:00
allyNode - > addAttribute ( " allyFactionIndex " , intToStr ( ally - > getIndex ( ) ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
}
for ( unsigned int i = 0 ; i < units . size ( ) ; + + i ) {
Unit * unit = units [ i ] ;
unit - > saveGame ( factionNode ) ;
}
2014-01-28 04:03:52 +01:00
2012-03-10 04:27:25 +01:00
factionNode - > addAttribute ( " control " , intToStr ( control ) , mapTagReplacements ) ;
2012-03-30 07:53:33 +02:00
factionNode - > addAttribute ( " overridePersonalityType " , intToStr ( overridePersonalityType ) , mapTagReplacements ) ;
2013-06-13 03:37:15 +02:00
factionNode - > addAttribute ( " factiontype " , factionType - > getName ( false ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
factionNode - > addAttribute ( " index " , intToStr ( index ) , mapTagReplacements ) ;
factionNode - > addAttribute ( " teamIndex " , intToStr ( teamIndex ) , mapTagReplacements ) ;
factionNode - > addAttribute ( " startLocationIndex " , intToStr ( startLocationIndex ) , mapTagReplacements ) ;
factionNode - > addAttribute ( " thisFaction " , intToStr ( thisFaction ) , mapTagReplacements ) ;
2014-01-28 04:03:52 +01:00
2012-03-10 04:27:25 +01:00
for ( std : : map < Vec2i , int > : : iterator iterMap = cacheResourceTargetList . begin ( ) ;
iterMap ! = cacheResourceTargetList . end ( ) ; + + iterMap ) {
XmlNode * cacheResourceTargetListNode = factionNode - > addChild ( " cacheResourceTargetList " ) ;
cacheResourceTargetListNode - > addAttribute ( " key " , iterMap - > first . getString ( ) , mapTagReplacements ) ;
cacheResourceTargetListNode - > addAttribute ( " value " , intToStr ( iterMap - > second ) , mapTagReplacements ) ;
}
2014-01-28 04:03:52 +01:00
2012-03-10 04:27:25 +01:00
for ( std : : map < Vec2i , bool > : : iterator iterMap = cachedCloseResourceTargetLookupList . begin ( ) ;
iterMap ! = cachedCloseResourceTargetLookupList . end ( ) ; + + iterMap ) {
XmlNode * cachedCloseResourceTargetLookupListNode = factionNode - > addChild ( " cachedCloseResourceTargetLookupList " ) ;
cachedCloseResourceTargetLookupListNode - > addAttribute ( " key " , iterMap - > first . getString ( ) , mapTagReplacements ) ;
cachedCloseResourceTargetLookupListNode - > addAttribute ( " value " , intToStr ( iterMap - > second ) , mapTagReplacements ) ;
}
factionNode - > addAttribute ( " random " , intToStr ( random . getLastNumber ( ) ) , mapTagReplacements ) ;
factionNode - > addAttribute ( " currentSwitchTeamVoteFactionIndex " , intToStr ( currentSwitchTeamVoteFactionIndex ) , mapTagReplacements ) ;
2014-01-28 04:03:52 +01:00
factionNode - > addAttribute ( " allowSharedTeamUnits " , intToStr ( allowSharedTeamUnits ) , mapTagReplacements ) ;
2014-11-16 18:32:13 +01:00
for ( std : : set < const UnitType * > : : iterator iterMap = lockedUnits . begin ( ) ;
iterMap ! = lockedUnits . end ( ) ; + + iterMap ) {
XmlNode * lockedUnitsListNode = factionNode - > addChild ( " lockedUnitList " ) ;
const UnitType * ut = * iterMap ;
lockedUnitsListNode - > addAttribute ( " value " , ut - > getName ( false ) , mapTagReplacements ) ;
}
2012-03-10 04:27:25 +01:00
2012-03-31 21:50:45 +02:00
for ( std : : map < int , int > : : iterator iterMap = unitsMovingList . begin ( ) ;
iterMap ! = unitsMovingList . end ( ) ; + + iterMap ) {
XmlNode * unitsMovingListNode = factionNode - > addChild ( " unitsMovingList " ) ;
unitsMovingListNode - > addAttribute ( " key " , intToStr ( iterMap - > first ) , mapTagReplacements ) ;
unitsMovingListNode - > addAttribute ( " value " , intToStr ( iterMap - > second ) , mapTagReplacements ) ;
}
for ( std : : map < int , int > : : iterator iterMap = unitsPathfindingList . begin ( ) ;
iterMap ! = unitsPathfindingList . end ( ) ; + + iterMap ) {
XmlNode * unitsPathfindingListNode = factionNode - > addChild ( " unitsPathfindingList " ) ;
unitsPathfindingListNode - > addAttribute ( " key " , intToStr ( iterMap - > first ) , mapTagReplacements ) ;
unitsPathfindingListNode - > addAttribute ( " value " , intToStr ( iterMap - > second ) , mapTagReplacements ) ;
}
2012-03-10 04:27:25 +01:00
}
2012-03-13 16:21:25 +01:00
void Faction : : loadGame ( const XmlNode * rootNode , int factionIndex , GameSettings * settings , World * world ) {
2012-03-13 00:08:22 +01:00
XmlNode * factionNode = NULL ;
vector < XmlNode * > factionNodeList = rootNode - > getChildList ( " Faction " ) ;
for ( unsigned int i = 0 ; i < factionNodeList . size ( ) ; + + i ) {
XmlNode * node = factionNodeList [ i ] ;
2012-03-13 16:21:25 +01:00
if ( node - > getAttribute ( " index " ) - > getIntValue ( ) = = factionIndex ) {
2012-03-13 00:08:22 +01:00
factionNode = node ;
break ;
}
}
if ( factionNode ! = NULL ) {
2012-03-13 16:21:25 +01:00
2012-03-14 00:10:48 +01:00
allies . clear ( ) ;
vector < XmlNode * > allyNodeList = factionNode - > getChildList ( " Ally " ) ;
for ( unsigned int i = 0 ; i < allyNodeList . size ( ) ; + + i ) {
XmlNode * allyNode = allyNodeList [ i ] ;
int allyFactionIndex = allyNode - > getAttribute ( " allyFactionIndex " ) - > getIntValue ( ) ;
allies . push_back ( world - > getFaction ( allyFactionIndex ) ) ;
}
2012-03-13 00:08:22 +01:00
vector < XmlNode * > unitNodeList = factionNode - > getChildList ( " Unit " ) ;
for ( unsigned int i = 0 ; i < unitNodeList . size ( ) ; + + i ) {
XmlNode * unitNode = unitNodeList [ i ] ;
Unit * unit = Unit : : loadGame ( unitNode , settings , this , world ) ;
this - > addUnit ( unit ) ;
}
2012-03-14 00:10:48 +01:00
for ( unsigned int i = 0 ; i < resources . size ( ) ; + + i ) {
Resource & resource = resources [ i ] ;
resource . loadGame ( factionNode , i , techTree ) ;
}
XmlNode * storeNode = factionNode - > getChild ( " Store " ) ;
for ( unsigned int i = 0 ; i < store . size ( ) ; + + i ) {
Resource & resource = store [ i ] ;
resource . loadGame ( storeNode , i , techTree ) ;
}
2012-03-13 16:21:25 +01:00
2012-03-14 00:10:48 +01:00
upgradeManager . loadGame ( factionNode , this ) ;
2012-03-14 00:51:39 +01:00
control = static_cast < ControlType > ( factionNode - > getAttribute ( " control " ) - > getIntValue ( ) ) ;
2012-03-30 07:53:33 +02:00
if ( factionNode - > hasAttribute ( " overridePersonalityType " ) = = true ) {
overridePersonalityType = static_cast < FactionPersonalityType > ( factionNode - > getAttribute ( " overridePersonalityType " ) - > getIntValue ( ) ) ;
}
2012-03-14 00:51:39 +01:00
teamIndex = factionNode - > getAttribute ( " teamIndex " ) - > getIntValue ( ) ;
2014-01-28 04:03:52 +01:00
2012-03-14 00:51:39 +01:00
startLocationIndex = factionNode - > getAttribute ( " startLocationIndex " ) - > getIntValue ( ) ;
2014-01-28 04:03:52 +01:00
2012-04-16 22:15:57 +02:00
thisFaction = factionNode - > getAttribute ( " thisFaction " ) - > getIntValue ( ) ! = 0 ;
2012-03-14 00:51:39 +01:00
2014-01-28 04:03:52 +01:00
if ( factionNode - > hasAttribute ( " allowSharedTeamUnits " ) = = true ) {
allowSharedTeamUnits = factionNode - > getAttribute ( " allowSharedTeamUnits " ) - > getIntValue ( ) ! = 0 ;
}
2013-02-15 19:25:10 +01:00
2012-03-31 21:50:45 +02:00
vector < XmlNode * > cacheResourceTargetListNodeList = factionNode - > getChildList ( " cacheResourceTargetList " ) ;
for ( unsigned int i = 0 ; i < cacheResourceTargetListNodeList . size ( ) ; + + i ) {
XmlNode * cacheResourceTargetListNode = cacheResourceTargetListNodeList [ i ] ;
Vec2i vec = Vec2i : : strToVec2 ( cacheResourceTargetListNode - > getAttribute ( " key " ) - > getValue ( ) ) ;
cacheResourceTargetList [ vec ] = cacheResourceTargetListNode - > getAttribute ( " value " ) - > getIntValue ( ) ;
}
vector < XmlNode * > cachedCloseResourceTargetLookupListNodeList = factionNode - > getChildList ( " cachedCloseResourceTargetLookupList " ) ;
for ( unsigned int i = 0 ; i < cachedCloseResourceTargetLookupListNodeList . size ( ) ; + + i ) {
XmlNode * cachedCloseResourceTargetLookupListNode = cachedCloseResourceTargetLookupListNodeList [ i ] ;
Vec2i vec = Vec2i : : strToVec2 ( cachedCloseResourceTargetLookupListNode - > getAttribute ( " key " ) - > getValue ( ) ) ;
2012-04-16 22:15:57 +02:00
cachedCloseResourceTargetLookupList [ vec ] = cachedCloseResourceTargetLookupListNode - > getAttribute ( " value " ) - > getIntValue ( ) ! = 0 ;
2012-03-31 21:50:45 +02:00
}
2012-03-14 00:51:39 +01:00
random . setLastNumber ( factionNode - > getAttribute ( " random " ) - > getIntValue ( ) ) ;
2012-03-31 21:50:45 +02:00
2014-11-16 18:32:13 +01:00
vector < XmlNode * > lockedUnitsListNodeList = factionNode - > getChildList ( " lockedUnitList " ) ;
for ( unsigned int i = 0 ; i < lockedUnitsListNodeList . size ( ) ; + + i ) {
XmlNode * lockedUnitsListNode = lockedUnitsListNodeList [ i ] ;
string unitName = lockedUnitsListNode - > getAttribute ( " value " ) - > getValue ( ) ;
lockedUnits . insert ( getType ( ) - > getUnitType ( unitName ) ) ;
}
2012-03-31 21:50:45 +02:00
vector < XmlNode * > unitsMovingListNodeList = factionNode - > getChildList ( " unitsMovingList " ) ;
for ( unsigned int i = 0 ; i < unitsMovingListNodeList . size ( ) ; + + i ) {
XmlNode * unitsMovingListNode = unitsMovingListNodeList [ i ] ;
int unitId = unitsMovingListNode - > getAttribute ( " key " ) - > getIntValue ( ) ;
unitsMovingList [ unitId ] = unitsMovingListNode - > getAttribute ( " value " ) - > getIntValue ( ) ;
}
vector < XmlNode * > unitsPathfindingListNodeList = factionNode - > getChildList ( " unitsPathfindingList " ) ;
for ( unsigned int i = 0 ; i < unitsPathfindingListNodeList . size ( ) ; + + i ) {
XmlNode * unitsPathfindingListNode = unitsPathfindingListNodeList [ i ] ;
int unitId = unitsPathfindingListNode - > getAttribute ( " key " ) - > getIntValue ( ) ;
unitsPathfindingList [ unitId ] = unitsPathfindingListNode - > getAttribute ( " value " ) - > getIntValue ( ) ;
}
2012-03-14 00:10:48 +01:00
}
2012-03-13 00:08:22 +01:00
}
2013-09-12 05:33:43 +02:00
Checksum Faction : : getCRC ( ) {
const bool consoleDebug = false ;
Checksum crcForFaction ;
// UpgradeManager upgradeManager;
for ( unsigned int i = 0 ; i < resources . size ( ) ; + + i ) {
Resource & resource = resources [ i ] ;
//crcForFaction.addSum(resource.getCRC().getSum());
uint32 crc = resource . getCRC ( ) . getSum ( ) ;
crcForFaction . addBytes ( & crc , sizeof ( uint32 ) ) ;
}
if ( consoleDebug ) {
if ( getWorld ( ) - > getFrameCount ( ) % 40 = = 0 ) {
printf ( " #1 Frame #: %d Faction: %d CRC: %u \n " , getWorld ( ) - > getFrameCount ( ) , index , crcForFaction . getSum ( ) ) ;
}
}
for ( unsigned int i = 0 ; i < store . size ( ) ; + + i ) {
Resource & resource = store [ i ] ;
//crcForFaction.addSum(resource.getCRC().getSum());
uint32 crc = resource . getCRC ( ) . getSum ( ) ;
crcForFaction . addBytes ( & crc , sizeof ( uint32 ) ) ;
}
if ( consoleDebug ) {
if ( getWorld ( ) - > getFrameCount ( ) % 40 = = 0 ) {
printf ( " #2 Frame #: %d Faction: %d CRC: %u \n " , getWorld ( ) - > getFrameCount ( ) , index , crcForFaction . getSum ( ) ) ;
}
}
for ( unsigned int i = 0 ; i < units . size ( ) ; + + i ) {
Unit * unit = units [ i ] ;
//crcForFaction.addSum(unit->getCRC().getSum());
uint32 crc = unit - > getCRC ( ) . getSum ( ) ;
crcForFaction . addBytes ( & crc , sizeof ( uint32 ) ) ;
}
if ( consoleDebug ) {
if ( getWorld ( ) - > getFrameCount ( ) % 40 = = 0 ) {
printf ( " #3 Frame #: %d Faction: %d CRC: %u \n " , getWorld ( ) - > getFrameCount ( ) , index , crcForFaction . getSum ( ) ) ;
}
}
return crcForFaction ;
}
2013-09-17 18:36:05 +02:00
void Faction : : addCRC_DetailsForWorldFrame ( int worldFrameCount , bool isNetworkServer ) {
2013-11-19 07:14:06 +01:00
unsigned int MAX_FRAME_CACHE = 250 ;
2013-09-17 18:36:05 +02:00
if ( isNetworkServer = = true ) {
2013-09-23 19:16:34 +02:00
MAX_FRAME_CACHE + = 250 ;
2013-09-17 18:36:05 +02:00
}
2013-09-17 02:43:14 +02:00
crcWorldFrameDetails [ worldFrameCount ] = this - > toString ( true ) ;
//if(worldFrameCount <= 0) printf("Adding world frame: %d log entries: %lld\n",worldFrameCount,(long long int)crcWorldFrameDetails.size());
2013-09-23 19:16:34 +02:00
for ( unsigned int i = 0 ; i < units . size ( ) ; + + i ) {
Unit * unit = units [ i ] ;
2013-10-17 04:49:25 +02:00
2013-09-23 19:16:34 +02:00
unit - > getRandom ( ) - > clearLastCaller ( ) ;
unit - > clearNetworkCRCDecHpList ( ) ;
2013-10-21 08:30:25 +02:00
unit - > clearParticleInfo ( ) ;
2013-09-23 19:16:34 +02:00
}
2013-11-19 07:14:06 +01:00
if ( ( unsigned int ) crcWorldFrameDetails . size ( ) > MAX_FRAME_CACHE ) {
2013-09-17 05:03:16 +02:00
//printf("===> Removing older world frame log entries: %lld\n",(long long int)crcWorldFrameDetails.size());
2013-09-17 02:43:14 +02:00
2013-11-19 07:14:06 +01:00
for ( ; ( unsigned int ) crcWorldFrameDetails . size ( ) - MAX_FRAME_CACHE > 0 ; ) {
2013-09-17 02:43:14 +02:00
crcWorldFrameDetails . erase ( crcWorldFrameDetails . begin ( ) ) ;
}
}
}
string Faction : : getCRC_DetailsForWorldFrame ( int worldFrameCount ) {
if ( crcWorldFrameDetails . empty ( ) ) {
return " " ;
}
return crcWorldFrameDetails [ worldFrameCount ] ;
}
2013-09-19 03:19:36 +02:00
std : : pair < int , string > Faction : : getCRC_DetailsForWorldFrameIndex ( int worldFrameIndex ) const {
2013-09-17 02:43:14 +02:00
if ( crcWorldFrameDetails . empty ( ) ) {
return make_pair < int , string > ( 0 , " " ) ;
}
2013-09-19 03:19:36 +02:00
std : : map < int , string > : : const_iterator iterMap = crcWorldFrameDetails . begin ( ) ;
2013-09-17 02:43:14 +02:00
std : : advance ( iterMap , worldFrameIndex ) ;
2013-09-19 03:19:36 +02:00
if ( iterMap = = crcWorldFrameDetails . end ( ) ) {
return make_pair < int , string > ( 0 , " " ) ;
}
2013-11-02 12:04:52 +01:00
return std : : pair < int , string > ( iterMap - > first , iterMap - > second ) ;
2013-09-17 02:43:14 +02:00
}
2013-09-19 03:19:36 +02:00
string Faction : : getCRC_DetailsForWorldFrames ( ) const {
2013-09-17 02:43:14 +02:00
string result = " " ;
2013-09-19 03:19:36 +02:00
for ( std : : map < int , string > : : const_iterator iterMap = crcWorldFrameDetails . begin ( ) ;
2013-09-17 02:43:14 +02:00
iterMap ! = crcWorldFrameDetails . end ( ) ; + + iterMap ) {
result + = string ( " ============================================================================ \n " ) ;
result + = string ( " ** world frame: " ) + intToStr ( iterMap - > first ) + string ( " detail: " ) + iterMap - > second ;
}
return result ;
}
2013-09-19 03:19:36 +02:00
uint64 Faction : : getCRC_DetailsForWorldFrameCount ( ) const {
2013-09-17 02:43:14 +02:00
return crcWorldFrameDetails . size ( ) ;
}
2010-03-19 19:58:46 +01:00
} } //end namespace