2011-01-20 16:56:30 +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
2011-01-20 16:56:30 +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 "tech_tree.h"
# include <cassert>
# include "util.h"
# include "resource.h"
# include "faction_type.h"
# include "logger.h"
# include "xml_parser.h"
# include "platform_util.h"
# include "game_util.h"
2011-01-20 09:19:14 +01:00
# include "window.h"
2011-01-20 16:56:30 +01:00
# include "leak_dumper.h"
using namespace Shared : : Util ;
using namespace Shared : : Xml ;
namespace Glest { namespace Game {
// =====================================================
// class TechTree
// =====================================================
2010-03-18 22:26:40 +01:00
2012-01-17 02:34:50 +01:00
TechTree : : TechTree ( const vector < string > pathList ) {
2011-11-11 05:17:55 +01:00
SkillType : : resetNextAttackBoostId ( ) ;
name = " " ;
treePath = " " ;
2012-01-17 02:34:50 +01:00
this - > pathList . assign ( pathList . begin ( ) , pathList . end ( ) ) ;
2011-11-11 05:17:55 +01:00
resourceTypes . clear ( ) ;
factionTypes . clear ( ) ;
armorTypes . clear ( ) ;
attackTypes . clear ( ) ;
2013-06-13 03:37:15 +02:00
translatedTechNames . clear ( ) ;
2013-06-13 10:55:48 +02:00
translatedTechFactionNames . clear ( ) ;
2013-10-29 22:13:44 +01:00
languageUsedForCache = " " ;
2013-11-04 08:21:04 +01:00
isValidationModeEnabled = false ;
2011-11-11 05:17:55 +01:00
}
2013-10-29 22:13:44 +01:00
string TechTree : : getNameUntranslated ( ) const {
return name ;
}
string TechTree : : getName ( bool translatedValue ) {
if ( translatedValue = = false ) {
return getNameUntranslated ( ) ;
}
2013-06-13 00:49:47 +02:00
2013-10-31 21:12:49 +01:00
bool foundTranslation = false ;
2013-06-13 00:49:47 +02:00
Lang & lang = Lang : : getInstance ( ) ;
2013-10-29 22:13:44 +01:00
if ( lang . getTechNameLoaded ( ) ! = name | |
lang . getLanguage ( ) ! = languageUsedForCache ) {
2013-10-29 21:24:23 +01:00
//printf("Line: %d Tech [%s]\n",__LINE__,name.c_str());
2013-10-31 21:12:49 +01:00
foundTranslation = lang . loadTechTreeStrings ( name , lang . getLanguage ( ) ! = languageUsedForCache ) ;
2013-10-29 22:13:44 +01:00
languageUsedForCache = lang . getLanguage ( ) ;
translatedTechFactionNames . erase ( name ) ;
2013-10-31 15:09:27 +01:00
translatedTechNames . erase ( name ) ;
2013-10-29 21:24:23 +01:00
}
2013-10-31 21:12:49 +01:00
string result = name ;
if ( foundTranslation = = true ) {
result = lang . getTechTreeString ( " TechTreeName " , name . c_str ( ) ) ;
}
2013-11-03 22:38:39 +01:00
else {
result = formatString ( result ) ;
}
2013-10-31 19:32:26 +01:00
//printf("Line: %d Tech [%s] result [%s]\n",__LINE__,name.c_str(),result.c_str());
return result ;
2013-06-13 00:49:47 +02:00
}
2013-06-13 10:55:48 +02:00
string TechTree : : getTranslatedName ( string techName , bool forceLoad , bool forceTechtreeActiveFile ) {
2013-06-13 03:37:15 +02:00
string result = techName ;
2013-10-29 21:24:23 +01:00
//printf("Line: %d Tech [%s] forceLoad = %d forceTechtreeActiveFile = %d\n",__LINE__,techName.c_str(),forceLoad,forceTechtreeActiveFile);
2013-10-29 22:13:44 +01:00
Lang & lang = Lang : : getInstance ( ) ;
2013-06-13 10:55:48 +02:00
if ( forceTechtreeActiveFile = = false & &
2013-10-29 22:13:44 +01:00
translatedTechNames . find ( techName ) ! = translatedTechNames . end ( ) & &
2013-10-31 19:32:26 +01:00
lang . getLanguage ( ) = = languageUsedForCache ) {
2013-06-13 03:37:15 +02:00
result = translatedTechNames [ techName ] ;
}
else {
name = " " ;
string path = findPath ( techName ) ;
if ( path ! = " " ) {
string currentPath = path ;
endPathWithSlash ( currentPath ) ;
treePath = currentPath ;
name = lastDir ( currentPath ) ;
2013-10-29 22:13:44 +01:00
lang . loadTechTreeStrings ( name , lang . getLanguage ( ) ! = languageUsedForCache ) ;
languageUsedForCache = lang . getLanguage ( ) ;
2013-06-13 03:37:15 +02:00
2013-10-31 15:09:27 +01:00
translatedTechFactionNames . erase ( techName ) ;
translatedTechNames . erase ( techName ) ;
2013-10-29 21:24:23 +01:00
2013-06-13 03:37:15 +02:00
result = getName ( true ) ;
2013-10-31 21:12:49 +01:00
//printf("techName [%s] name [%s] result [%s]\n",techName.c_str(),name.c_str(),result.c_str());
2013-10-31 20:45:03 +01:00
translatedTechNames [ name ] = result ;
2013-06-13 03:37:15 +02:00
}
}
return result ;
}
2013-06-13 10:55:48 +02:00
string TechTree : : getTranslatedFactionName ( string techName , string factionName ) {
2013-10-29 21:24:23 +01:00
//printf("Line: %d Tech [%s] name [%s] factionName [%s]\n",__LINE__,techName.c_str(),name.c_str(),factionName.c_str());
Lang & lang = Lang : : getInstance ( ) ;
2013-10-29 22:13:44 +01:00
if ( lang . getTechNameLoaded ( ) ! = techName | |
lang . getLanguage ( ) ! = languageUsedForCache ) {
2013-10-29 21:24:23 +01:00
//printf("Line: %d Tech [%s] name [%s] lang.getTechNameLoaded() [%s] factionName [%s]\n",__LINE__,techName.c_str(),name.c_str(),lang.getTechNameLoaded().c_str(),factionName.c_str());
2013-10-29 22:13:44 +01:00
lang . loadTechTreeStrings ( techName , lang . getLanguage ( ) ! = languageUsedForCache ) ;
languageUsedForCache = lang . getLanguage ( ) ;
2013-10-29 21:24:23 +01:00
translatedTechFactionNames . erase ( techName ) ;
}
2013-06-13 10:55:48 +02:00
std : : map < string , std : : map < string , string > > : : iterator iterMap = translatedTechFactionNames . find ( techName ) ;
if ( iterMap ! = translatedTechFactionNames . end ( ) ) {
if ( iterMap - > second . find ( factionName ) ! = iterMap - > second . end ( ) ) {
2013-10-29 21:24:23 +01:00
//printf("Line: %d Tech [%s] factionName [%s]\n",__LINE__,techName.c_str(),factionName.c_str());
2013-06-13 10:55:48 +02:00
return iterMap - > second . find ( factionName ) - > second ;
}
}
2013-10-29 21:24:23 +01:00
//printf("Line: %d Tech [%s] factionName [%s]\n",__LINE__,techName.c_str(),factionName.c_str());
2013-06-13 10:55:48 +02:00
getTranslatedName ( techName , false , true ) ;
2013-10-29 21:24:23 +01:00
2013-11-03 22:38:39 +01:00
string result = lang . getTechTreeString ( " FactionName_ " + factionName , formatString ( factionName ) . c_str ( ) ) ;
2013-11-03 22:55:50 +01:00
//printf(">>result = %s\n",result.c_str());
2013-06-13 10:55:48 +02:00
translatedTechFactionNames [ techName ] [ factionName ] = result ;
2013-10-29 21:24:23 +01:00
//printf("Line: %d Translated faction for Tech [%s] faction [%s] result [%s]\n",__LINE__,techName.c_str(),factionName.c_str(),result.c_str());
2013-06-13 10:55:48 +02:00
return result ;
}
2012-01-17 02:34:50 +01:00
Checksum TechTree : : loadTech ( const string & techName ,
2013-11-04 08:21:04 +01:00
set < string > & factions , Checksum * checksum ,
std : : map < string , vector < pair < string , string > > > & loadedFileList ,
bool validationMode ) {
2011-05-07 00:12:16 +02:00
name = " " ;
2013-11-04 08:21:04 +01:00
isValidationModeEnabled = validationMode ;
2011-01-09 05:49:21 +01:00
Checksum techtreeChecksum ;
2012-01-17 02:34:50 +01:00
string path = findPath ( techName ) ;
2012-04-02 17:17:31 +02:00
if ( path ! = " " ) {
2012-01-28 15:41:46 +01:00
//printf(">>> path=%s\n",path.c_str());
2013-11-04 08:21:04 +01:00
load ( path , factions , checksum , & techtreeChecksum , loadedFileList ,
validationMode ) ;
2012-01-17 02:34:50 +01:00
}
2012-04-02 17:17:31 +02:00
else {
printf ( " >>> techtree [%s] path not found. \n " , techName . c_str ( ) ) ;
2012-01-17 02:34:50 +01:00
}
return techtreeChecksum ;
}
2013-11-24 05:44:12 +01:00
bool TechTree : : exists ( const string & techName , const vector < string > & pathTechList ) {
bool techFound = false ;
std : : auto_ptr < TechTree > techTree ( new TechTree ( pathTechList ) ) ;
string path = techTree - > findPath ( techName ) ;
if ( path ! = " " ) {
techFound = true ;
}
return techFound ;
}
2012-10-16 21:07:50 +02:00
string TechTree : : findPath ( const string & techName ) const {
return findPath ( techName , pathList ) ;
}
string TechTree : : findPath ( const string & techName , const vector < string > & pathTechList ) {
for ( unsigned int idx = 0 ; idx < pathTechList . size ( ) ; + + idx ) {
string currentPath = ( pathTechList ) [ idx ] ;
2011-03-13 09:23:43 +01:00
endPathWithSlash ( currentPath ) ;
string path = currentPath + techName ;
2012-01-17 02:34:50 +01:00
2012-01-28 15:41:46 +01:00
//printf(">>> test path=%s\n",path.c_str());
2010-03-18 22:26:40 +01:00
if ( isdir ( path . c_str ( ) ) = = true ) {
2012-01-17 02:34:50 +01:00
return path ;
2012-04-16 21:29:37 +02:00
//break;
2010-03-18 22:26:40 +01:00
}
}
2012-01-17 02:34:50 +01:00
//return "no path found for tech: \""+techname+"\"";
return " " ;
2010-03-18 22:26:40 +01:00
}
2011-01-20 16:56:30 +01:00
2012-01-17 02:34:50 +01:00
2011-03-15 16:30:28 +01:00
void TechTree : : load ( const string & dir , set < string > & factions , Checksum * checksum ,
2013-11-04 08:21:04 +01:00
Checksum * techtreeChecksum ,
std : : map < string , vector < pair < string , string > > > & loadedFileList ,
bool validationMode ) {
2012-11-11 00:19:42 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-20 16:56:30 +01:00
2011-03-15 16:30:28 +01:00
string currentPath = dir ;
endPathWithSlash ( currentPath ) ;
2011-05-07 00:12:16 +02:00
treePath = currentPath ;
name = lastDir ( currentPath ) ;
2011-03-15 16:30:28 +01:00
2013-06-13 00:49:47 +02:00
Lang & lang = Lang : : getInstance ( ) ;
2013-06-13 03:37:15 +02:00
lang . loadTechTreeStrings ( name , true ) ;
2013-10-29 22:13:44 +01:00
languageUsedForCache = lang . getLanguage ( ) ;
2013-06-13 00:49:47 +02:00
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-10-29 07:13:38 +01:00
snprintf ( szBuf , 8096 , Lang : : getInstance ( ) . getString ( " LogScreenGameLoadingTechtree " , " " , true ) . c_str ( ) , formatString ( getName ( true ) ) . c_str ( ) ) ;
2011-11-02 18:17:28 +01:00
Logger : : getInstance ( ) . add ( szBuf , true ) ;
2011-01-20 16:56:30 +01:00
2011-11-02 18:17:28 +01:00
vector < string > filenames ;
2011-01-20 16:56:30 +01:00
//load resources
2011-03-15 16:30:28 +01:00
string str = currentPath + " resources/*. " ;
2011-01-20 16:56:30 +01:00
2011-03-15 16:30:28 +01:00
try {
2011-01-20 16:56:30 +01:00
findAll ( str , filenames ) ;
resourceTypes . resize ( filenames . size ( ) ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) filenames . size ( ) ; + + i ) {
2011-03-15 16:30:28 +01:00
str = currentPath + " resources/ " + filenames [ i ] ;
2011-05-07 00:12:16 +02:00
resourceTypes [ i ] . load ( str , checksum , & checksumValue , loadedFileList ,
treePath ) ;
2011-01-20 16:56:30 +01:00
Window : : handleEvent ( ) ;
SDL_PumpEvents ( ) ;
}
// Cleanup pixmap memory
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) filenames . size ( ) ; + + i ) {
2011-01-20 16:56:30 +01:00
resourceTypes [ i ] . deletePixels ( ) ;
}
}
catch ( const exception & e ) {
2012-11-11 00:19:42 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , e . what ( ) ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Error loading Resource Types in: [ " + currentPath + " ] \n " + e . what ( ) , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
// give CPU time to update other things to avoid apperance of hanging
sleep ( 0 ) ;
Window : : handleEvent ( ) ;
SDL_PumpEvents ( ) ;
//load tech tree xml info
2011-03-15 16:30:28 +01:00
try {
2011-01-20 16:56:30 +01:00
XmlTree xmlTree ;
2011-03-13 09:23:43 +01:00
string currentPath = dir ;
endPathWithSlash ( currentPath ) ;
string path = currentPath + lastDir ( dir ) + " .xml " ;
2011-01-20 16:56:30 +01:00
2011-01-09 05:49:21 +01:00
checksum - > addFile ( path ) ;
2011-01-20 16:56:30 +01:00
checksumValue . addFile ( path ) ;
2011-05-07 00:12:16 +02:00
std : : map < string , string > mapExtraTagReplacementValues ;
mapExtraTagReplacementValues [ " $COMMONDATAPATH " ] = currentPath + " /commondata/ " ;
xmlTree . load ( path , Properties : : getTagReplacementValues ( & mapExtraTagReplacementValues ) ) ;
2011-05-06 09:47:31 +02:00
loadedFileList [ path ] . push_back ( make_pair ( currentPath , currentPath ) ) ;
2011-03-15 16:30:28 +01:00
2013-05-28 04:54:23 +02:00
Properties : : setTechtreePath ( currentPath ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " ==> Set techtree path to [%s] \n " , currentPath . c_str ( ) ) ;
2011-01-20 16:56:30 +01:00
const XmlNode * techTreeNode = xmlTree . getRootNode ( ) ;
//attack types
const XmlNode * attackTypesNode = techTreeNode - > getChild ( " attack-types " ) ;
attackTypes . resize ( attackTypesNode - > getChildCount ( ) ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) attackTypes . size ( ) ; + + i ) {
2011-01-20 16:56:30 +01:00
const XmlNode * attackTypeNode = attackTypesNode - > getChild ( " attack-type " , i ) ;
attackTypes [ i ] . setName ( attackTypeNode - > getAttribute ( " name " ) - > getRestrictedValue ( ) ) ;
attackTypes [ i ] . setId ( i ) ;
2011-03-15 16:30:28 +01:00
2011-01-20 16:56:30 +01:00
Window : : handleEvent ( ) ;
SDL_PumpEvents ( ) ;
}
// give CPU time to update other things to avoid apperance of hanging
sleep ( 0 ) ;
//SDL_PumpEvents();
//armor types
const XmlNode * armorTypesNode = techTreeNode - > getChild ( " armor-types " ) ;
armorTypes . resize ( armorTypesNode - > getChildCount ( ) ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) armorTypes . size ( ) ; + + i ) {
2011-01-20 16:56:30 +01:00
const XmlNode * armorTypeNode = armorTypesNode - > getChild ( " armor-type " , i ) ;
armorTypes [ i ] . setName ( armorTypeNode - > getAttribute ( " name " ) - > getRestrictedValue ( ) ) ;
armorTypes [ i ] . setId ( i ) ;
2011-03-15 16:30:28 +01:00
2011-01-20 16:56:30 +01:00
Window : : handleEvent ( ) ;
SDL_PumpEvents ( ) ;
}
//damage multipliers
2013-11-02 12:04:52 +01:00
damageMultiplierTable . init ( ( int ) attackTypes . size ( ) , ( int ) armorTypes . size ( ) ) ;
2011-01-20 16:56:30 +01:00
const XmlNode * damageMultipliersNode = techTreeNode - > getChild ( " damage-multipliers " ) ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) damageMultipliersNode - > getChildCount ( ) ; + + i ) {
2011-01-20 16:56:30 +01:00
const XmlNode * damageMultiplierNode = damageMultipliersNode - > getChild ( " damage-multiplier " , i ) ;
const AttackType * attackType = getAttackType ( damageMultiplierNode - > getAttribute ( " attack " ) - > getRestrictedValue ( ) ) ;
const ArmorType * armorType = getArmorType ( damageMultiplierNode - > getAttribute ( " armor " ) - > getRestrictedValue ( ) ) ;
2013-09-23 19:16:34 +02:00
double multiplier = damageMultiplierNode - > getAttribute ( " value " ) - > getFloatValue ( ) ;
2011-01-20 16:56:30 +01:00
damageMultiplierTable . setDamageMultiplier ( attackType , armorType , multiplier ) ;
2011-03-15 16:30:28 +01:00
2011-01-20 16:56:30 +01:00
Window : : handleEvent ( ) ;
SDL_PumpEvents ( ) ;
}
}
catch ( const exception & e ) {
2012-11-11 00:19:42 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , e . what ( ) ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Error loading Tech Tree: " + currentPath + " \n " + e . what ( ) , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
// give CPU time to update other things to avoid apperance of hanging
sleep ( 0 ) ;
//SDL_PumpEvents();
//load factions
try {
factionTypes . resize ( factions . size ( ) ) ;
int i = 0 ;
for ( set < string > : : iterator it = factions . begin ( ) ; it ! = factions . end ( ) ; + + it ) {
string factionName = * it ;
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-10-29 07:13:38 +01:00
snprintf ( szBuf , 8096 , " %s %s [%d / %d] - %s " , Lang : : getInstance ( ) . getString ( " Loading " ) . c_str ( ) ,
Lang : : getInstance ( ) . getString ( " Faction " ) . c_str ( ) ,
2011-03-15 16:30:28 +01:00
i + 1 ,
( int ) factions . size ( ) ,
2013-06-16 03:14:04 +02:00
formatString ( this - > getTranslatedFactionName ( name , factionName ) ) . c_str ( ) ) ;
2011-01-20 16:56:30 +01:00
Logger & logger = Logger : : getInstance ( ) ;
2011-01-09 11:03:33 +01:00
logger . setState ( szBuf ) ;
2011-01-20 16:56:30 +01:00
logger . setProgress ( ( int ) ( ( ( ( double ) i ) / ( double ) factions . size ( ) ) * 100.0 ) ) ;
2013-11-04 08:21:04 +01:00
factionTypes [ i + + ] . load ( factionName , this , checksum , & checksumValue ,
loadedFileList , validationMode ) ;
2011-01-20 16:56:30 +01:00
// give CPU time to update other things to avoid apperance of hanging
sleep ( 0 ) ;
Window : : handleEvent ( ) ;
SDL_PumpEvents ( ) ;
}
2012-11-11 00:19:42 +01:00
}
catch ( megaglest_runtime_error & ex ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Error loading Faction Types: " + currentPath + " \n Message: " + ex . what ( ) , ! ex . wantStackTrace ( ) | | isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
catch ( const exception & e ) {
2012-11-11 00:19:42 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , e . what ( ) ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Error loading Faction Types: " + currentPath + " \n Message: " + e . what ( ) , isValidationModeEnabled ) ;
2011-01-09 05:49:21 +01:00
}
if ( techtreeChecksum ! = NULL ) {
* techtreeChecksum = checksumValue ;
}
2011-01-20 16:56:30 +01:00
2012-11-11 00:19:42 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2011-01-20 16:56:30 +01:00
}
TechTree : : ~ TechTree ( ) {
2012-11-11 00:19:42 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-10-29 07:13:38 +01:00
Logger : : getInstance ( ) . add ( Lang : : getInstance ( ) . getString ( " LogScreenGameUnLoadingTechtree " , " " , true ) , true ) ;
2012-05-24 09:08:31 +02:00
resourceTypes . clear ( ) ;
factionTypes . clear ( ) ;
armorTypes . clear ( ) ;
attackTypes . clear ( ) ;
2011-01-20 16:56:30 +01:00
}
std : : vector < std : : string > TechTree : : validateFactionTypes ( ) {
std : : vector < std : : string > results ;
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) factionTypes . size ( ) ; + + i ) {
2011-01-20 16:56:30 +01:00
std : : vector < std : : string > factionResults = factionTypes [ i ] . validateFactionType ( ) ;
2011-09-01 20:08:56 +02:00
if ( factionResults . empty ( ) = = false ) {
2011-04-06 20:03:22 +02:00
results . insert ( results . end ( ) , factionResults . begin ( ) , factionResults . end ( ) ) ;
}
2011-01-20 16:56:30 +01:00
factionResults = factionTypes [ i ] . validateFactionTypeUpgradeTypes ( ) ;
2011-09-01 20:08:56 +02:00
if ( factionResults . empty ( ) = = false ) {
2011-04-06 20:03:22 +02:00
results . insert ( results . end ( ) , factionResults . begin ( ) , factionResults . end ( ) ) ;
}
2011-01-20 16:56:30 +01:00
}
return results ;
}
std : : vector < std : : string > TechTree : : validateResourceTypes ( ) {
std : : vector < std : : string > results ;
2011-04-06 19:50:20 +02:00
ResourceTypes resourceTypesNotUsed = resourceTypes ;
2012-05-24 09:08:31 +02:00
for ( unsigned int i = 0 ; i < resourceTypesNotUsed . size ( ) ; + + i ) {
ResourceType & rt = resourceTypesNotUsed [ i ] ;
rt . setCleanupMemory ( false ) ;
}
2011-04-06 19:50:20 +02:00
for ( unsigned int i = 0 ; i < factionTypes . size ( ) ; + + i ) {
//printf("Validating [%d / %d] faction [%s]\n",i,(int)factionTypes.size(),factionTypes[i].getName().c_str());
2011-01-20 16:56:30 +01:00
std : : vector < std : : string > factionResults = factionTypes [ i ] . validateFactionTypeResourceTypes ( resourceTypes ) ;
2011-09-01 20:08:56 +02:00
if ( factionResults . empty ( ) = = false ) {
2011-04-06 19:50:20 +02:00
results . insert ( results . end ( ) , factionResults . begin ( ) , factionResults . end ( ) ) ;
}
// Check if the faction uses the resources in this techtree
// Now lets find a matching faction resource type for the unit
2013-11-02 12:04:52 +01:00
for ( int j = ( int ) resourceTypesNotUsed . size ( ) - 1 ; j > = 0 ; - - j ) {
2011-04-06 19:50:20 +02:00
const ResourceType & rt = resourceTypesNotUsed [ j ] ;
//printf("Validating [%d / %d] resourcetype [%s]\n",j,(int)resourceTypesNotUsed.size(),rt.getName().c_str());
if ( factionTypes [ i ] . factionUsesResourceType ( & rt ) = = true ) {
//printf("FOUND FACTION CONSUMER FOR RESOURCE - [%d / %d] faction [%s] resource [%d / %d] resourcetype [%s]\n",i,(int)factionTypes.size(),factionTypes[i].getName().c_str(),j,(int)resourceTypesNotUsed.size(),rt.getName().c_str());
resourceTypesNotUsed . erase ( resourceTypesNotUsed . begin ( ) + j ) ;
}
}
}
2011-09-01 20:08:56 +02:00
if ( resourceTypesNotUsed . empty ( ) = = false ) {
2011-04-06 19:50:20 +02:00
//printf("FOUND unused resource Types [%d]\n",(int)resourceTypesNotUsed.size());
for ( unsigned int i = 0 ; i < resourceTypesNotUsed . size ( ) ; + + i ) {
const ResourceType & rt = resourceTypesNotUsed [ i ] ;
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " The Resource type [%s] is not used by any units in this techtree! " , rt . getName ( ) . c_str ( ) ) ;
2011-04-06 19:50:20 +02:00
results . push_back ( szBuf ) ;
}
2011-01-20 16:56:30 +01:00
}
return results ;
}
// ==================== get ====================
FactionType * TechTree : : getTypeByName ( const string & name ) {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) factionTypes . size ( ) ; + + i ) {
2013-06-13 03:37:15 +02:00
if ( factionTypes [ i ] . getName ( false ) = = name ) {
2011-01-20 16:56:30 +01:00
return & factionTypes [ i ] ;
}
}
2012-11-11 00:19:42 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Faction not found: " + name , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
const FactionType * TechTree : : getType ( const string & name ) const {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) factionTypes . size ( ) ; + + i ) {
2013-06-13 03:37:15 +02:00
if ( factionTypes [ i ] . getName ( false ) = = name ) {
2011-01-20 16:56:30 +01:00
return & factionTypes [ i ] ;
}
}
2012-11-11 00:19:42 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Faction not found: " + name , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
const ResourceType * TechTree : : getTechResourceType ( int i ) const {
for ( int j = 0 ; j < getResourceTypeCount ( ) ; + + j ) {
const ResourceType * rt = getResourceType ( j ) ;
assert ( rt ! = NULL ) ;
if ( rt = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " rt == NULL " ) ;
2011-01-20 16:56:30 +01:00
}
if ( rt - > getResourceNumber ( ) = = i & & rt - > getClass ( ) = = rcTech )
return getResourceType ( j ) ;
}
return getFirstTechResourceType ( ) ;
}
const ResourceType * TechTree : : getFirstTechResourceType ( ) const {
for ( int i = 0 ; i < getResourceTypeCount ( ) ; + + i ) {
const ResourceType * rt = getResourceType ( i ) ;
assert ( rt ! = NULL ) ;
if ( rt - > getResourceNumber ( ) = = 1 & & rt - > getClass ( ) = = rcTech )
return getResourceType ( i ) ;
}
2012-07-20 17:31:56 +02:00
char szBuf [ 8096 ] = " " ;
2012-10-19 03:31:20 +02:00
snprintf ( szBuf , 8096 , " The referenced tech tree [%s] is either missing or has no resources defined but at least one resource is required. " , this - > name . c_str ( ) ) ;
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( szBuf , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
const ResourceType * TechTree : : getResourceType ( const string & name ) const {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) resourceTypes . size ( ) ; + + i ) {
2011-01-20 16:56:30 +01:00
if ( resourceTypes [ i ] . getName ( ) = = name ) {
return & resourceTypes [ i ] ;
}
}
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Resource Type not found: " + name , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
const ArmorType * TechTree : : getArmorType ( const string & name ) const {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) armorTypes . size ( ) ; + + i ) {
2013-06-13 10:55:48 +02:00
if ( armorTypes [ i ] . getName ( false ) = = name ) {
2011-01-20 16:56:30 +01:00
return & armorTypes [ i ] ;
}
}
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Armor Type not found: " + name , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
const AttackType * TechTree : : getAttackType ( const string & name ) const {
2013-11-19 07:14:06 +01:00
for ( int i = 0 ; i < ( int ) attackTypes . size ( ) ; + + i ) {
2013-06-13 10:55:48 +02:00
if ( attackTypes [ i ] . getName ( false ) = = name ) {
2011-01-20 16:56:30 +01:00
return & attackTypes [ i ] ;
}
}
2013-11-04 08:21:04 +01:00
throw megaglest_runtime_error ( " Attack Type not found: " + name , isValidationModeEnabled ) ;
2011-01-20 16:56:30 +01:00
}
2013-09-23 19:16:34 +02:00
double TechTree : : getDamageMultiplier ( const AttackType * att , const ArmorType * art ) const {
2011-01-20 16:56:30 +01:00
return damageMultiplierTable . getDamageMultiplier ( att , art ) ;
}
2012-03-10 04:27:25 +01:00
void TechTree : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * techTreeNode = rootNode - > addChild ( " TechTree " ) ;
// string name;
techTreeNode - > addAttribute ( " name " , name , mapTagReplacements ) ;
// //string desc;
// string treePath;
2012-03-13 00:08:22 +01:00
//techTreeNode->addAttribute("treePath",treePath, mapTagReplacements);
2012-03-10 04:27:25 +01:00
// vector<string> pathList;
2012-03-13 00:08:22 +01:00
// for(unsigned int i = 0; i < pathList.size(); ++i) {
// XmlNode *pathListNode = techTreeNode->addChild("pathList");
// pathListNode->addAttribute("value",pathList[i], mapTagReplacements);
// }
2012-03-10 04:27:25 +01:00
// ResourceTypes resourceTypes;
2012-03-13 00:08:22 +01:00
// for(unsigned int i = 0; i < resourceTypes.size(); ++i) {
// ResourceType &rt = resourceTypes[i];
// rt.saveGame(techTreeNode);
// }
2012-03-10 04:27:25 +01:00
// FactionTypes factionTypes;
2012-03-13 00:08:22 +01:00
// for(unsigned int i = 0; i < factionTypes.size(); ++i) {
// FactionType &ft = factionTypes[i];
// ft.saveGame(techTreeNode);
// }
2012-03-10 04:27:25 +01:00
// ArmorTypes armorTypes;
2012-03-13 00:08:22 +01:00
// for(unsigned int i = 0; i < armorTypes.size(); ++i) {
// ArmorType &at = armorTypes[i];
// at.saveGame(techTreeNode);
// }
2012-03-10 04:27:25 +01:00
// AttackTypes attackTypes;
2012-03-13 00:08:22 +01:00
// for(unsigned int i = 0; i < attackTypes.size(); ++i) {
// AttackType &at = attackTypes[i];
// at.saveGame(techTreeNode);
// }
2012-03-10 04:27:25 +01:00
// DamageMultiplierTable damageMultiplierTable;
2012-03-13 00:08:22 +01:00
// damageMultiplierTable.saveGame(techTreeNode);
2012-03-10 04:27:25 +01:00
// Checksum checksumValue;
techTreeNode - > addAttribute ( " checksumValue " , intToStr ( checksumValue . getSum ( ) ) , mapTagReplacements ) ;
}
2011-01-20 16:56:30 +01:00
} } //end namespace