2010-03-12 08:42:55 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2010-05-18 23:18:51 +02:00
// Copyright (C) 2001-2008 Martiño Figueroa
2010-03-12 08:42:55 +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
// ==============================================================
2012-04-20 03:04:05 +02:00
# define NOMINMAX
2012-04-21 05:42:25 +02:00
2010-03-12 08:42:55 +01:00
# include <cassert>
# include "unit.h"
# include "unit_particle_type.h"
# include "world.h"
# include "upgrade.h"
# include "map.h"
# include "command.h"
# include "object.h"
# include "config.h"
# include "skill_type.h"
# include "core_data.h"
# include "renderer.h"
2010-04-27 16:10:53 +02:00
# include "game.h"
2010-03-18 22:26:40 +01:00
# include "socket.h"
2010-12-28 03:17:44 +01:00
# include "sound_renderer.h"
2010-03-12 08:42:55 +01:00
2010-04-24 13:15:15 +02:00
# include "leak_dumper.h"
2010-03-12 08:42:55 +01:00
using namespace Shared : : Graphics ;
using namespace Shared : : Util ;
namespace Glest { namespace Game {
2011-10-28 03:22:36 +02:00
const float CHANGE_COMMAND_SPEED = 325.0 ;
2011-09-25 06:07:59 +02:00
//Mutex Unit::mutexDeletedUnits;
//map<void *,bool> Unit::deletedUnits;
2010-08-25 09:29:35 +02:00
const int UnitPathBasic : : maxBlockCount = GameConstants : : updateFps / 2 ;
2010-07-21 20:21:40 +02:00
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
std : : map < UnitPathBasic * , bool > UnitPathBasic : : mapMemoryList ;
std : : map < Unit * , bool > Unit : : mapMemoryList ;
std : : map < UnitPathInterface * , int > Unit : : mapMemoryList2 ;
# endif
2011-09-27 12:16:09 +02:00
UnitPathBasic : : UnitPathBasic ( ) : UnitPathInterface ( ) {
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
UnitPathBasic : : mapMemoryList [ this ] = true ;
# endif
2010-07-21 20:21:40 +02:00
this - > blockCount = 0 ;
this - > pathQueue . clear ( ) ;
2011-02-12 00:32:24 +01:00
this - > lastPathCacheQueue . clear ( ) ;
2011-02-23 08:03:38 +01:00
this - > map = NULL ;
2010-07-21 20:21:40 +02:00
}
2011-02-12 10:08:50 +01:00
UnitPathBasic : : ~ UnitPathBasic ( ) {
this - > blockCount = 0 ;
this - > pathQueue . clear ( ) ;
this - > lastPathCacheQueue . clear ( ) ;
2011-02-23 08:03:38 +01:00
this - > map = NULL ;
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
UnitPathBasic : : mapMemoryList . erase ( this ) ;
# endif
2011-02-12 10:08:50 +01:00
}
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
void UnitPathBasic : : dumpMemoryList ( ) {
printf ( " ===== START report of Unfreed UnitPathBasic pointers ===== \n " ) ;
for ( std : : map < UnitPathBasic * , bool > : : iterator iterMap = UnitPathBasic : : mapMemoryList . begin ( ) ;
iterMap ! = UnitPathBasic : : mapMemoryList . end ( ) ; + + iterMap ) {
printf ( " ************** ==> Unfreed UnitPathBasic pointer [%p] \n " , iterMap - > first ) ;
if ( Unit : : mapMemoryList2 . find ( iterMap - > first ) ! = Unit : : mapMemoryList2 . end ( ) ) {
printf ( " Found owner unit id [%d] \n " , Unit : : mapMemoryList2 [ iterMap - > first ] ) ;
}
}
}
# endif
2010-07-21 20:21:40 +02:00
bool UnitPathBasic : : isEmpty ( ) const {
return pathQueue . empty ( ) ;
}
bool UnitPathBasic : : isBlocked ( ) const {
return blockCount > = maxBlockCount ;
}
2010-10-17 08:34:42 +02:00
bool UnitPathBasic : : isStuck ( ) const {
return ( isBlocked ( ) = = true & & blockCount > = ( maxBlockCount * 2 ) ) ;
}
2010-07-21 20:21:40 +02:00
void UnitPathBasic : : clear ( ) {
pathQueue . clear ( ) ;
2011-02-12 00:32:24 +01:00
lastPathCacheQueue . clear ( ) ;
2010-07-21 20:21:40 +02:00
blockCount = 0 ;
}
void UnitPathBasic : : incBlockCount ( ) {
pathQueue . clear ( ) ;
2011-02-12 00:32:24 +01:00
lastPathCacheQueue . clear ( ) ;
2010-07-21 20:21:40 +02:00
blockCount + + ;
}
2011-02-23 08:03:38 +01:00
void UnitPathBasic : : add ( const Vec2i & path ) {
if ( this - > map ! = NULL ) {
if ( this - > map - > isInside ( path ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Invalid map path position = " + path . getString ( ) + " map w x h = " + intToStr ( map - > getW ( ) ) + " " + intToStr ( map - > getH ( ) ) ) ;
2011-02-23 08:03:38 +01:00
}
else if ( this - > map - > isInsideSurface ( this - > map - > toSurfCoords ( path ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Invalid map surface path position = " + path . getString ( ) + " map surface w x h = " + intToStr ( map - > getSurfaceW ( ) ) + " " + intToStr ( map - > getSurfaceH ( ) ) ) ;
2011-02-23 08:03:38 +01:00
}
}
2010-07-21 20:21:40 +02:00
pathQueue . push_back ( path ) ;
}
2011-02-12 00:32:24 +01:00
void UnitPathBasic : : addToLastPathCache ( const Vec2i & path ) {
2011-02-23 08:03:38 +01:00
if ( this - > map ! = NULL ) {
if ( this - > map - > isInside ( path ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Invalid map path position = " + path . getString ( ) + " map w x h = " + intToStr ( map - > getW ( ) ) + " " + intToStr ( map - > getH ( ) ) ) ;
2011-02-23 08:03:38 +01:00
}
else if ( this - > map - > isInsideSurface ( this - > map - > toSurfCoords ( path ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Invalid map surface path position = " + path . getString ( ) + " map surface w x h = " + intToStr ( map - > getSurfaceW ( ) ) + " " + intToStr ( map - > getSurfaceH ( ) ) ) ;
2011-02-23 08:03:38 +01:00
}
}
2011-12-02 17:07:59 +01:00
const bool tryLastPathCache = Config : : getInstance ( ) . getBool ( " EnablePathfinderCache " , " false " ) ;
if ( tryLastPathCache = = true ) {
lastPathCacheQueue . push_back ( path ) ;
}
2011-02-12 00:32:24 +01:00
}
2011-03-18 04:53:06 +01:00
Vec2i UnitPathBasic : : pop ( bool removeFrontPos ) {
2012-10-06 09:06:40 +02:00
if ( pathQueue . empty ( ) = = true ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " pathQueue.size() = " + intToStr(pathQueue.size())) ;
2011-02-23 08:03:38 +01:00
}
2010-07-21 20:21:40 +02:00
Vec2i p = pathQueue . front ( ) ;
2011-03-18 04:53:06 +01:00
if ( removeFrontPos = = true ) {
pathQueue . erase ( pathQueue . begin ( ) ) ;
}
2010-07-21 20:21:40 +02:00
return p ;
}
std : : string UnitPathBasic : : toString ( ) const {
2012-10-06 09:06:40 +02:00
std : : string result = " unit path blockCount = " + intToStr ( blockCount ) + " pathQueue size = " + intToStr ( pathQueue . size ( ) ) ;
2011-09-01 03:11:23 +02:00
for ( int idx = 0 ; idx < pathQueue . size ( ) ; + + idx ) {
2010-07-21 20:21:40 +02:00
result + = " index = " + intToStr ( idx ) + " " + pathQueue [ idx ] . getString ( ) ;
}
return result ;
}
2012-03-10 04:27:25 +01:00
void UnitPathBasic : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * unitPathBasicNode = rootNode - > addChild ( " UnitPathBasic " ) ;
// int blockCount;
unitPathBasicNode - > addAttribute ( " blockCount " , intToStr ( blockCount ) , mapTagReplacements ) ;
// vector<Vec2i> pathQueue;
for ( unsigned int i = 0 ; i < pathQueue . size ( ) ; + + i ) {
Vec2i & vec = pathQueue [ i ] ;
XmlNode * pathQueueNode = unitPathBasicNode - > addChild ( " pathQueue " ) ;
pathQueueNode - > addAttribute ( " vec " , vec . getString ( ) , mapTagReplacements ) ;
}
// vector<Vec2i> lastPathCacheQueue;
for ( unsigned int i = 0 ; i < lastPathCacheQueue . size ( ) ; + + i ) {
Vec2i & vec = lastPathCacheQueue [ i ] ;
XmlNode * lastPathCacheQueueNode = unitPathBasicNode - > addChild ( " lastPathCacheQueue " ) ;
lastPathCacheQueueNode - > addAttribute ( " vec " , vec . getString ( ) , mapTagReplacements ) ;
}
}
2010-03-12 08:42:55 +01:00
// =====================================================
// class UnitPath
// =====================================================
2011-01-20 16:56:30 +01:00
void WaypointPath : : condense ( ) {
if ( size ( ) < 2 ) {
return ;
}
iterator prev , curr ;
prev = curr = begin ( ) ;
while ( + + curr ! = end ( ) ) {
if ( prev - > dist ( * curr ) < 3.f ) {
prev = erase ( prev ) ;
} else {
+ + prev ;
}
}
}
2010-03-12 08:42:55 +01:00
2010-05-18 05:53:57 +02:00
std : : string UnitPath : : toString ( ) const {
2012-10-06 09:06:40 +02:00
std : : string result = " unit path blockCount = " + intToStr ( blockCount ) + " pathQueue size = " + intToStr ( size ( ) ) ;
2010-07-11 20:31:02 +02:00
result + = " path = " ;
for ( const_iterator it = begin ( ) ; it ! = end ( ) ; + + it ) {
result + = " [ " + intToStr ( it - > x ) + " , " + intToStr ( it - > y ) + " ] " ;
2010-05-18 05:53:57 +02:00
}
return result ;
}
2010-03-12 08:42:55 +01:00
// =====================================================
// class UnitReference
// =====================================================
UnitReference : : UnitReference ( ) {
id = - 1 ;
faction = NULL ;
}
2011-09-01 03:11:23 +02:00
UnitReference & UnitReference : : operator = ( const Unit * unit ) {
2010-03-12 08:42:55 +01:00
if ( unit = = NULL ) {
id = - 1 ;
faction = NULL ;
}
else {
id = unit - > getId ( ) ;
faction = unit - > getFaction ( ) ;
}
2011-09-01 03:11:23 +02:00
return * this ;
2010-03-12 08:42:55 +01:00
}
Unit * UnitReference : : getUnit ( ) const {
if ( faction ! = NULL ) {
return faction - > findUnit ( id ) ;
}
return NULL ;
}
2012-03-10 04:27:25 +01:00
void UnitReference : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * unitRefNode = rootNode - > addChild ( " UnitReference " ) ;
unitRefNode - > addAttribute ( " id " , intToStr ( id ) , mapTagReplacements ) ;
if ( faction ! = NULL ) {
2012-03-13 02:34:14 +01:00
unitRefNode - > addAttribute ( " factionIndex " , intToStr ( faction - > getIndex ( ) ) , mapTagReplacements ) ;
}
}
void UnitReference : : loadGame ( const XmlNode * rootNode , World * world ) {
const XmlNode * unitRefNode = rootNode - > getChild ( " UnitReference " ) ;
id = unitRefNode - > getAttribute ( " id " ) - > getIntValue ( ) ;
if ( unitRefNode - > hasAttribute ( " factionIndex " ) = = true ) {
int factionIndex = unitRefNode - > getAttribute ( " factionIndex " ) - > getIntValue ( ) ;
if ( factionIndex > = world - > getFactionCount ( ) ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " factionIndex >= world->getFactionCount() [%d] : [%d] " , factionIndex , world - > getFactionCount ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2012-03-13 02:34:14 +01:00
}
faction = world - > getFaction ( factionIndex ) ;
2012-03-10 04:27:25 +01:00
}
}
2011-07-06 07:16:25 +02:00
const bool checkMemory = false ;
static map < void * , int > memoryObjectList ;
2011-06-25 22:44:46 +02:00
UnitAttackBoostEffect : : UnitAttackBoostEffect ( ) {
2011-07-06 07:16:25 +02:00
if ( checkMemory ) {
printf ( " ++ Create UnitAttackBoostEffect [%p] before count = %d \n " , this , memoryObjectList [ this ] ) ;
memoryObjectList [ this ] + + ;
printf ( " ++ Create UnitAttackBoostEffect [%p] after count = %d \n " , this , memoryObjectList [ this ] ) ;
}
2011-06-25 22:44:46 +02:00
boost = NULL ;
source = NULL ;
ups = NULL ;
upst = NULL ;
}
UnitAttackBoostEffect : : ~ UnitAttackBoostEffect ( ) {
2011-07-06 07:16:25 +02:00
if ( checkMemory ) {
printf ( " -- Delete UnitAttackBoostEffect [%p] count = %d \n " , this , memoryObjectList [ this ] ) ;
memoryObjectList [ this ] - - ;
assert ( memoryObjectList [ this ] = = 0 ) ;
}
2011-06-25 22:44:46 +02:00
if ( ups ! = NULL ) {
2011-10-30 07:12:40 +01:00
bool particleValid = Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ups , rsGame ) ;
if ( particleValid = = true ) {
ups - > fade ( ) ;
2011-06-25 22:44:46 +02:00
2011-10-30 07:12:40 +01:00
vector < UnitParticleSystem * > particleSystemToRemove ;
particleSystemToRemove . push_back ( ups ) ;
2011-06-25 22:44:46 +02:00
2011-10-30 07:12:40 +01:00
Renderer : : getInstance ( ) . cleanupUnitParticleSystems ( particleSystemToRemove , rsGame ) ;
ups = NULL ;
}
2011-06-25 22:44:46 +02:00
}
delete upst ;
upst = NULL ;
}
2012-03-10 04:27:25 +01:00
void UnitAttackBoostEffect : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * unitAttackBoostEffectNode = rootNode - > addChild ( " UnitAttackBoostEffect " ) ;
// const AttackBoost *boost;
if ( boost ! = NULL ) {
boost - > saveGame ( unitAttackBoostEffectNode ) ;
}
// const Unit *source;
if ( source ! = NULL ) {
unitAttackBoostEffectNode - > addAttribute ( " source " , intToStr ( source - > getId ( ) ) , mapTagReplacements ) ;
}
// UnitParticleSystem *ups;
2012-03-14 00:18:09 +01:00
if ( ups ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ups , rsGame ) = = true ) {
2012-03-10 04:27:25 +01:00
ups - > saveGame ( unitAttackBoostEffectNode ) ;
}
// UnitParticleSystemType *upst;
if ( upst ! = NULL ) {
upst - > saveGame ( unitAttackBoostEffectNode ) ;
}
}
2011-06-25 22:44:46 +02:00
UnitAttackBoostEffectOriginator : : UnitAttackBoostEffectOriginator ( ) {
skillType = NULL ;
currentAppliedEffect = NULL ;
}
UnitAttackBoostEffectOriginator : : ~ UnitAttackBoostEffectOriginator ( ) {
delete currentAppliedEffect ;
currentAppliedEffect = NULL ;
}
2012-03-10 04:27:25 +01:00
void UnitAttackBoostEffectOriginator : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * unitAttackBoostEffectOriginatorNode = rootNode - > addChild ( " UnitAttackBoostEffectOriginator " ) ;
// const SkillType *skillType;
if ( skillType ! = NULL ) {
unitAttackBoostEffectOriginatorNode - > addAttribute ( " skillType " , skillType - > getName ( ) , mapTagReplacements ) ;
}
// std::vector<int> currentAttackBoostUnits;
for ( unsigned int i = 0 ; i < currentAttackBoostUnits . size ( ) ; + + i ) {
XmlNode * currentAttackBoostUnitsNode = unitAttackBoostEffectOriginatorNode - > addChild ( " currentAttackBoostUnits " ) ;
currentAttackBoostUnitsNode - > addAttribute ( " value " , intToStr ( currentAttackBoostUnits [ i ] ) , mapTagReplacements ) ;
}
// UnitAttackBoostEffect *currentAppliedEffect;
if ( currentAppliedEffect ! = NULL ) {
currentAppliedEffect - > saveGame ( unitAttackBoostEffectOriginatorNode ) ;
}
}
2011-06-25 22:44:46 +02:00
2010-03-12 08:42:55 +01:00
// =====================================================
// class Unit
// =====================================================
const float Unit : : speedDivider = 100.f ;
2010-04-18 09:35:48 +02:00
const int Unit : : maxDeadCount = 1000 ; //time in until the corpse disapears - should be about 40 seconds
2010-03-12 08:42:55 +01:00
const int Unit : : invalidId = - 1 ;
2011-09-27 19:15:56 +02:00
//set<int> Unit::livingUnits;
//set<Unit*> Unit::livingUnitsp;
2010-04-18 09:35:48 +02:00
2010-03-12 08:42:55 +01:00
// ============================ Constructor & destructor =============================
2010-09-09 03:44:25 +02:00
Game * Unit : : game = NULL ;
2011-12-13 02:30:52 +01:00
Unit : : Unit ( int id , UnitPathInterface * unitpath , const Vec2i & pos ,
const UnitType * type , Faction * faction , Map * map , CardinalDir placeFacing ) : BaseColorPickEntity ( ) , id ( id ) {
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
Unit : : mapMemoryList [ this ] = true ;
# endif
2011-12-02 17:07:59 +01:00
mutexCommands = new Mutex ( ) ;
2011-10-28 02:22:03 +02:00
changedActiveCommand = false ;
2011-09-27 12:16:09 +02:00
lastSynchDataString = " " ;
2010-03-25 13:15:10 +01:00
modelFacing = CardinalDir : : NORTH ;
2011-04-04 06:32:01 +02:00
lastStuckFrame = 0 ;
lastStuckPos = Vec2i ( 0 , 0 ) ;
2011-04-14 04:51:13 +02:00
lastPathfindFailedFrame = 0 ;
lastPathfindFailedPos = Vec2i ( 0 , 0 ) ;
usePathfinderExtendedMaxNodes = false ;
2011-07-06 07:16:25 +02:00
this - > currentAttackBoostOriginatorEffect . skillType = NULL ;
2011-11-16 22:38:12 +01:00
lastAttackerUnitId = - 1 ;
lastAttackedUnitId = - 1 ;
causeOfDeath = ucodNone ;
2012-04-29 06:45:51 +02:00
pathfindFailedConsecutiveFrameCount = 0 ;
2011-04-14 04:51:13 +02:00
2011-07-12 03:48:14 +02:00
targetRotationZ = .0f ;
targetRotationX = .0f ;
rotationZ = .0f ;
rotationX = .0f ;
2011-07-12 01:59:16 +02:00
2011-09-28 08:57:42 +02:00
this - > unitPath = unitpath ;
this - > unitPath - > setMap ( map ) ;
2011-07-12 01:59:16 +02:00
2012-05-12 03:06:55 +02:00
//RandomGen random;
random . init ( id ) ;
pathFindRefreshCellCount = random . randRange ( 10 , 20 ) ;
2010-03-12 08:42:55 +01:00
2011-02-23 08:03:38 +01:00
if ( map - > isInside ( pos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( pos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #2 Invalid path position = " + pos . getString ( ) ) ;
2011-02-23 08:03:38 +01:00
}
2010-03-12 08:42:55 +01:00
this - > pos = pos ;
this - > type = type ;
this - > faction = faction ;
this - > map = map ;
2010-06-02 10:03:56 +02:00
this - > targetRef = NULL ;
2010-06-08 09:40:32 +02:00
this - > targetField = fLand ;
this - > targetVec = Vec3f ( 0.0 ) ;
this - > targetPos = Vec2i ( 0 ) ;
2010-06-15 18:27:52 +02:00
this - > lastRenderFrame = 0 ;
this - > visible = true ;
2010-08-28 03:46:26 +02:00
this - > retryCurrCommandCount = 0 ;
2010-09-07 20:28:09 +02:00
this - > screenPos = Vec3f ( 0.0 ) ;
2011-01-29 13:42:18 +01:00
this - > ignoreCheckCommand = false ;
2010-10-17 08:34:42 +02:00
this - > inBailOutAttempt = false ;
2010-10-17 10:50:27 +02:00
this - > lastHarvestResourceTarget . first = Vec2i ( 0 ) ;
2012-09-22 01:45:59 +02:00
this - > morphFieldsBlocked = false ;
2010-12-01 00:32:39 +01:00
//this->lastBadHarvestListPurge = 0;
2010-06-08 09:40:32 +02:00
2010-03-12 08:42:55 +01:00
level = NULL ;
2010-05-18 05:53:57 +02:00
loadType = NULL ;
2010-03-12 08:42:55 +01:00
2010-03-25 13:15:10 +01:00
setModelFacing ( placeFacing ) ;
2010-03-12 08:42:55 +01:00
2010-07-21 20:21:40 +02:00
Config & config = Config : : getInstance ( ) ;
2011-04-28 02:16:26 +02:00
showUnitParticles = config . getBool ( " UnitParticles " , " true " ) ;
2011-05-01 22:19:41 +02:00
maxQueuedCommandDisplayCount = config . getInt ( " MaxQueuedCommandDisplayCount " , " 15 " ) ;
2010-03-12 08:42:55 +01:00
2011-12-02 23:04:02 +01:00
if ( GlobalStaticFlags : : getIsNonGraphicalModeEnabled ( ) = = true ) {
2011-12-02 17:07:59 +01:00
showUnitParticles = false ;
}
2010-03-12 08:42:55 +01:00
lastPos = pos ;
progress = 0 ;
lastAnimProgress = 0 ;
animProgress = 0 ;
progress2 = 0 ;
kills = 0 ;
2011-04-20 18:46:47 +02:00
enemyKills = 0 ;
2010-03-12 08:42:55 +01:00
loadCount = 0 ;
ep = 0 ;
deadCount = 0 ;
hp = type - > getMaxHp ( ) / 20 ;
toBeUndertaken = false ;
highlight = 0.f ;
meetingPos = pos ;
alive = true ;
2010-09-06 19:52:33 +02:00
if ( type - > hasSkillClass ( scBeBuilt ) = = false ) {
2010-03-25 13:15:10 +01:00
float rot = 0.f ;
random . init ( id ) ;
rot + = random . randRange ( - 5 , 5 ) ;
rotation = rot ;
lastRotation = rot ;
targetRotation = rot ;
}
// else it was set appropriately in setModelFacing()
2010-03-12 08:42:55 +01:00
2010-09-06 19:52:33 +02:00
if ( getType ( ) - > getField ( fAir ) ) {
currField = fAir ;
}
if ( getType ( ) - > getField ( fLand ) ) {
currField = fLand ;
}
2010-03-12 08:42:55 +01:00
fire = NULL ;
computeTotalUpgrade ( ) ;
//starting skill
2011-06-25 09:31:01 +02:00
this - > lastModelIndexForCurrSkillType = - 1 ;
2011-06-25 23:40:27 +02:00
this - > animationRandomCycleCount = 0 ;
2010-09-06 19:52:33 +02:00
this - > currSkill = getType ( ) - > getFirstStOfClass ( scStop ) ;
2011-06-25 22:44:46 +02:00
this - > currentAttackBoostOriginatorEffect . skillType = this - > currSkill ;
2011-06-25 10:53:53 +02:00
2011-09-27 19:15:56 +02:00
this - > faction - > addLivingUnits ( id ) ;
this - > faction - > addLivingUnitsp ( this ) ;
2010-04-27 05:36:36 +02:00
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
addItemToVault ( & this - > ep , this - > ep ) ;
2013-01-04 19:00:51 +01:00
calculateFogOfWarRadius ( ) ;
2011-09-25 06:07:59 +02:00
// if(isUnitDeleted(this) == true) {
// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
// deletedUnits.erase(this);
// }
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
}
2010-11-07 03:37:00 +01:00
Unit : : ~ Unit ( ) {
2010-10-17 10:50:27 +02:00
badHarvestPosList . clear ( ) ;
2011-09-27 19:15:56 +02:00
this - > faction - > deleteLivingUnits ( id ) ;
this - > faction - > deleteLivingUnitsp ( this ) ;
2010-12-24 09:43:09 +01:00
2010-03-12 08:42:55 +01:00
//remove commands
2011-07-05 17:43:39 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-05 17:43:39 +02:00
2011-10-28 03:11:42 +02:00
changedActiveCommand = false ;
2010-09-06 19:52:33 +02:00
while ( commands . empty ( ) = = false ) {
2010-03-12 08:42:55 +01:00
delete commands . back ( ) ;
commands . pop_back ( ) ;
}
2011-07-05 17:43:39 +02:00
safeMutex . ReleaseLock ( ) ;
2010-09-06 19:52:33 +02:00
// If the unit is not visible we better make sure we cleanup associated particles
if ( this - > getVisible ( ) = = false ) {
Renderer : : getInstance ( ) . cleanupUnitParticleSystems ( unitParticleSystems , rsGame ) ;
2010-09-07 07:25:40 +02:00
2010-09-06 19:52:33 +02:00
Renderer : : getInstance ( ) . cleanupParticleSystems ( fireParticleSystems , rsGame ) ;
2010-09-07 07:25:40 +02:00
// Must set this to null of it will be used below in stopDamageParticles()
2010-09-07 19:30:13 +02:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( fire , rsGame ) = = false ) {
fire = NULL ;
}
2010-09-06 19:52:33 +02:00
}
2010-03-12 08:42:55 +01:00
// fade(and by this remove) all unit particle systems
2011-08-27 08:52:17 +02:00
queuedUnitParticleSystemTypes . clear ( ) ;
2010-09-06 19:52:33 +02:00
while ( unitParticleSystems . empty ( ) = = false ) {
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( unitParticleSystems . back ( ) , rsGame ) = = true ) {
unitParticleSystems . back ( ) - > fade ( ) ;
}
2010-03-25 13:15:10 +01:00
unitParticleSystems . pop_back ( ) ;
}
2011-07-01 23:47:54 +02:00
stopDamageParticles ( true ) ;
2010-07-21 20:21:40 +02:00
2011-06-25 22:44:46 +02:00
while ( currentAttackBoostEffects . empty ( ) = = false ) {
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
2011-07-06 07:16:25 +02:00
UnitAttackBoostEffect * ab = currentAttackBoostEffects . back ( ) ;
delete ab ;
2011-06-25 22:44:46 +02:00
currentAttackBoostEffects . pop_back ( ) ;
}
delete currentAttackBoostOriginatorEffect . currentAppliedEffect ;
currentAttackBoostOriginatorEffect . currentAppliedEffect = NULL ;
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
Unit : : mapMemoryList2 [ this - > unitPath ] = this - > getId ( ) ;
# endif
2010-07-21 20:21:40 +02:00
delete this - > unitPath ;
this - > unitPath = NULL ;
2010-09-10 17:51:16 +02:00
Renderer & renderer = Renderer : : getInstance ( ) ;
2010-09-10 21:44:00 +02:00
renderer . removeUnitFromQuadCache ( this ) ;
2012-04-12 22:43:19 +02:00
if ( game ! = NULL ) {
game - > removeUnitFromSelection ( this ) ;
}
2011-09-25 06:07:59 +02:00
//MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
//deletedUnits[this]=true;
2011-09-28 08:57:42 +02:00
2011-12-02 17:07:59 +01:00
delete mutexCommands ;
mutexCommands = NULL ;
2011-09-28 08:57:42 +02:00
# ifdef LEAK_CHECK_UNITS
Unit : : mapMemoryList . erase ( this ) ;
# endif
}
# ifdef LEAK_CHECK_UNITS
void Unit : : dumpMemoryList ( ) {
printf ( " ===== START report of Unfreed Unit pointers ===== \n " ) ;
for ( std : : map < Unit * , bool > : : iterator iterMap = Unit : : mapMemoryList . begin ( ) ;
iterMap ! = Unit : : mapMemoryList . end ( ) ; + + iterMap ) {
printf ( " ************** ==> Unfreed Unit pointer [%p] \n " , iterMap - > first ) ;
}
2010-03-25 13:15:10 +01:00
}
2011-09-28 08:57:42 +02:00
# endif
2010-03-12 08:42:55 +01:00
2011-09-25 06:07:59 +02:00
//bool Unit::isUnitDeleted(void *unit) {
// bool result = false;
// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
// if(deletedUnits.find(unit) != deletedUnits.end()) {
// result = true;
// }
// return result;
//}
2010-12-24 09:43:09 +01:00
void Unit : : setModelFacing ( CardinalDir value ) {
2010-03-25 13:15:10 +01:00
modelFacing = value ;
lastRotation = targetRotation = rotation = value * 90.f ;
2010-03-12 08:42:55 +01:00
}
// ====================================== get ======================================
2010-06-14 08:38:24 +02:00
Vec2i Unit : : getCenteredPos ( ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
return pos + Vec2i ( type - > getSize ( ) / 2 , type - > getSize ( ) / 2 ) ;
}
2010-06-14 08:38:24 +02:00
Vec2f Unit : : getFloatCenteredPos ( ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
return Vec2f ( pos . x - 0.5f + type - > getSize ( ) / 2.f , pos . y - 0.5f + type - > getSize ( ) / 2.f ) ;
}
2010-06-14 08:38:24 +02:00
Vec2i Unit : : getCellPos ( ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
if ( type - > hasCellMap ( ) ) {
2010-10-30 10:54:00 +02:00
if ( type - > hasEmptyCellMap ( ) = = false | |
type - > getAllowEmptyCellMap ( ) = = true ) {
//find nearest pos to center that is free
Vec2i centeredPos = getCenteredPos ( ) ;
float nearestDist = - 1.f ;
Vec2i nearestPos = pos ;
for ( int i = 0 ; i < type - > getSize ( ) ; + + i ) {
for ( int j = 0 ; j < type - > getSize ( ) ; + + j ) {
if ( type - > getCellMapCell ( i , j , modelFacing ) ) {
Vec2i currPos = pos + Vec2i ( i , j ) ;
float dist = currPos . dist ( centeredPos ) ;
if ( nearestDist = = - 1.f | | dist < nearestDist ) {
nearestDist = dist ;
nearestPos = currPos ;
}
2010-03-12 08:42:55 +01:00
}
}
}
2010-10-30 10:54:00 +02:00
return nearestPos ;
2010-03-12 08:42:55 +01:00
}
}
return pos ;
}
2011-07-12 01:59:16 +02:00
void Unit : : calculateXZRotation ( ) {
//if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){
//if(currSkill->getClass()==scMove)
if ( lastPos ! = pos ) { // targetPosCalc ( maybe also sometimes needed if no move ? terrain flatting... )
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( pos ) ) ;
const Vec3f normal = sc - > getNormal ( ) ;
2011-07-13 21:57:29 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
targetRotationZ = radToDeg ( streflop : : atan2 ( static_cast < streflop : : Simple > ( abs ( normal . x ) ) , static_cast < streflop : : Simple > ( abs ( normal . y ) ) ) ) ;
2011-07-13 21:57:29 +02:00
# else
2011-07-17 23:47:56 +02:00
targetRotationZ = radToDeg ( atan2 ( abs ( normal . x ) , abs ( normal . y ) ) ) ;
2011-07-13 21:57:29 +02:00
# endif
2011-07-12 01:59:16 +02:00
if ( ( normal . y < 0 | | normal . x < 0 ) & & ! ( normal . y < 0 & & normal . x < 0 ) ) {
targetRotationZ = targetRotationZ * - 1 ;
}
targetRotationZ = targetRotationZ * - 1 ;
2011-07-13 21:57:29 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
targetRotationX = radToDeg ( streflop : : atan2 ( static_cast < streflop : : Simple > ( abs ( normal . z ) ) , static_cast < streflop : : Simple > ( abs ( normal . y ) ) ) ) ;
2011-07-13 21:57:29 +02:00
# else
targetRotationX = radToDeg ( atan2 ( abs ( normal . z ) , abs ( normal . y ) ) ) ;
# endif
2011-07-12 01:59:16 +02:00
if ( ( normal . y < 0 | | normal . z < 0 ) & & ! ( normal . y < 0 & & normal . z < 0 ) ) {
targetRotationX = targetRotationX * - 1 ;
}
}
//For smooth rotation we now softly adjust the angle
2011-07-17 23:47:56 +02:00
int adjustStep = 1 ;
2011-07-12 01:59:16 +02:00
if ( rotationZ < targetRotationZ ) {
if ( rotationZ + adjustStep > targetRotationZ ) {
rotationZ = targetRotationZ ;
}
else {
rotationZ = rotationZ + adjustStep ;
}
}
else if ( rotationZ > targetRotationZ ) {
if ( rotationZ - adjustStep < targetRotationZ ) {
rotationZ = targetRotationZ ;
}
else {
rotationZ = rotationZ - adjustStep ;
}
}
if ( rotationX < targetRotationX ) {
if ( rotationX + adjustStep > targetRotationX ) {
rotationX = targetRotationX ;
}
else {
rotationX = rotationX + adjustStep ;
}
}
else if ( rotationX > targetRotationX ) {
if ( rotationX - adjustStep < targetRotationX ) {
rotationX = targetRotationX ;
}
else {
rotationX = rotationX - adjustStep ;
}
}
}
float Unit : : getRotationZ ( ) const {
return rotationZ ;
}
float Unit : : getRotationX ( ) const {
return rotationX ;
2010-03-12 08:42:55 +01:00
}
int Unit : : getProductionPercent ( ) const {
if ( anyCommand ( ) ) {
const ProducibleType * produced = commands . front ( ) - > getCommandType ( ) - > getProduced ( ) ;
if ( produced ! = NULL ) {
return clamp ( progress2 * 100 / produced - > getProductionTime ( ) , 0 , 100 ) ;
}
}
return - 1 ;
}
2011-07-08 01:02:46 +02:00
float Unit : : getProgressRatio ( ) const {
if ( anyCommand ( ) ) {
const ProducibleType * produced = commands . front ( ) - > getCommandType ( ) - > getProduced ( ) ;
if ( produced ! = NULL ) {
float help = progress2 ;
return clamp ( help / produced - > getProductionTime ( ) , 0.f , 1.f ) ;
}
}
return - 1 ;
}
2010-06-14 08:38:24 +02:00
float Unit : : getHpRatio ( ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
return clamp ( static_cast < float > ( hp ) / type - > getTotalMaxHp ( & totalUpgrade ) , 0.f , 1.f ) ;
}
2010-06-14 08:38:24 +02:00
float Unit : : getEpRatio ( ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
if ( type - > getMaxHp ( ) = = 0 ) {
return 0.f ;
}
else {
return clamp ( static_cast < float > ( ep ) / type - > getTotalMaxEp ( & totalUpgrade ) , 0.f , 1.f ) ;
}
}
const Level * Unit : : getNextLevel ( ) const {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
if ( level = = NULL & & type - > getLevelCount ( ) > 0 ) {
return type - > getLevel ( 0 ) ;
}
else {
for ( int i = 1 ; i < type - > getLevelCount ( ) ; + + i ) {
if ( type - > getLevel ( i - 1 ) = = level ) {
return type - > getLevel ( i ) ;
}
}
}
return NULL ;
}
string Unit : : getFullName ( ) const {
string str = " " ;
if ( level ! = NULL ) {
2013-01-16 22:16:59 +01:00
str + = ( level - > getName ( true ) + " " ) ;
2010-03-12 08:42:55 +01:00
}
if ( type = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " type == NULL in Unit::getFullName() ! " ) ;
2010-03-12 08:42:55 +01:00
}
2012-05-02 22:46:47 +02:00
str + = type - > getName ( true ) ;
2010-03-12 08:42:55 +01:00
return str ;
}
// ====================================== is ======================================
bool Unit : : isOperative ( ) const {
return isAlive ( ) & & isBuilt ( ) ;
}
2011-07-08 01:02:46 +02:00
bool Unit : : isAnimProgressBound ( ) const {
2011-07-02 23:44:29 +02:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2011-07-02 23:44:29 +02:00
}
bool result = false ;
if ( currSkill - > getClass ( ) = = scBeBuilt ) {
2011-07-08 01:02:46 +02:00
const BeBuiltSkillType * skill = dynamic_cast < const BeBuiltSkillType * > ( currSkill ) ;
if ( skill ! = NULL ) {
result = skill - > getAnimProgressBound ( ) ;
}
}
else if ( currSkill - > getClass ( ) = = scProduce ) {
const ProduceSkillType * skill = dynamic_cast < const ProduceSkillType * > ( currSkill ) ;
if ( skill ! = NULL ) {
result = skill - > getAnimProgressBound ( ) ;
}
}
else if ( currSkill - > getClass ( ) = = scUpgrade ) {
const UpgradeSkillType * skill = dynamic_cast < const UpgradeSkillType * > ( currSkill ) ;
if ( skill ! = NULL ) {
result = skill - > getAnimProgressBound ( ) ;
}
}
else if ( currSkill - > getClass ( ) = = scMorph ) {
const MorphSkillType * skill = dynamic_cast < const MorphSkillType * > ( currSkill ) ;
if ( skill ! = NULL ) {
result = skill - > getAnimProgressBound ( ) ;
2011-07-02 23:44:29 +02:00
}
}
return result ;
}
2010-03-12 08:42:55 +01:00
bool Unit : : isBeingBuilt ( ) const {
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-09-06 19:52:33 +02:00
return ( currSkill - > getClass ( ) = = scBeBuilt ) ;
2010-03-12 08:42:55 +01:00
}
bool Unit : : isBuilt ( ) const {
2010-09-06 19:52:33 +02:00
return ( isBeingBuilt ( ) = = false ) ;
2010-03-12 08:42:55 +01:00
}
2012-06-22 06:58:44 +02:00
bool Unit : : isBuildCommandPending ( ) const {
bool result = false ;
Command * command = this - > getCurrCommand ( ) ;
if ( command ! = NULL ) {
const BuildCommandType * bct = dynamic_cast < const BuildCommandType * > ( command - > getCommandType ( ) ) ;
if ( bct ! = NULL ) {
if ( this - > getCurrSkill ( ) - > getClass ( ) ! = scBuild ) {
result = true ;
}
}
}
return result ;
}
2012-06-22 15:30:15 +02:00
UnitBuildInfo Unit : : getBuildCommandPendingInfo ( ) const {
UnitBuildInfo result ;
2012-06-22 06:58:44 +02:00
Command * command = this - > getCurrCommand ( ) ;
if ( command ! = NULL ) {
const BuildCommandType * bct = dynamic_cast < const BuildCommandType * > ( command - > getCommandType ( ) ) ;
if ( bct ! = NULL ) {
2012-06-22 15:30:15 +02:00
result . pos = command - > getOriginalPos ( ) ;
result . facing = command - > getFacing ( ) ;
result . buildUnit = command - > getUnitType ( ) ;
result . unit = this ;
2012-06-22 06:58:44 +02:00
}
}
return result ;
}
2010-06-14 08:38:24 +02:00
bool Unit : : isAlly ( const Unit * unit ) const {
if ( unit = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
return faction - > isAlly ( unit - > getFaction ( ) ) ;
}
2010-06-14 08:38:24 +02:00
bool Unit : : isDamaged ( ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
return hp < type - > getTotalMaxHp ( & totalUpgrade ) ;
}
2010-06-14 08:38:24 +02:00
bool Unit : : isInteresting ( InterestingUnitType iut ) const {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2011-01-08 22:53:05 +01:00
switch ( iut ) {
2010-03-12 08:42:55 +01:00
case iutIdleHarvester :
2011-01-08 22:53:05 +01:00
if ( type - > hasCommandClass ( ccHarvest ) ) {
if ( commands . empty ( ) = = false ) {
2010-03-12 08:42:55 +01:00
const CommandType * ct = commands . front ( ) - > getCommandType ( ) ;
2011-01-08 22:53:05 +01:00
if ( ct ! = NULL ) {
return ct - > getClass ( ) = = ccStop ;
2010-03-12 08:42:55 +01:00
}
}
}
return false ;
case iutBuiltBuilding :
return type - > hasSkillClass ( scBeBuilt ) & & isBuilt ( ) ;
case iutProducer :
return type - > hasSkillClass ( scProduce ) ;
case iutDamaged :
return isDamaged ( ) ;
case iutStore :
return type - > getStoredResourceCount ( ) > 0 ;
default :
return false ;
}
}
// ====================================== set ======================================
2010-09-06 19:52:33 +02:00
void Unit : : setCurrSkill ( const SkillType * currSkill ) {
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
if ( this - > currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: this->currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2012-03-31 21:50:45 +02:00
if ( this - > currSkill - > getClass ( ) = = scMove & &
currSkill - > getClass ( ) ! = scMove ) {
faction - > removeUnitFromMovingList ( this - > getId ( ) ) ;
}
else if ( this - > currSkill - > getClass ( ) ! = scMove & &
currSkill - > getClass ( ) = = scMove ) {
faction - > addUnitToMovingList ( this - > getId ( ) ) ;
}
2011-10-28 06:37:10 +02:00
changedActiveCommand = false ;
2012-03-31 21:50:45 +02:00
if ( currSkill - > getClass ( ) ! = this - > currSkill - > getClass ( ) | |
currSkill - > getName ( ) ! = this - > currSkill - > getName ( ) ) {
2010-03-12 08:42:55 +01:00
animProgress = 0 ;
lastAnimProgress = 0 ;
2011-08-27 08:52:17 +02:00
queuedUnitParticleSystemTypes . clear ( ) ;
2010-09-06 19:52:33 +02:00
while ( unitParticleSystems . empty ( ) = = false ) {
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( unitParticleSystems . back ( ) , rsGame ) = = true ) {
unitParticleSystems . back ( ) - > fade ( ) ;
}
2010-03-12 08:42:55 +01:00
unitParticleSystems . pop_back ( ) ;
}
2013-01-11 19:18:58 +01:00
Command * cmd = getCurrrentCommandThreadSafe ( ) ;
// Set mew fog of war skill type if need be
if ( cmd ! = NULL & & cmd - > getCommandType ( ) ! = NULL & &
cmd - > getCommandType ( ) - > hasFogOfWarSkillType ( currSkill - > getName ( ) ) ) {
const FogOfWarSkillType * fowst = cmd - > getCommandType ( ) - > getFogOfWarSkillType ( ) ;
2013-01-11 19:40:47 +01:00
// Remove old fog of war skill type if need be
game - > getWorld ( ) - > removeFogOfWarSkillTypeFromList ( this ) ;
2013-01-11 19:18:58 +01:00
game - > getWorld ( ) - > addFogOfWarSkillType ( this , fowst ) ;
}
2013-01-11 19:40:47 +01:00
else {
// Remove old fog of war skill type if need be
game - > getWorld ( ) - > removeFogOfWarSkillType ( this ) ;
}
2010-03-12 08:42:55 +01:00
}
2011-12-03 01:39:03 +01:00
if ( showUnitParticles = = true & &
currSkill - > unitParticleSystemTypes . empty ( ) = = false & &
unitParticleSystems . empty ( ) = = true ) {
2011-08-27 08:52:17 +02:00
//printf("START - particle system type\n");
2010-09-06 19:52:33 +02:00
for ( UnitParticleSystemTypes : : const_iterator it = currSkill - > unitParticleSystemTypes . begin ( ) ; it ! = currSkill - > unitParticleSystemTypes . end ( ) ; + + it ) {
2011-08-27 08:52:17 +02:00
if ( ( * it ) - > getStartTime ( ) = = 0.0 ) {
//printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime());
UnitParticleSystem * ups = new UnitParticleSystem ( 200 ) ;
( * it ) - > setValues ( ups ) ;
ups - > setPos ( getCurrVector ( ) ) ;
2011-09-27 09:01:08 +02:00
if ( getFaction ( ) - > getTexture ( ) ) {
ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
2011-08-27 08:52:17 +02:00
unitParticleSystems . push_back ( ups ) ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
else {
//printf("Adding queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime());
queuedUnitParticleSystemTypes . push_back ( * it ) ;
}
2010-03-12 08:42:55 +01:00
}
}
progress2 = 0 ;
2011-06-25 09:31:01 +02:00
if ( this - > currSkill ! = currSkill ) {
this - > lastModelIndexForCurrSkillType = - 1 ;
2011-06-25 23:40:27 +02:00
this - > animationRandomCycleCount = 0 ;
2011-06-25 09:31:01 +02:00
}
2010-03-12 08:42:55 +01:00
this - > currSkill = currSkill ;
}
2010-10-30 10:54:00 +02:00
void Unit : : setCurrSkill ( SkillClass sc ) {
2010-06-14 08:38:24 +02:00
if ( getType ( ) = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
setCurrSkill ( getType ( ) - > getFirstStOfClass ( sc ) ) ;
}
void Unit : : setTarget ( const Unit * unit ) {
2010-06-14 08:38:24 +02:00
if ( unit = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
//find a free pos in cellmap
setTargetPos ( unit - > getCellPos ( ) ) ;
//ser field and vector
targetField = unit - > getCurrField ( ) ;
targetVec = unit - > getCurrVector ( ) ;
targetRef = unit ;
}
2012-04-11 07:41:40 +02:00
void Unit : : setPos ( const Vec2i & pos , bool clearPathFinder ) {
2011-02-23 08:03:38 +01:00
if ( map - > isInside ( pos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( pos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #3 Invalid path position = " + pos . getString ( ) ) ;
2011-02-23 08:03:38 +01:00
}
2012-04-11 07:41:40 +02:00
if ( clearPathFinder = = true & & this - > unitPath ! = NULL ) {
this - > unitPath - > clear ( ) ;
}
2012-09-22 22:13:57 +02:00
Vec2i oldLastPos = this - > lastPos ;
2010-03-12 08:42:55 +01:00
this - > lastPos = this - > pos ;
this - > pos = pos ;
2012-09-22 22:13:57 +02:00
2012-09-26 02:15:37 +02:00
// // This code is initial code to make the camera 'follow' a unit
// //if(this->getId() == 5) {
// if(cameraFollowUnit == true) {
// //printf("A fov [%f] [H [%f] [V [%f]\n",game->getGameCameraPtr()->getFov(),game->getGameCameraPtr()->getHAng(),game->getGameCameraPtr()->getVAng());
//
// //game->getGameCameraPtr()->setClampDisabled(true);
//
// //game->getGameCameraPtr()->setFov(45);
// if(oldLastPos.x > pos.x) {
// game->getGameCameraPtr()->setHAng(270);
// game->getGameCameraPtr()->setVAng(-7.6);
// }
// else if(oldLastPos.x < pos.x) {
// game->getGameCameraPtr()->setHAng(90);
// game->getGameCameraPtr()->setVAng(1.4);
// }
// else if(oldLastPos.y > pos.y) {
// game->getGameCameraPtr()->setHAng(180);
// game->getGameCameraPtr()->setVAng(4.2);
// }
// else {
// game->getGameCameraPtr()->setHAng(-2.4);
// game->getGameCameraPtr()->setVAng(-1.4);
// }
//
// game->getGameCameraPtr()->setPos(getCurrVector());
// game->getGameCameraPtr()->stop();
//
// //printf("B fov [%f] [H [%f] [V [%f]\n",game->getGameCameraPtr()->getFov(),game->getGameCameraPtr()->getHAng(),game->getGameCameraPtr()->getVAng());
// }
2012-09-22 22:13:57 +02:00
2011-02-25 05:15:22 +01:00
map - > clampPos ( this - > pos ) ;
2010-03-12 08:42:55 +01:00
this - > meetingPos = pos - Vec2i ( 1 ) ;
2011-02-25 05:15:22 +01:00
map - > clampPos ( this - > meetingPos ) ;
2010-04-27 05:36:36 +02:00
2010-09-09 03:44:25 +02:00
// Attempt to improve performance
this - > exploreCells ( ) ;
2013-01-04 19:00:51 +01:00
calculateFogOfWarRadius ( ) ;
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
}
2013-01-04 19:00:51 +01:00
FowAlphaCellsLookupItem Unit : : getFogOfWarRadius ( bool useCache ) const {
if ( useCache = = true & & Config : : getInstance ( ) . getBool ( " EnableFowCache " , " true " ) = = true ) {
return cachedFow ;
}
FowAlphaCellsLookupItem result ;
//iterate through all cells
int sightRange = this - > getType ( ) - > getSight ( ) ;
PosCircularIterator pci ( map , this - > getPos ( ) , sightRange + World : : indirectSightRange ) ;
while ( pci . next ( ) ) {
const Vec2i sightpos = pci . getPos ( ) ;
Vec2i surfPos = Map : : toSurfCoords ( sightpos ) ;
//compute max alpha
float maxAlpha = 0.0f ;
if ( surfPos . x > 1 & & surfPos . y > 1 & & surfPos . x < map - > getSurfaceW ( ) - 2 & & surfPos . y < map - > getSurfaceH ( ) - 2 ) {
maxAlpha = 1.f ;
}
else if ( surfPos . x > 0 & & surfPos . y > 0 & & surfPos . x < map - > getSurfaceW ( ) - 1 & & surfPos . y < map - > getSurfaceH ( ) - 1 ) {
maxAlpha = 0.3f ;
}
//compute alpha
float alpha = maxAlpha ;
float dist = this - > getPos ( ) . dist ( sightpos ) ;
if ( dist > sightRange ) {
alpha = clamp ( 1.f - ( dist - sightRange ) / ( World : : indirectSightRange ) , 0.f , maxAlpha ) ;
}
result . surfPosList . push_back ( surfPos ) ;
result . alphaList . push_back ( alpha ) ;
}
return result ;
}
void Unit : : calculateFogOfWarRadius ( ) {
if ( game - > getWorld ( ) - > getFogOfWar ( ) = = true ) {
2013-01-04 21:35:38 +01:00
if ( Config : : getInstance ( ) . getBool ( " EnableFowCache " , " true " ) = = true & & this - > pos ! = this - > cachedFowPos ) {
2013-01-04 19:00:51 +01:00
cachedFow = getFogOfWarRadius ( false ) ;
2013-01-04 21:35:38 +01:00
this - > cachedFowPos = this - > pos ;
2013-01-04 19:00:51 +01:00
}
}
}
2011-02-23 08:03:38 +01:00
void Unit : : setTargetPos ( const Vec2i & targetPos ) {
if ( map - > isInside ( targetPos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( targetPos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #4 Invalid path position = " + targetPos . getString ( ) ) ;
2011-02-23 08:03:38 +01:00
}
2010-03-12 08:42:55 +01:00
Vec2i relPos = targetPos - pos ;
2011-02-25 05:15:22 +01:00
//map->clampPos(relPos);
2010-04-27 22:38:34 +02:00
Vec2f relPosf = Vec2f ( ( float ) relPos . x , ( float ) relPos . y ) ;
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
targetRotation = radToDeg ( streflop : : atan2 ( static_cast < streflop : : Simple > ( relPosf . x ) , static_cast < streflop : : Simple > ( relPosf . y ) ) ) ;
2010-05-01 22:14:25 +02:00
# else
targetRotation = radToDeg ( atan2 ( relPosf . x , relPosf . y ) ) ;
# endif
2010-03-12 08:42:55 +01:00
targetRef = NULL ;
2010-06-08 09:40:32 +02:00
//this->targetField = fLand;
//this->targetVec = Vec3f(0.0);
//this->targetPos = Vec2i(0);
2010-03-12 08:42:55 +01:00
this - > targetPos = targetPos ;
2011-02-25 05:15:22 +01:00
map - > clampPos ( this - > targetPos ) ;
2010-04-27 05:36:36 +02:00
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
}
2010-06-15 18:27:52 +02:00
void Unit : : setVisible ( const bool visible ) {
this - > visible = visible ;
2012-03-19 22:35:54 +01:00
if ( unitParticleSystems . empty ( ) = = false ) {
for ( UnitParticleSystems : : iterator it = unitParticleSystems . begin ( ) ; it ! = unitParticleSystems . end ( ) ; + + it ) {
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ( * it ) , rsGame ) = = true ) {
( * it ) - > setVisible ( visible ) ;
}
2011-11-05 06:45:02 +01:00
}
2010-03-12 08:42:55 +01:00
}
2012-03-19 22:35:54 +01:00
if ( damageParticleSystems . empty ( ) = = false ) {
for ( UnitParticleSystems : : iterator it = damageParticleSystems . begin ( ) ; it ! = damageParticleSystems . end ( ) ; + + it ) {
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ( * it ) , rsGame ) = = true ) {
( * it ) - > setVisible ( visible ) ;
}
2011-11-05 06:45:02 +01:00
}
2010-03-12 08:42:55 +01:00
}
2012-03-19 22:35:54 +01:00
if ( smokeParticleSystems . empty ( ) = = false ) {
for ( UnitParticleSystems : : iterator it = smokeParticleSystems . begin ( ) ; it ! = smokeParticleSystems . end ( ) ; + + it ) {
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ( * it ) , rsGame ) = = true ) {
if ( ( * it ) - > getVisible ( ) ! = visible ) {
//printf("Changing visibility for smoke particle system to: %d\n",visible);
( * it ) - > setVisible ( visible ) ;
}
}
2011-11-05 06:45:02 +01:00
}
2011-07-04 17:55:13 +02:00
}
2012-03-19 22:35:54 +01:00
if ( currentAttackBoostEffects . empty ( ) = = false ) {
for ( unsigned int i = 0 ; i < currentAttackBoostEffects . size ( ) ; + + i ) {
UnitAttackBoostEffect * effect = currentAttackBoostEffects [ i ] ;
if ( effect ! = NULL & & effect - > ups ! = NULL ) {
bool particleValid = Renderer : : getInstance ( ) . validateParticleSystemStillExists ( effect - > ups , rsGame ) ;
if ( particleValid = = true ) {
effect - > ups - > setVisible ( visible ) ;
}
2011-10-30 07:12:40 +01:00
}
2011-06-25 22:44:46 +02:00
}
}
if ( currentAttackBoostOriginatorEffect . currentAppliedEffect ! = NULL ) {
if ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups ! = NULL ) {
2011-10-30 07:12:40 +01:00
bool particleValid = Renderer : : getInstance ( ) . validateParticleSystemStillExists ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups , rsGame ) ;
if ( particleValid = = true ) {
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setVisible ( visible ) ;
}
2011-06-25 22:44:46 +02:00
}
}
2010-03-12 08:42:55 +01:00
}
// =============================== Render related ==================================
2011-06-25 09:31:01 +02:00
Model * Unit : : getCurrentModelPtr ( ) {
2011-01-18 08:52:06 +01:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2011-01-18 08:52:06 +01:00
}
2011-06-25 23:40:27 +02:00
int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType ;
Model * result = currSkill - > getAnimation ( animProgress , this , & lastModelIndexForCurrSkillType , & animationRandomCycleCount ) ;
if ( currentModelIndexForCurrSkillType ! = lastModelIndexForCurrSkillType ) {
animationRandomCycleCount + + ;
2012-03-24 19:30:49 +01:00
if ( currSkill ! = NULL & & animationRandomCycleCount > = currSkill - > getAnimationCount ( ) ) {
animationRandomCycleCount = 0 ;
}
2011-06-25 23:40:27 +02:00
}
return result ;
2011-01-18 08:52:06 +01:00
}
2011-06-25 09:31:01 +02:00
const Model * Unit : : getCurrentModel ( ) {
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2011-06-25 23:40:27 +02:00
int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType ;
const Model * result = currSkill - > getAnimation ( animProgress , this , & lastModelIndexForCurrSkillType , & animationRandomCycleCount ) ;
if ( currentModelIndexForCurrSkillType ! = lastModelIndexForCurrSkillType ) {
animationRandomCycleCount + + ;
2012-03-24 19:30:49 +01:00
if ( currSkill ! = NULL & & animationRandomCycleCount > = currSkill - > getAnimationCount ( ) ) {
animationRandomCycleCount = 0 ;
}
2011-06-25 23:40:27 +02:00
}
return result ;
2010-03-12 08:42:55 +01:00
}
2012-03-24 19:30:49 +01:00
bool Unit : : checkModelStateInfoForNewHpValue ( ) {
bool result = false ;
if ( currSkill ! = NULL & & currSkill - > getAnimationCount ( ) > 1 ) {
if ( lastModelIndexForCurrSkillType > = 0 ) {
const AnimationAttributes attributes = currSkill - > getAnimationAttribute ( lastModelIndexForCurrSkillType ) ;
if ( attributes . fromHp ! = 0 | | attributes . toHp ! = 0 ) {
//printf("Check for RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp);
//if(this->getHp() >= attributes.fromHp && this->getHp() <= attributes.toHp) {
if ( this - > getHp ( ) < attributes . fromHp | | this - > getHp ( ) > attributes . toHp ) {
//printf("RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp);
lastModelIndexForCurrSkillType = - 1 ;
animationRandomCycleCount = 0 ;
2012-03-28 08:25:57 +02:00
result = true ;
2012-03-24 19:30:49 +01:00
}
}
else {
//printf("Check for RESET #2 model state for [%d - %s] HP = %d [%d to %d] for skill [%s]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp,currSkill->getName().c_str());
}
}
}
return result ;
}
2010-03-12 08:42:55 +01:00
Vec3f Unit : : getCurrVector ( ) const {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
return getCurrVectorFlat ( ) + Vec3f ( 0.f , type - > getHeight ( ) / 2.f , 0.f ) ;
}
Vec3f Unit : : getCurrVectorFlat ( ) const {
2011-02-11 05:48:17 +01:00
return getVectorFlat ( lastPos , pos ) ;
/*
Vec3f v ;
2010-03-12 08:42:55 +01:00
float y1 = computeHeight ( lastPos ) ;
float y2 = computeHeight ( pos ) ;
2010-10-30 10:54:00 +02:00
if ( currSkill - > getClass ( ) = = scMove ) {
2010-03-12 08:42:55 +01:00
v . x = lastPos . x + progress * ( pos . x - lastPos . x ) ;
v . z = lastPos . y + progress * ( pos . y - lastPos . y ) ;
v . y = y1 + progress * ( y2 - y1 ) ;
}
else {
v . x = static_cast < float > ( pos . x ) ;
v . z = static_cast < float > ( pos . y ) ;
v . y = y2 ;
}
v . x + = type - > getSize ( ) / 2.f - 0.5f ;
v . z + = type - > getSize ( ) / 2.f - 0.5f ;
2011-02-11 05:48:17 +01:00
return v ;
*/
}
Vec3f Unit : : getVectorFlat ( const Vec2i & lastPosValue , const Vec2i & curPosValue ) const {
Vec3f v ;
float y1 = computeHeight ( lastPosValue ) ;
float y2 = computeHeight ( curPosValue ) ;
if ( currSkill - > getClass ( ) = = scMove ) {
v . x = lastPosValue . x + progress * ( curPosValue . x - lastPosValue . x ) ;
v . z = lastPosValue . y + progress * ( curPosValue . y - lastPosValue . y ) ;
v . y = y1 + progress * ( y2 - y1 ) ;
}
else {
v . x = static_cast < float > ( curPosValue . x ) ;
v . z = static_cast < float > ( curPosValue . y ) ;
v . y = y2 ;
}
v . x + = type - > getSize ( ) / 2.f - 0.5f ;
v . z + = type - > getSize ( ) / 2.f - 0.5f ;
2010-03-12 08:42:55 +01:00
return v ;
}
// =================== Command list related ===================
//any command
2010-10-28 20:31:12 +02:00
bool Unit : : anyCommand ( bool validateCommandtype ) const {
bool result = false ;
if ( validateCommandtype = = false ) {
result = ( commands . empty ( ) = = false ) ;
}
else {
for ( Commands : : const_iterator it = commands . begin ( ) ; it ! = commands . end ( ) ; + + it ) {
const CommandType * ct = ( * it ) - > getCommandType ( ) ;
if ( ct ! = NULL & & ct - > getClass ( ) ! = ccStop ) {
result = true ;
break ;
}
}
}
return result ;
2010-03-12 08:42:55 +01:00
}
2011-07-05 17:43:39 +02:00
//return current command, assert that there is always one command
Command * Unit : : getCurrrentCommandThreadSafe ( ) {
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-05 17:43:39 +02:00
if ( commands . empty ( ) = = false ) {
return commands . front ( ) ;
}
2011-07-05 20:26:09 +02:00
2011-07-05 17:43:39 +02:00
return NULL ;
}
2010-08-28 03:46:26 +02:00
void Unit : : replaceCurrCommand ( Command * cmd ) {
2011-07-06 08:38:56 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-06 08:38:56 +02:00
2011-01-08 22:53:05 +01:00
assert ( commands . empty ( ) = = false ) ;
2010-08-28 03:46:26 +02:00
commands . front ( ) = cmd ;
2010-09-01 06:42:10 +02:00
this - > setCurrentUnitTitle ( " " ) ;
2010-08-28 03:46:26 +02:00
}
2010-03-12 08:42:55 +01:00
//returns the size of the commands
2011-01-08 22:53:05 +01:00
unsigned int Unit : : getCommandSize ( ) const {
2010-03-12 08:42:55 +01:00
return commands . size ( ) ;
}
2010-08-22 23:09:35 +02:00
//return current command, assert that there is always one command
int Unit : : getCountOfProducedUnits ( const UnitType * ut ) const {
int count = 0 ;
for ( Commands : : const_iterator it = commands . begin ( ) ; it ! = commands . end ( ) ; + + it ) {
const CommandType * ct = ( * it ) - > getCommandType ( ) ;
2010-10-08 21:30:53 +02:00
if ( ct - > getClass ( ) = = ccProduce | | ct - > getClass ( ) = = ccMorph ) {
2010-08-22 23:09:35 +02:00
const UnitType * producedUnitType = static_cast < const UnitType * > ( ct - > getProduced ( ) ) ;
if ( producedUnitType = = ut )
{
count + + ;
}
}
2010-10-08 21:30:53 +02:00
if ( ct - > getClass ( ) = = ccBuild ) {
const UnitType * builtUnitType = ( * it ) - > getUnitType ( ) ;
if ( builtUnitType = = ut )
{
count + + ;
}
}
2010-08-22 23:09:35 +02:00
}
return count ;
}
2010-03-12 08:42:55 +01:00
//give one command (clear, and push back)
2012-11-10 20:39:55 +01:00
std : : pair < CommandResult , string > Unit : : giveCommand ( Command * command , bool tryQueue ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugUnitCommands ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " \n ====================== \n Unit Command tryQueue = %d \n Unit Info: \n %s \n Command Info: \n %s \n " , tryQueue , this - > toString ( ) . c_str ( ) , command - > toString ( ) . c_str ( ) ) ;
2010-06-08 09:40:32 +02:00
2012-11-10 20:39:55 +01:00
std : : pair < CommandResult , string > result ( crFailUndefined , " " ) ;
2011-10-28 06:17:26 +02:00
changedActiveCommand = false ;
2010-11-11 09:02:50 +01:00
Chrono chrono ;
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled ) chrono . start ( ) ;
2010-11-11 09:02:50 +01:00
2010-05-01 11:27:08 +02:00
assert ( command ! = NULL ) ;
assert ( command - > getCommandType ( ) ! = NULL ) ;
2010-12-23 11:44:11 +01:00
const int command_priority = command - > getPriority ( ) ;
2010-05-18 23:18:51 +02:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-11-11 09:02:50 +01:00
2011-10-28 02:22:03 +02:00
//printf("In [%s::%s] Line: %d unit [%d - %s] command [%s] tryQueue = %d command->getCommandType()->isQueuable(tryQueue) = %d\n",__FILE__,__FUNCTION__,__LINE__,this->getId(),this->getType()->getName().c_str(), command->getCommandType()->getName().c_str(), tryQueue,command->getCommandType()->isQueuable(tryQueue));
2011-01-08 22:53:05 +01:00
if ( command - > getCommandType ( ) - > isQueuable ( tryQueue ) ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugUnitCommands ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Command is Queable \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-09 10:06:52 +01:00
2011-04-08 22:25:03 +02:00
if ( command - > getCommandType ( ) - > isQueuable ( ) = = qAlways & & tryQueue ) {
// Its a produce or upgrade command called without queued key
// in this case we must NOT delete lower priority commands!
// we just queue it!
2011-01-08 22:53:05 +01:00
2011-04-08 22:25:03 +02:00
}
else {
//Delete all lower-prioirty commands
for ( list < Command * > : : iterator i = commands . begin ( ) ; i ! = commands . end ( ) ; ) {
if ( ( * i ) - > getPriority ( ) < command_priority ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugUnitCommands ) . enabled )
SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Deleting lower priority command [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( * i ) - > toString ( ) . c_str ( ) ) ;
2011-07-06 08:38:56 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-06 08:38:56 +02:00
2011-04-08 22:25:03 +02:00
deleteQueuedCommand ( * i ) ;
i = commands . erase ( i ) ;
2011-07-06 08:38:56 +02:00
safeMutex . ReleaseLock ( ) ;
2011-04-08 22:25:03 +02:00
}
else {
+ + i ;
}
2010-05-18 23:18:51 +02:00
}
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-11-11 09:02:50 +01:00
2010-03-12 08:42:55 +01:00
//cancel current command if it is not queuable
2011-01-08 22:53:05 +01:00
if ( commands . empty ( ) = = false & &
commands . back ( ) - > getCommandType ( ) - > isQueueAppendable ( ) = = false ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugUnitCommands ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Cancel command because last one is NOT queable [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , commands . back ( ) - > toString ( ) . c_str ( ) ) ;
2010-11-09 10:06:52 +01:00
cancelCommand ( ) ;
2010-03-12 08:42:55 +01:00
}
2010-11-11 09:02:50 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-12 08:42:55 +01:00
}
2010-05-31 08:11:31 +02:00
else {
2010-03-12 08:42:55 +01:00
//empty command queue
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugUnitCommands ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Clear commands because current is NOT queable. \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2011-01-08 22:53:05 +01:00
2011-11-29 01:54:38 +01:00
// bool willChangedActiveCommand = (commands.size() > 0);
// if(willChangedActiveCommand && getCurrCommand()->getCommandType()->getClass() == command->getCommandType()->getClass()) {
// willChangedActiveCommand = false;
// }
// clearCommands();
// changedActiveCommand = willChangedActiveCommand;
2011-12-02 17:07:59 +01:00
bool willChangedActiveCommand = ( commands . empty ( ) = = false ) ;
2011-11-29 01:54:38 +01:00
if ( willChangedActiveCommand ) {
CommandClass currCommandClass = getCurrCommand ( ) - > getCommandType ( ) - > getClass ( ) ;
CommandClass commandClass = command - > getCommandType ( ) - > getClass ( ) ;
if ( currCommandClass
= = commandClass ) {
willChangedActiveCommand = false ;
}
else if ( currCommandClass = = ccAttack | | currCommandClass = = ccAttackStopped | |
commandClass = = ccAttack | | commandClass = = ccAttackStopped ) {
willChangedActiveCommand = true ;
}
else {
willChangedActiveCommand = false ;
}
2011-10-28 06:37:10 +02:00
}
2010-03-12 08:42:55 +01:00
clearCommands ( ) ;
2011-11-29 01:54:38 +01:00
changedActiveCommand = willChangedActiveCommand ;
2011-10-28 02:22:03 +02:00
//printf("In [%s::%s] Line: %d cleared existing commands\n",__FILE__,__FUNCTION__,__LINE__);
2010-11-11 09:02:50 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-12 08:42:55 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-11-11 09:02:50 +01:00
2010-03-12 08:42:55 +01:00
//check command
2012-11-10 20:39:55 +01:00
result = checkCommand ( command ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugUnitCommands ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] checkCommand returned: [%d] \n " , __FILE__ , __FUNCTION__ , __LINE__ , result . first ) ;
2010-11-09 10:06:52 +01:00
2012-03-20 05:53:26 +01:00
//printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n[%s]\n\n",__FILE__,__FUNCTION__,__LINE__,result,commands.size(),command->toString().c_str());
2010-11-11 09:02:50 +01:00
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-11-11 09:02:50 +01:00
2012-11-10 20:39:55 +01:00
if ( result . first = = crSuccess ) {
2010-03-12 08:42:55 +01:00
applyCommand ( command ) ;
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-11-11 09:02:50 +01:00
2010-03-12 08:42:55 +01:00
//push back command
2012-11-10 20:39:55 +01:00
if ( result . first = = crSuccess ) {
2011-07-05 17:43:39 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-05 17:43:39 +02:00
2010-03-12 08:42:55 +01:00
commands . push_back ( command ) ;
2011-07-05 17:43:39 +02:00
safeMutex . ReleaseLock ( ) ;
2010-03-12 08:42:55 +01:00
}
2010-05-31 08:11:31 +02:00
else {
2010-03-12 08:42:55 +01:00
delete command ;
2011-10-28 06:37:10 +02:00
changedActiveCommand = false ;
2010-03-12 08:42:55 +01:00
}
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled & & chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-12 08:42:55 +01:00
return result ;
}
//pop front (used when order is done)
2010-09-01 01:14:15 +02:00
CommandResult Unit : : finishCommand ( ) {
2011-10-28 06:37:10 +02:00
changedActiveCommand = false ;
2010-08-28 03:46:26 +02:00
retryCurrCommandCount = 0 ;
2010-09-01 01:14:15 +02:00
this - > setCurrentUnitTitle ( " " ) ;
2010-03-12 08:42:55 +01:00
//is empty?
2011-01-08 22:53:05 +01:00
if ( commands . empty ( ) ) {
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-12 08:42:55 +01:00
return crFailUndefined ;
}
//pop front
2011-07-05 17:43:39 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-05 17:43:39 +02:00
2010-03-12 08:42:55 +01:00
delete commands . front ( ) ;
commands . erase ( commands . begin ( ) ) ;
2011-07-06 08:38:56 +02:00
safeMutex . ReleaseLock ( true ) ;
2010-07-21 20:21:40 +02:00
this - > unitPath - > clear ( ) ;
2010-03-12 08:42:55 +01:00
2011-01-08 22:53:05 +01:00
while ( commands . empty ( ) = = false ) {
2011-09-27 19:15:56 +02:00
if ( commands . front ( ) - > getUnit ( ) ! = NULL & & this - > faction - > isUnitInLivingUnitsp ( commands . front ( ) - > getUnit ( ) ) = = false ) {
2011-07-06 08:38:56 +02:00
safeMutex . Lock ( ) ;
2010-04-18 09:35:48 +02:00
delete commands . front ( ) ;
commands . erase ( commands . begin ( ) ) ;
2011-07-06 08:38:56 +02:00
safeMutex . ReleaseLock ( true ) ;
}
else {
2010-04-18 09:35:48 +02:00
break ;
}
}
2010-03-12 08:42:55 +01:00
return crSuccess ;
}
//to cancel a command
2010-09-01 01:14:15 +02:00
CommandResult Unit : : cancelCommand ( ) {
2011-10-28 06:37:10 +02:00
changedActiveCommand = false ;
2010-08-28 03:46:26 +02:00
retryCurrCommandCount = 0 ;
2010-09-01 01:14:15 +02:00
this - > setCurrentUnitTitle ( " " ) ;
2010-03-12 08:42:55 +01:00
//is empty?
if ( commands . empty ( ) ) {
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-12 08:42:55 +01:00
return crFailUndefined ;
}
//undo command
undoCommand ( commands . back ( ) ) ;
//delete ans pop command
2011-07-05 17:43:39 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-05 17:43:39 +02:00
2010-03-12 08:42:55 +01:00
delete commands . back ( ) ;
commands . pop_back ( ) ;
2011-07-06 08:38:56 +02:00
safeMutex . ReleaseLock ( ) ;
2010-03-12 08:42:55 +01:00
//clear routes
2010-07-21 20:21:40 +02:00
this - > unitPath - > clear ( ) ;
2010-03-12 08:42:55 +01:00
2011-07-06 08:38:56 +02:00
2011-07-05 20:26:09 +02:00
2010-03-12 08:42:55 +01:00
return crSuccess ;
}
// =================== route stack ===================
2012-03-27 05:23:03 +02:00
void Unit : : create ( bool startingUnit ) {
2010-03-12 08:42:55 +01:00
faction - > addUnit ( this ) ;
map - > putUnitCells ( this , pos ) ;
2012-03-27 05:23:03 +02:00
if ( startingUnit ) {
faction - > applyStaticCosts ( type , NULL ) ;
2010-03-12 08:42:55 +01:00
}
}
2012-03-27 05:23:03 +02:00
void Unit : : born ( const CommandType * ct ) {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
faction - > addStore ( type ) ;
2012-03-27 05:23:03 +02:00
faction - > applyStaticProduction ( type , ct ) ;
2010-03-12 08:42:55 +01:00
setCurrSkill ( scStop ) ;
2010-06-14 08:38:24 +02:00
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
hp = type - > getMaxHp ( ) ;
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
}
2010-10-30 10:54:00 +02:00
void Unit : : kill ( ) {
2010-03-12 08:42:55 +01:00
//no longer needs static resources
2010-10-30 10:54:00 +02:00
if ( isBeingBuilt ( ) ) {
2012-03-27 05:23:03 +02:00
faction - > deApplyStaticConsumption ( type , ( getCurrCommand ( ) ! = NULL ? getCurrCommand ( ) - > getCommandType ( ) : NULL ) ) ;
2010-03-12 08:42:55 +01:00
}
2010-10-30 10:54:00 +02:00
else {
2012-03-27 05:23:03 +02:00
faction - > deApplyStaticCosts ( type , ( getCurrCommand ( ) ! = NULL ? getCurrCommand ( ) - > getCommandType ( ) : NULL ) ) ;
2010-03-12 08:42:55 +01:00
}
//do the cleaning
2012-09-15 01:46:01 +02:00
//clear commands ( and their blocking fields )
clearCommands ( ) ;
map - > clearUnitCells ( this , pos , true ) ;
2010-10-30 10:54:00 +02:00
if ( isBeingBuilt ( ) = = false ) {
2010-03-12 08:42:55 +01:00
faction - > removeStore ( type ) ;
}
setCurrSkill ( scDie ) ;
notifyObservers ( UnitObserver : : eKill ) ;
2011-03-18 22:23:34 +01:00
UnitUpdater * unitUpdater = game - > getWorld ( ) - > getUnitUpdater ( ) ;
2011-03-29 12:01:01 +02:00
//unitUpdater->clearUnitPrecache(this);
unitUpdater - > removeUnitPrecache ( this ) ;
2010-03-12 08:42:55 +01:00
}
2010-04-20 04:19:37 +02:00
void Unit : : undertake ( ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > id , this - > getFullName ( ) . c_str ( ) , this - > getDesc ( ) . c_str ( ) ) ;
2010-04-20 04:19:37 +02:00
2011-06-25 16:18:53 +02:00
// Remove any units that were previously in attack-boost range
2011-09-01 03:11:23 +02:00
if ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . empty ( ) = = false & & currentAttackBoostOriginatorEffect . skillType ! = NULL ) {
2011-06-25 22:44:46 +02:00
for ( unsigned int i = 0 ; i < currentAttackBoostOriginatorEffect . currentAttackBoostUnits . size ( ) ; + + i ) {
2011-06-25 16:18:53 +02:00
// Remove attack boost upgrades from unit
2011-07-06 07:16:25 +02:00
int findUnitId = currentAttackBoostOriginatorEffect . currentAttackBoostUnits [ i ] ;
Unit * affectedUnit = game - > getWorld ( ) - > findUnitById ( findUnitId ) ;
if ( affectedUnit ! = NULL ) {
affectedUnit - > deapplyAttackBoost ( currentAttackBoostOriginatorEffect . skillType - > getAttackBoost ( ) , this ) ;
}
2011-06-25 16:18:53 +02:00
//printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
2011-06-25 22:44:46 +02:00
currentAttackBoostOriginatorEffect . currentAttackBoostUnits . clear ( ) ;
2011-06-25 16:18:53 +02:00
}
2011-03-18 22:23:34 +01:00
UnitUpdater * unitUpdater = game - > getWorld ( ) - > getUnitUpdater ( ) ;
2011-03-29 12:01:01 +02:00
//unitUpdater->clearUnitPrecache(this);
unitUpdater - > removeUnitPrecache ( this ) ;
2011-03-18 22:23:34 +01:00
2011-09-27 19:15:56 +02:00
this - > faction - > deleteLivingUnits ( id ) ;
this - > faction - > deleteLivingUnitsp ( this ) ;
2010-03-12 08:42:55 +01:00
faction - > removeUnit ( this ) ;
}
// =================== Referencers ===================
void Unit : : addObserver ( UnitObserver * unitObserver ) {
observers . push_back ( unitObserver ) ;
}
void Unit : : removeObserver ( UnitObserver * unitObserver ) {
observers . remove ( unitObserver ) ;
}
void Unit : : notifyObservers ( UnitObserver : : Event event ) {
for ( Observers : : iterator it = observers . begin ( ) ; it ! = observers . end ( ) ; + + it ) {
( * it ) - > unitEvent ( event , this ) ;
}
}
// =================== Other ===================
void Unit : : resetHighlight ( ) {
highlight = 1.f ;
}
const CommandType * Unit : : computeCommandType ( const Vec2i & pos , const Unit * targetUnit ) const {
const CommandType * commandType = NULL ;
2011-02-23 08:03:38 +01:00
if ( map - > isInside ( pos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( pos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #6 Invalid path position = " + pos . getString ( ) ) ;
2011-02-23 08:03:38 +01:00
}
2010-03-12 08:42:55 +01:00
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( pos ) ) ;
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
if ( targetUnit ! = NULL ) {
//attack enemies
if ( ! isAlly ( targetUnit ) ) {
commandType = type - > getFirstAttackCommand ( targetUnit - > getCurrField ( ) ) ;
}
//repair allies
else {
commandType = type - > getFirstRepairCommand ( targetUnit - > getType ( ) ) ;
}
}
else {
//check harvest command
Resource * resource = sc - > getResource ( ) ;
if ( resource ! = NULL ) {
2010-10-02 03:11:59 +02:00
commandType = type - > getFirstHarvestCommand ( resource - > getType ( ) , this - > getFaction ( ) ) ;
2010-03-12 08:42:55 +01:00
}
}
//default command is move command
if ( commandType = = NULL ) {
commandType = type - > getFirstCtOfClass ( ccMove ) ;
}
return commandType ;
}
2011-03-18 04:53:06 +01:00
bool Unit : : needToUpdate ( ) {
assert ( progress < = 1.f ) ;
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2011-03-18 04:53:06 +01:00
}
2011-03-19 13:04:18 +01:00
bool return_value = false ;
if ( currSkill - > getClass ( ) ! = scDie ) {
//speed
int speed = currSkill - > getTotalSpeed ( & totalUpgrade ) ;
2011-03-18 04:53:06 +01:00
2011-10-28 03:11:42 +02:00
if ( changedActiveCommand ) {
2011-10-28 03:22:36 +02:00
speed = CHANGE_COMMAND_SPEED ;
2011-10-28 03:11:42 +02:00
}
2011-03-19 13:04:18 +01:00
//speed modifier
float diagonalFactor = 1.f ;
float heightFactor = 1.f ;
if ( currSkill - > getClass ( ) = = scMove ) {
//if moving in diagonal move slower
Vec2i dest = pos - lastPos ;
if ( abs ( dest . x ) + abs ( dest . y ) = = 2 ) {
diagonalFactor = 0.71f ;
}
2011-03-18 04:53:06 +01:00
2011-03-19 13:04:18 +01:00
//if moving to an higher cell move slower else move faster
float heightDiff = map - > getCell ( pos ) - > getHeight ( ) - map - > getCell ( targetPos ) - > getHeight ( ) ;
heightFactor = clamp ( 1.f + heightDiff / 5.f , 0.2f , 5.f ) ;
}
2011-03-18 04:53:06 +01:00
2011-03-19 13:04:18 +01:00
//update progresses
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
2011-03-24 22:55:39 +01:00
float speedDenominator = ( speedDivider * game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
float newProgress = progress ;
newProgress + = ( speed * diagonalFactor * heightFactor ) / speedDenominator ;
2011-03-18 04:53:06 +01:00
2011-03-19 13:04:18 +01:00
if ( newProgress > = 1.f ) {
2011-03-18 04:53:06 +01:00
return_value = true ;
}
}
return return_value ;
}
2011-08-27 08:52:17 +02:00
void Unit : : updateTimedParticles ( ) {
//!!!
// Start new particle systems based on start time
2013-01-03 18:30:59 +01:00
if ( queuedUnitParticleSystemTypes . empty ( ) = = false ) {
for ( int i = queuedUnitParticleSystemTypes . size ( ) - 1 ; i > = 0 ; i - - ) {
UnitParticleSystemType * pst = queuedUnitParticleSystemTypes [ i ] ;
if ( pst ! = NULL ) {
if ( truncateDecimal < float > ( pst - > getStartTime ( ) ) < = truncateDecimal < float > ( animProgress ) ) {
//printf("STARTING queued particle system type [%s] [%f] [%f] [%f] [%f]\n",pst->getType().c_str(),truncateDecimal<float>(pst->getStartTime()),truncateDecimal<float>(pst->getEndTime()),truncateDecimal<float>(animProgress),truncateDecimal<float>(lastAnimProgress));
UnitParticleSystem * ups = new UnitParticleSystem ( 200 ) ;
pst - > setValues ( ups ) ;
ups - > setPos ( getCurrVector ( ) ) ;
if ( getFaction ( ) - > getTexture ( ) ) {
ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
unitParticleSystems . push_back ( ups ) ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
2011-08-27 08:52:17 +02:00
2013-01-03 18:30:59 +01:00
queuedUnitParticleSystemTypes . erase ( queuedUnitParticleSystemTypes . begin ( ) + i ) ;
2011-09-27 09:01:08 +02:00
}
2013-01-03 18:30:59 +01:00
}
else {
2011-08-27 08:52:17 +02:00
queuedUnitParticleSystemTypes . erase ( queuedUnitParticleSystemTypes . begin ( ) + i ) ;
}
}
}
// End existing systems based on end time
2013-01-03 18:30:59 +01:00
if ( unitParticleSystems . empty ( ) = = false ) {
for ( int i = unitParticleSystems . size ( ) - 1 ; i > = 0 ; i - - ) {
UnitParticleSystem * ps = unitParticleSystems [ i ] ;
if ( ps ! = NULL ) {
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
if ( truncateDecimal < float > ( ps - > getStartTime ( ) ) ! = 0.0 | | truncateDecimal < float > ( ps - > getEndTime ( ) ) ! = 1.0 ) {
//printf("Checking for end particle system #%d [%d] [%f] [%f] [%f] [%f]\n",i,ps->shape,truncateDecimal<float>(ps->getStartTime()),truncateDecimal<float>(ps->getEndTime()),truncateDecimal<float>(animProgress),truncateDecimal<float>(lastAnimProgress));
if ( truncateDecimal < float > ( animProgress ) > = 0.99 | |
truncateDecimal < float > ( animProgress ) > = truncateDecimal < float > ( ps - > getEndTime ( ) ) ) {
//printf("ENDING particle system [%d]\n",ps->shape);
ps - > fade ( ) ;
unitParticleSystems . erase ( unitParticleSystems . begin ( ) + i ) ;
}
2011-11-05 06:45:02 +01:00
}
2011-08-27 08:52:17 +02:00
}
}
}
}
}
2010-09-07 07:25:40 +02:00
bool Unit : : update ( ) {
2011-03-19 13:04:18 +01:00
assert ( progress < = 1.f ) ;
2010-03-12 08:42:55 +01:00
//highlight
2011-03-19 13:04:18 +01:00
if ( highlight > 0.f ) {
2010-08-24 03:21:34 +02:00
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
2012-04-04 02:30:16 +02:00
highlight - = 1.f / ( Game : : highlightTime * game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
2010-03-12 08:42:55 +01:00
}
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
//speed
int speed = currSkill - > getTotalSpeed ( & totalUpgrade ) ;
2011-10-28 03:11:42 +02:00
if ( changedActiveCommand ) {
2011-10-28 03:22:36 +02:00
speed = CHANGE_COMMAND_SPEED ;
2011-10-28 03:11:42 +02:00
}
2010-03-12 08:42:55 +01:00
//speed modifier
2011-03-19 13:04:18 +01:00
float diagonalFactor = 1.f ;
float heightFactor = 1.f ;
2010-10-30 10:54:00 +02:00
if ( currSkill - > getClass ( ) = = scMove ) {
2010-03-12 08:42:55 +01:00
//if moving in diagonal move slower
2011-03-19 13:04:18 +01:00
Vec2i dest = pos - lastPos ;
if ( abs ( dest . x ) + abs ( dest . y ) = = 2 ) {
diagonalFactor = 0.71f ;
2010-03-12 08:42:55 +01:00
}
2011-03-19 13:04:18 +01:00
//if moving to an higher cell move slower else move faster
float heightDiff = map - > getCell ( pos ) - > getHeight ( ) - map - > getCell ( targetPos ) - > getHeight ( ) ;
heightFactor = clamp ( 1.f + heightDiff / 5.f , 0.2f , 5.f ) ;
2010-03-12 08:42:55 +01:00
}
//update progresses
lastAnimProgress = animProgress ;
2010-08-24 03:21:34 +02:00
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
2011-03-24 22:55:39 +01:00
float speedDenominator = ( speedDivider * game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
progress + = ( speed * diagonalFactor * heightFactor ) / speedDenominator ;
2011-07-08 01:02:46 +02:00
if ( isAnimProgressBound ( ) = = true ) {
2011-07-13 22:54:04 +02:00
float targetProgress = 0 ;
2011-07-13 21:57:29 +02:00
if ( currSkill - > getClass ( ) = = scBeBuilt ) {
2011-07-13 22:54:04 +02:00
targetProgress = this - > getHpRatio ( ) ;
2011-07-13 21:57:29 +02:00
}
if ( currSkill - > getClass ( ) = = scProduce ) {
2011-07-13 22:54:04 +02:00
targetProgress = this - > getProgressRatio ( ) ;
2011-07-13 21:57:29 +02:00
}
if ( currSkill - > getClass ( ) = = scUpgrade ) {
2011-07-13 22:54:04 +02:00
targetProgress = this - > getProgressRatio ( ) ;
2011-07-13 21:57:29 +02:00
}
if ( currSkill - > getClass ( ) = = scMorph ) {
2011-07-13 22:54:04 +02:00
targetProgress = this - > getProgressRatio ( ) ;
}
if ( animProgress < targetProgress ) {
float diff = targetProgress - animProgress ;
animProgress = animProgress + diff / ( GameConstants : : updateFps ) ;
2011-07-13 21:57:29 +02:00
}
2011-07-02 18:07:04 +02:00
}
2011-07-13 21:57:29 +02:00
else {
2011-07-02 18:07:04 +02:00
animProgress + = ( currSkill - > getAnimSpeed ( ) * heightFactor ) / speedDenominator ;
}
2010-03-12 08:42:55 +01:00
//update target
updateTarget ( ) ;
//rotation
2010-10-30 10:54:00 +02:00
if ( currSkill - > getClass ( ) ! = scStop ) {
2010-03-12 08:42:55 +01:00
const int rotFactor = 2 ;
2011-03-19 13:04:18 +01:00
if ( progress < 1.f / rotFactor ) {
2010-03-12 08:42:55 +01:00
if ( type - > getFirstStOfClass ( scMove ) ) {
2010-04-27 22:38:34 +02:00
if ( abs ( ( int ) ( lastRotation - targetRotation ) ) < 180 )
2011-03-19 13:04:18 +01:00
rotation = lastRotation + ( targetRotation - lastRotation ) * progress * rotFactor ;
else {
float rotationTerm = targetRotation > lastRotation ? - 360.f : + 360.f ;
rotation = lastRotation + ( targetRotation - lastRotation + rotationTerm ) * progress * rotFactor ;
2010-03-12 08:42:55 +01:00
}
}
}
}
2011-07-12 01:59:16 +02:00
if ( type - > getProperty ( UnitType : : pRotatedClimb ) ) {
calculateXZRotation ( ) ;
}
2011-07-16 19:33:48 +02:00
else {
rotationZ = .0f ;
rotationX = .0f ;
}
2011-07-12 01:59:16 +02:00
2010-09-07 19:30:13 +02:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( fire , rsGame ) = = false ) {
fire = NULL ;
}
if ( fire ! = NULL ) {
2010-03-12 08:42:55 +01:00
fire - > setPos ( getCurrVector ( ) ) ;
}
2010-09-06 19:52:33 +02:00
for ( UnitParticleSystems : : iterator it = unitParticleSystems . begin ( ) ; it ! = unitParticleSystems . end ( ) ; + + it ) {
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ( * it ) , rsGame ) = = true ) {
( * it ) - > setPos ( getCurrVector ( ) ) ;
( * it ) - > setRotation ( getRotation ( ) ) ;
}
2010-03-12 08:42:55 +01:00
}
2010-09-06 19:52:33 +02:00
for ( UnitParticleSystems : : iterator it = damageParticleSystems . begin ( ) ; it ! = damageParticleSystems . end ( ) ; + + it ) {
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ( * it ) , rsGame ) = = true ) {
( * it ) - > setPos ( getCurrVector ( ) ) ;
( * it ) - > setRotation ( getRotation ( ) ) ;
}
2010-03-12 08:42:55 +01:00
}
2011-03-24 22:55:39 +01:00
2011-07-04 17:55:13 +02:00
for ( UnitParticleSystems : : iterator it = smokeParticleSystems . begin ( ) ; it ! = smokeParticleSystems . end ( ) ; + + it ) {
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ( * it ) , rsGame ) = = true ) {
( * it ) - > setPos ( getCurrVector ( ) ) ;
( * it ) - > setRotation ( getRotation ( ) ) ;
}
2011-07-04 17:55:13 +02:00
}
2011-06-25 22:44:46 +02:00
for ( unsigned int i = 0 ; i < currentAttackBoostEffects . size ( ) ; + + i ) {
2011-07-06 07:16:25 +02:00
UnitAttackBoostEffect * effect = currentAttackBoostEffects [ i ] ;
if ( effect ! = NULL & & effect - > ups ! = NULL ) {
2011-10-30 07:12:40 +01:00
bool particleValid = Renderer : : getInstance ( ) . validateParticleSystemStillExists ( effect - > ups , rsGame ) ;
if ( particleValid = = true ) {
effect - > ups - > setPos ( getCurrVector ( ) ) ;
effect - > ups - > setRotation ( getRotation ( ) ) ;
}
2011-06-25 22:44:46 +02:00
}
}
if ( currentAttackBoostOriginatorEffect . currentAppliedEffect ! = NULL ) {
if ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups ! = NULL ) {
2011-10-30 07:12:40 +01:00
bool particleValid = Renderer : : getInstance ( ) . validateParticleSystemStillExists ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups , rsGame ) ;
if ( particleValid = = true ) {
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setPos ( getCurrVector ( ) ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setRotation ( getRotation ( ) ) ;
}
2011-06-25 22:44:46 +02:00
}
}
2010-03-12 08:42:55 +01:00
//checks
2011-03-19 13:04:18 +01:00
if ( animProgress > 1.f ) {
2011-06-25 23:40:27 +02:00
bool canCycle = currSkill - > CanCycleNextRandomAnimation ( & animationRandomCycleCount ) ;
2011-03-19 13:04:18 +01:00
animProgress = currSkill - > getClass ( ) = = scDie ? 1.f : 0.f ;
2011-06-25 23:40:27 +02:00
if ( canCycle = = true ) {
this - > lastModelIndexForCurrSkillType = - 1 ;
}
2010-03-12 08:42:55 +01:00
}
2010-03-18 22:26:40 +01:00
bool return_value = false ;
2010-03-12 08:42:55 +01:00
//checks
2011-03-19 13:04:18 +01:00
if ( progress > = 1.f ) {
2010-03-12 08:42:55 +01:00
lastRotation = targetRotation ;
2010-10-30 10:54:00 +02:00
if ( currSkill - > getClass ( ) ! = scDie ) {
2011-03-19 13:04:18 +01:00
progress = 0.f ;
2010-03-18 22:26:40 +01:00
return_value = true ;
2010-03-12 08:42:55 +01:00
}
2010-09-06 19:52:33 +02:00
else {
2010-03-12 08:42:55 +01:00
progress = 1.f ;
deadCount + + ;
2011-03-19 13:04:18 +01:00
if ( deadCount > = maxDeadCount ) {
2010-03-12 08:42:55 +01:00
toBeUndertaken = true ;
2010-03-18 22:26:40 +01:00
return_value = false ;
2010-03-12 08:42:55 +01:00
}
}
}
2011-06-25 22:44:46 +02:00
if ( currSkill ! = currentAttackBoostOriginatorEffect . skillType ) {
if ( currentAttackBoostOriginatorEffect . currentAppliedEffect ! = NULL ) {
delete currentAttackBoostOriginatorEffect . currentAppliedEffect ;
currentAttackBoostOriginatorEffect . currentAppliedEffect = NULL ;
2011-06-25 10:53:53 +02:00
2011-06-25 22:44:46 +02:00
//printf("- #1 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
// Remove any units that were previously in range
2011-09-01 03:11:23 +02:00
if ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . empty ( ) = = false & & currentAttackBoostOriginatorEffect . skillType ! = NULL ) {
2011-06-25 22:44:46 +02:00
for ( unsigned int i = 0 ; i < currentAttackBoostOriginatorEffect . currentAttackBoostUnits . size ( ) ; + + i ) {
// Remove attack boost upgrades from unit
2011-07-06 07:16:25 +02:00
int findUnitId = currentAttackBoostOriginatorEffect . currentAttackBoostUnits [ i ] ;
Unit * affectedUnit = game - > getWorld ( ) - > findUnitById ( findUnitId ) ;
if ( affectedUnit ! = NULL ) {
affectedUnit - > deapplyAttackBoost ( currentAttackBoostOriginatorEffect . skillType - > getAttackBoost ( ) , this ) ;
}
2011-06-25 22:44:46 +02:00
//printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
currentAttackBoostOriginatorEffect . currentAttackBoostUnits . clear ( ) ;
}
currentAttackBoostOriginatorEffect . skillType = currSkill ;
if ( currSkill - > isAttackBoostEnabled ( ) = = true ) {
// Search for units in range of this unit which apply to the
// attack-boost and temporarily upgrade them
UnitUpdater * unitUpdater = this - > game - > getWorld ( ) - > getUnitUpdater ( ) ;
const AttackBoost * attackBoost = currSkill - > getAttackBoost ( ) ;
vector < Unit * > candidates = unitUpdater - > findUnitsInRange ( this , attackBoost - > radius ) ;
for ( unsigned int i = 0 ; i < candidates . size ( ) ; + + i ) {
Unit * affectedUnit = candidates [ i ] ;
if ( attackBoost - > isAffected ( this , affectedUnit ) = = true ) {
if ( affectedUnit - > applyAttackBoost ( attackBoost , this ) = = true ) {
2011-07-06 07:16:25 +02:00
currentAttackBoostOriginatorEffect . currentAttackBoostUnits . push_back ( affectedUnit - > getId ( ) ) ;
2011-06-25 22:44:46 +02:00
//printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
if ( showUnitParticles = = true ) {
2011-09-01 03:11:23 +02:00
if ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . empty ( ) = = false ) {
2011-06-25 22:44:46 +02:00
if ( attackBoost - > unitParticleSystemTypeForSourceUnit ! = NULL ) {
currentAttackBoostOriginatorEffect . currentAppliedEffect = new UnitAttackBoostEffect ( ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > upst = new UnitParticleSystemType ( ) ;
* currentAttackBoostOriginatorEffect . currentAppliedEffect - > upst = * attackBoost - > unitParticleSystemTypeForSourceUnit ;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups = new UnitParticleSystem ( 200 ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > upst - > setValues ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setPos ( getCurrVector ( ) ) ;
2011-09-27 09:01:08 +02:00
if ( getFaction ( ) - > getTexture ( ) ) {
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
2011-06-25 22:44:46 +02:00
Renderer : : getInstance ( ) . manageParticleSystem ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups , rsGame ) ;
//printf("+ #1 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
}
}
2011-06-25 10:53:53 +02:00
}
}
2011-06-25 22:44:46 +02:00
else {
if ( currSkill - > isAttackBoostEnabled ( ) = = true ) {
// Search for units in range of this unit which apply to the
// attack-boost and temporarily upgrade them
UnitUpdater * unitUpdater = this - > game - > getWorld ( ) - > getUnitUpdater ( ) ;
const AttackBoost * attackBoost = currSkill - > getAttackBoost ( ) ;
vector < Unit * > candidates = unitUpdater - > findUnitsInRange ( this , attackBoost - > radius ) ;
for ( unsigned int i = 0 ; i < candidates . size ( ) ; + + i ) {
Unit * affectedUnit = candidates [ i ] ;
2011-07-06 07:16:25 +02:00
std : : vector < int > : : iterator iterFound = std : : find ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . begin ( ) , currentAttackBoostOriginatorEffect . currentAttackBoostUnits . end ( ) , affectedUnit - > getId ( ) ) ;
2011-06-25 22:44:46 +02:00
if ( attackBoost - > isAffected ( this , affectedUnit ) = = true ) {
if ( iterFound = = currentAttackBoostOriginatorEffect . currentAttackBoostUnits . end ( ) ) {
if ( affectedUnit - > applyAttackBoost ( attackBoost , this ) = = true ) {
2011-07-06 07:16:25 +02:00
currentAttackBoostOriginatorEffect . currentAttackBoostUnits . push_back ( affectedUnit - > getId ( ) ) ;
2011-06-25 22:44:46 +02:00
//printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
else {
if ( iterFound ! = currentAttackBoostOriginatorEffect . currentAttackBoostUnits . end ( ) ) {
affectedUnit - > deapplyAttackBoost ( currentAttackBoostOriginatorEffect . skillType - > getAttackBoost ( ) , this ) ;
currentAttackBoostOriginatorEffect . currentAttackBoostUnits . erase ( iterFound ) ;
//printf("- #2 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
if ( showUnitParticles = = true ) {
2011-09-01 03:11:23 +02:00
if ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . empty ( ) = = false ) {
2011-06-25 22:44:46 +02:00
if ( attackBoost - > unitParticleSystemTypeForSourceUnit ! = NULL & &
currentAttackBoostOriginatorEffect . currentAppliedEffect = = NULL ) {
2011-06-25 10:53:53 +02:00
2011-06-25 22:44:46 +02:00
currentAttackBoostOriginatorEffect . currentAppliedEffect = new UnitAttackBoostEffect ( ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > upst = new UnitParticleSystemType ( ) ;
* currentAttackBoostOriginatorEffect . currentAppliedEffect - > upst = * attackBoost - > unitParticleSystemTypeForSourceUnit ;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
2011-06-25 10:53:53 +02:00
2011-06-25 22:44:46 +02:00
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups = new UnitParticleSystem ( 200 ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > upst - > setValues ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups ) ;
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setPos ( getCurrVector ( ) ) ;
2011-09-27 09:01:08 +02:00
if ( getFaction ( ) - > getTexture ( ) ) {
currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
2011-06-25 22:44:46 +02:00
Renderer : : getInstance ( ) . manageParticleSystem ( currentAttackBoostOriginatorEffect . currentAppliedEffect - > ups , rsGame ) ;
2011-06-25 10:53:53 +02:00
2011-06-25 22:44:46 +02:00
//printf("+ #2 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
}
2012-10-06 09:06:40 +02:00
else if ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . empty ( ) = = true ) {
2011-06-25 22:44:46 +02:00
if ( currentAttackBoostOriginatorEffect . currentAppliedEffect ! = NULL ) {
delete currentAttackBoostOriginatorEffect . currentAppliedEffect ;
currentAttackBoostOriginatorEffect . currentAppliedEffect = NULL ;
2011-06-25 10:53:53 +02:00
2011-06-25 22:44:46 +02:00
//printf("- #2 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
}
2011-06-25 10:53:53 +02:00
}
}
}
2011-10-29 00:49:00 +02:00
if ( return_value ) {
changedActiveCommand = false ;
}
2010-03-18 22:26:40 +01:00
return return_value ;
2010-03-12 08:42:55 +01:00
}
2011-06-25 22:44:46 +02:00
bool Unit : : unitHasAttackBoost ( const AttackBoost * boost , const Unit * source ) const {
bool result = false ;
for ( unsigned int i = 0 ; i < currentAttackBoostEffects . size ( ) ; + + i ) {
2011-07-06 07:16:25 +02:00
const UnitAttackBoostEffect * effect = currentAttackBoostEffects [ i ] ;
2011-11-11 05:17:55 +01:00
if ( effect ! = NULL & & effect - > boost - > name = = boost - > name & &
2011-07-06 07:16:25 +02:00
effect - > source - > getType ( ) - > getId ( ) = = source - > getType ( ) - > getId ( ) ) {
2011-06-25 22:44:46 +02:00
result = true ;
break ;
}
}
return result ;
}
bool Unit : : applyAttackBoost ( const AttackBoost * boost , const Unit * source ) {
if ( boost = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2011-06-25 22:44:46 +02:00
}
//printf("APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
bool shouldApplyAttackBoost = true ;
if ( boost - > allowMultipleBoosts = = false ) {
// Check if we already have this boost from this unit type and multiples
// are not allowed
bool alreadyHasAttackBoost = this - > unitHasAttackBoost ( boost , source ) ;
if ( alreadyHasAttackBoost = = true ) {
shouldApplyAttackBoost = false ;
}
}
if ( shouldApplyAttackBoost = = true ) {
2011-07-06 07:16:25 +02:00
//printf("APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
UnitAttackBoostEffect * effect = new UnitAttackBoostEffect ( ) ;
effect - > boost = boost ;
effect - > source = source ;
2011-06-25 22:44:46 +02:00
2011-07-02 02:20:28 +02:00
bool wasAlive = alive ;
2011-11-16 22:38:12 +01:00
int originalHp = hp ;
2011-07-02 02:20:28 +02:00
int prevMaxHp = totalUpgrade . getMaxHp ( ) ;
2011-07-22 09:05:47 +02:00
int prevMaxHpRegen = totalUpgrade . getMaxHpRegeneration ( ) ;
2011-07-02 02:20:28 +02:00
//printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp());
2011-06-25 22:44:46 +02:00
2011-07-02 02:20:28 +02:00
totalUpgrade . apply ( & boost - > boostUpgrade , this ) ;
checkItemInVault ( & this - > hp , this - > hp ) ;
//hp += boost->boostUpgrade.getMaxHp();
hp + = ( totalUpgrade . getMaxHp ( ) - prevMaxHp ) ;
addItemToVault ( & this - > hp , this - > hp ) ;
2011-07-22 09:05:47 +02:00
//regenerate hp upgrade / or boost
if ( totalUpgrade . getMaxHpRegeneration ( ) ! = 0 ) {
checkItemInVault ( & this - > hp , this - > hp ) ;
2011-07-22 22:06:48 +02:00
//printf("BEFORE Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp);
2011-07-22 09:05:47 +02:00
hp + = ( totalUpgrade . getMaxHpRegeneration ( ) - prevMaxHpRegen ) ;
2011-07-22 22:06:48 +02:00
//if(hp > type->getTotalMaxHp(&totalUpgrade)) {
// hp = type->getTotalMaxHp(&totalUpgrade);
//}
2011-07-22 09:05:47 +02:00
addItemToVault ( & this - > hp , this - > hp ) ;
2011-07-22 22:06:48 +02:00
//printf("AFTER Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp);
2011-07-22 09:05:47 +02:00
}
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-11-16 22:38:12 +01:00
if ( originalHp < hp ) {
this - > setLastAttackerUnitId ( source - > getId ( ) ) ;
}
2011-07-02 02:20:28 +02:00
//printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp());
2011-07-06 07:16:25 +02:00
if ( showUnitParticles = = true ) {
2011-07-12 02:58:09 +02:00
if ( boost - > unitParticleSystemTypeForAffectedUnit ! = NULL ) {
effect - > upst = new UnitParticleSystemType ( ) ;
* effect - > upst = * boost - > unitParticleSystemTypeForAffectedUnit ;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
effect - > ups = new UnitParticleSystem ( 200 ) ;
effect - > upst - > setValues ( effect - > ups ) ;
effect - > ups - > setPos ( getCurrVector ( ) ) ;
2011-09-27 09:01:08 +02:00
if ( getFaction ( ) - > getTexture ( ) ) {
effect - > ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
2011-07-12 02:58:09 +02:00
Renderer : : getInstance ( ) . manageParticleSystem ( effect - > ups , rsGame ) ;
}
2011-07-06 07:16:25 +02:00
}
currentAttackBoostEffects . push_back ( effect ) ;
2011-07-02 02:20:28 +02:00
if ( wasAlive = = true ) {
//startDamageParticles
2012-12-29 02:01:14 +01:00
if ( originalHp > hp ) {
startDamageParticles ( ) ;
}
2011-07-02 02:20:28 +02:00
//stop DamageParticles on death
if ( hp < = 0 ) {
alive = false ;
hp = 0 ;
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-07-02 02:20:28 +02:00
stopDamageParticles ( true ) ;
2011-11-16 22:38:12 +01:00
this - > setLastAttackerUnitId ( source - > getId ( ) ) ;
this - > setCauseOfDeath ( ucodAttackBoost ) ;
2012-03-31 01:38:05 +02:00
Unit : : game - > getWorld ( ) - > getStats ( ) - > die ( getFactionIndex ( ) , getType ( ) - > getCountUnitDeathInStats ( ) ) ;
2011-07-02 02:20:28 +02:00
game - > getScriptManager ( ) - > onUnitDied ( this ) ;
StaticSound * sound = this - > getType ( ) - > getFirstStOfClass ( scDie ) - > getSound ( ) ;
if ( sound ! = NULL & &
( this - > getFactionIndex ( ) = = Unit : : game - > getWorld ( ) - > getThisFactionIndex ( ) | |
2011-10-12 18:03:55 +02:00
( game - > getWorld ( ) - > showWorldForPlayer ( game - > getWorld ( ) - > getThisTeamIndex ( ) ) = = true ) ) ) {
2011-07-02 02:20:28 +02:00
SoundRenderer : : getInstance ( ) . playFx ( sound ) ;
}
if ( this - > isDead ( ) & & this - > getCurrSkill ( ) - > getClass ( ) ! = scDie ) {
this - > kill ( ) ;
}
}
}
2011-06-25 22:44:46 +02:00
2011-07-06 07:16:25 +02:00
//printf("APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
2011-06-25 22:44:46 +02:00
}
return shouldApplyAttackBoost ;
}
void Unit : : deapplyAttackBoost ( const AttackBoost * boost , const Unit * source ) {
if ( boost = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2011-06-25 22:44:46 +02:00
}
2011-07-06 07:16:25 +02:00
//printf("DE-APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
2011-06-25 22:44:46 +02:00
2011-07-02 02:20:28 +02:00
bool wasAlive = alive ;
2011-11-16 22:38:12 +01:00
int originalHp = hp ;
2011-07-02 02:20:28 +02:00
int prevMaxHp = totalUpgrade . getMaxHp ( ) ;
2011-07-22 09:05:47 +02:00
int prevMaxHpRegen = totalUpgrade . getMaxHpRegeneration ( ) ;
2011-07-02 02:20:28 +02:00
totalUpgrade . deapply ( & boost - > boostUpgrade , this ) ;
checkItemInVault ( & this - > hp , this - > hp ) ;
//hp -= boost->boostUpgrade.getMaxHp();
hp - = ( prevMaxHp - totalUpgrade . getMaxHp ( ) ) ;
addItemToVault ( & this - > hp , this - > hp ) ;
2011-07-22 09:05:47 +02:00
//regenerate hp upgrade / or boost
if ( totalUpgrade . getMaxHpRegeneration ( ) ! = 0 ) {
checkItemInVault ( & this - > hp , this - > hp ) ;
2011-07-22 22:06:48 +02:00
//printf("BEFORE DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp);
2011-07-22 09:05:47 +02:00
hp - = ( totalUpgrade . getMaxHpRegeneration ( ) - prevMaxHpRegen ) ;
2011-07-22 22:06:48 +02:00
//if(hp > totalUpgrade.getMaxHp()) {
// hp = totalUpgrade.getMaxHp();
//}
2011-07-22 09:05:47 +02:00
addItemToVault ( & this - > hp , this - > hp ) ;
2011-07-22 22:06:48 +02:00
//printf("AFTER DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp);
2011-07-22 09:05:47 +02:00
}
2011-11-16 22:38:12 +01:00
if ( originalHp < hp ) {
this - > setLastAttackerUnitId ( source - > getId ( ) ) ;
}
2011-07-02 02:20:28 +02:00
if ( wasAlive = = true ) {
2011-07-06 07:16:25 +02:00
//printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
2011-07-02 02:20:28 +02:00
//startDamageParticles
2012-12-29 02:01:14 +01:00
if ( originalHp > hp ) {
startDamageParticles ( ) ;
}
2011-07-02 02:20:28 +02:00
//stop DamageParticles on death
if ( hp < = 0 ) {
alive = false ;
hp = 0 ;
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-07-02 02:20:28 +02:00
stopDamageParticles ( true ) ;
2011-11-16 22:38:12 +01:00
this - > setLastAttackerUnitId ( source - > getId ( ) ) ;
this - > setCauseOfDeath ( ucodAttackBoost ) ;
2012-03-31 01:38:05 +02:00
Unit : : game - > getWorld ( ) - > getStats ( ) - > die ( getFactionIndex ( ) , getType ( ) - > getCountUnitDeathInStats ( ) ) ;
2011-07-02 02:20:28 +02:00
game - > getScriptManager ( ) - > onUnitDied ( this ) ;
StaticSound * sound = this - > getType ( ) - > getFirstStOfClass ( scDie ) - > getSound ( ) ;
if ( sound ! = NULL & &
( this - > getFactionIndex ( ) = = Unit : : game - > getWorld ( ) - > getThisFactionIndex ( ) | |
2011-10-12 18:03:55 +02:00
( game - > getWorld ( ) - > showWorldForPlayer ( game - > getWorld ( ) - > getThisTeamIndex ( ) ) = = true ) ) ) {
2011-07-02 02:20:28 +02:00
SoundRenderer : : getInstance ( ) . playFx ( sound ) ;
}
if ( this - > isDead ( ) & & this - > getCurrSkill ( ) - > getClass ( ) ! = scDie ) {
this - > kill ( ) ;
}
}
}
2011-06-25 22:44:46 +02:00
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-07-06 07:16:25 +02:00
//printf("DE-APPLYING ATTACK BOOST BEFORE END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
2011-06-25 22:44:46 +02:00
for ( unsigned int i = 0 ; i < currentAttackBoostEffects . size ( ) ; + + i ) {
2011-07-06 07:16:25 +02:00
UnitAttackBoostEffect * effect = currentAttackBoostEffects [ i ] ;
if ( effect ! = NULL & & effect - > boost = = boost & & effect - > source = = source ) {
delete effect ;
2011-06-25 22:44:46 +02:00
currentAttackBoostEffects . erase ( currentAttackBoostEffects . begin ( ) + i ) ;
break ;
}
}
2011-07-06 07:16:25 +02:00
//printf("DE-APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
2011-06-25 22:44:46 +02:00
}
2010-06-14 08:38:24 +02:00
void Unit : : tick ( ) {
if ( isAlive ( ) ) {
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
2011-11-28 07:25:20 +01:00
//if(this->getType()->getName() == "spearman") printf("Unit [%d - %s] start tick hp = %d\n",this->getId(),this->getType()->getName().c_str(),hp);
2011-11-16 22:38:12 +01:00
2010-12-28 03:17:44 +01:00
2011-07-22 09:05:47 +02:00
//regenerate hp upgrade / or boost
2011-11-28 07:25:20 +01:00
if ( type - > getTotalMaxHpRegeneration ( & totalUpgrade ) ! = 0 ) {
2011-11-29 01:54:38 +01:00
if ( currSkill - > getClass ( ) ! = scBeBuilt ) {
if ( type - > getTotalMaxHpRegeneration ( & totalUpgrade ) > = 0 ) {
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = type - > getTotalMaxHpRegeneration ( & totalUpgrade ) ;
if ( hp > type - > getTotalMaxHp ( & totalUpgrade ) ) {
hp = type - > getTotalMaxHp ( & totalUpgrade ) ;
}
addItemToVault ( & this - > hp , this - > hp ) ;
2011-11-28 07:25:20 +01:00
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-11-29 01:54:38 +01:00
//if(this->getType()->getName() == "spearman") printf("tick hp#2 [type->getTotalMaxHpRegeneration(&totalUpgrade)] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getTotalMaxHpRegeneration(&totalUpgrade),type->getTotalMaxHp(&totalUpgrade),hp);
2011-11-28 07:25:20 +01:00
}
2011-11-29 01:54:38 +01:00
// If we have negative regeneration then check if the unit should die
else {
bool decHpResult = decHp ( - type - > getTotalMaxHpRegeneration ( & totalUpgrade ) ) ;
if ( decHpResult ) {
this - > setCauseOfDeath ( ucodStarvedRegeneration ) ;
2012-03-31 01:38:05 +02:00
Unit : : game - > getWorld ( ) - > getStats ( ) - > die ( getFactionIndex ( ) , getType ( ) - > getCountUnitDeathInStats ( ) ) ;
2011-11-29 01:54:38 +01:00
game - > getScriptManager ( ) - > onUnitDied ( this ) ;
}
StaticSound * sound = this - > getType ( ) - > getFirstStOfClass ( scDie ) - > getSound ( ) ;
if ( sound ! = NULL & &
( this - > getFactionIndex ( ) = = Unit : : game - > getWorld ( ) - > getThisFactionIndex ( ) | |
( game - > getWorld ( ) - > showWorldForPlayer ( game - > getWorld ( ) - > getThisTeamIndex ( ) ) = = true ) ) ) {
SoundRenderer : : getInstance ( ) . playFx ( sound ) ;
}
2011-11-28 07:25:20 +01:00
}
}
2011-07-22 09:05:47 +02:00
}
2011-11-28 07:25:20 +01:00
//regenerate hp
2011-07-22 09:05:47 +02:00
else {
2011-11-28 07:25:20 +01:00
if ( type - > getHpRegeneration ( ) > = 0 ) {
2011-11-29 01:54:38 +01:00
if ( currSkill - > getClass ( ) ! = scBeBuilt ) {
checkItemInVault ( & this - > hp , this - > hp ) ;
2011-11-28 07:25:20 +01:00
2011-11-29 01:54:38 +01:00
hp + = type - > getHpRegeneration ( ) ;
if ( hp > type - > getTotalMaxHp ( & totalUpgrade ) ) {
hp = type - > getTotalMaxHp ( & totalUpgrade ) ;
}
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-11-29 01:54:38 +01:00
//if(this->getType()->getName() == "spearman") printf("tick hp#1 [type->getHpRegeneration()] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getHpRegeneration(),type->getTotalMaxHp(&totalUpgrade),hp);
2011-11-28 07:25:20 +01:00
}
}
// If we have negative regeneration then check if the unit should die
else {
bool decHpResult = decHp ( - type - > getHpRegeneration ( ) ) ;
if ( decHpResult ) {
this - > setCauseOfDeath ( ucodStarvedRegeneration ) ;
2012-03-31 01:38:05 +02:00
Unit : : game - > getWorld ( ) - > getStats ( ) - > die ( getFactionIndex ( ) , getType ( ) - > getCountUnitDeathInStats ( ) ) ;
2011-11-28 07:25:20 +01:00
game - > getScriptManager ( ) - > onUnitDied ( this ) ;
}
StaticSound * sound = this - > getType ( ) - > getFirstStOfClass ( scDie ) - > getSound ( ) ;
if ( sound ! = NULL & &
( this - > getFactionIndex ( ) = = Unit : : game - > getWorld ( ) - > getThisFactionIndex ( ) | |
( game - > getWorld ( ) - > showWorldForPlayer ( game - > getWorld ( ) - > getThisTeamIndex ( ) ) = = true ) ) ) {
SoundRenderer : : getInstance ( ) . playFx ( sound ) ;
}
}
2011-07-22 09:05:47 +02:00
}
2010-03-12 08:42:55 +01:00
//stop DamageParticles
2011-07-01 23:47:54 +02:00
stopDamageParticles ( false ) ;
2010-12-28 03:17:44 +01:00
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > ep , this - > ep ) ;
2010-03-12 08:42:55 +01:00
//regenerate ep
2011-10-12 04:46:31 +02:00
// ep += type->getEpRegeneration();
// if(ep > type->getTotalMaxEp(&totalUpgrade)){
// ep = type->getTotalMaxEp(&totalUpgrade);
// }
// addItemToVault(&this->ep,this->ep);
2011-07-22 09:05:47 +02:00
//regenerate ep upgrade / or boost
checkItemInVault ( & this - > ep , this - > ep ) ;
//regenerate ep
ep + = type - > getTotalMaxEpRegeneration ( & totalUpgrade ) ;
if ( ep > type - > getTotalMaxEp ( & totalUpgrade ) ) {
ep = type - > getTotalMaxEp ( & totalUpgrade ) ;
}
addItemToVault ( & this - > ep , this - > ep ) ;
2010-03-12 08:42:55 +01:00
}
}
2010-12-28 03:17:44 +01:00
int Unit : : update2 ( ) {
2010-03-12 08:42:55 +01:00
progress2 + + ;
return progress2 ;
}
2010-10-30 10:54:00 +02:00
bool Unit : : computeEp ( ) {
2010-03-12 08:42:55 +01:00
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
//if not enough ep
2011-01-15 00:51:15 +01:00
if ( ep - currSkill - > getEpCost ( ) < 0 ) {
2010-03-12 08:42:55 +01:00
return true ;
}
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > ep , this - > ep ) ;
2010-03-12 08:42:55 +01:00
//decrease ep
2011-01-15 00:51:15 +01:00
ep - = currSkill - > getEpCost ( ) ;
addItemToVault ( & this - > ep , this - > ep ) ;
2010-06-14 08:38:24 +02:00
if ( getType ( ) = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2011-01-15 00:51:15 +01:00
if ( ep > getType ( ) - > getTotalMaxEp ( & totalUpgrade ) ) {
ep = getType ( ) - > getTotalMaxEp ( & totalUpgrade ) ;
2010-03-12 08:42:55 +01:00
}
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > ep , this - > ep ) ;
2010-03-12 08:42:55 +01:00
return false ;
}
2011-02-06 19:33:49 +01:00
2010-03-12 08:42:55 +01:00
bool Unit : : repair ( ) {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
//increase hp
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = getType ( ) - > getMaxHp ( ) / type - > getProductionTime ( ) + 1 ;
if ( hp > ( getType ( ) - > getTotalMaxHp ( & totalUpgrade ) ) ) {
hp = getType ( ) - > getTotalMaxHp ( & totalUpgrade ) ;
addItemToVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
return true ;
}
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2010-03-12 08:42:55 +01:00
//stop DamageParticles
2011-07-01 23:47:54 +02:00
stopDamageParticles ( false ) ;
2010-03-12 08:42:55 +01:00
return false ;
}
//decrements HP and returns if dead
2010-12-28 03:17:44 +01:00
bool Unit : : decHp ( int i ) {
if ( hp = = 0 ) {
2010-03-12 08:42:55 +01:00
return false ;
}
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
2010-12-28 03:17:44 +01:00
hp - = i ;
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
//startDamageParticles
2011-07-01 23:47:54 +02:00
startDamageParticles ( ) ;
2010-03-12 08:42:55 +01:00
//stop DamageParticles on death
2010-12-28 03:17:44 +01:00
if ( hp < = 0 ) {
2010-03-12 08:42:55 +01:00
alive = false ;
hp = 0 ;
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2011-07-01 23:47:54 +02:00
stopDamageParticles ( true ) ;
2010-03-12 08:42:55 +01:00
return true ;
}
return false ;
}
2011-05-01 22:19:41 +02:00
string Unit : : getDescExtension ( ) const {
Lang & lang = Lang : : getInstance ( ) ;
string str = " \n " ;
if ( commands . empty ( ) = = false & & commands . size ( ) > 1 ) {
Commands : : const_iterator it = commands . begin ( ) ;
for ( unsigned int i = 0 ; i < min ( ( size_t ) maxQueuedCommandDisplayCount , commands . size ( ) ) ; + + i ) {
const CommandType * ct = ( * it ) - > getCommandType ( ) ;
if ( i = = 0 ) {
str + = " \n " + lang . get ( " OrdersOnQueue " ) + " : " ;
}
2012-05-02 22:46:47 +02:00
str + = " \n # " + intToStr ( i + 1 ) + " " + ct - > getName ( true ) ;
2011-09-01 20:08:56 +02:00
+ + it ;
2011-05-01 22:19:41 +02:00
}
}
return str ;
}
2010-12-28 03:17:44 +01:00
string Unit : : getDesc ( ) const {
2010-03-12 08:42:55 +01:00
Lang & lang = Lang : : getInstance ( ) ;
//pos
//str+="Pos: "+v2iToStr(pos)+"\n";
//hp
2010-08-22 23:09:35 +02:00
string str = " \n " ;
2010-12-24 09:43:09 +01:00
2010-08-22 23:09:35 +02:00
//maxUnitCount
if ( type - > getMaxUnitCount ( ) > 0 ) {
str + = lang . get ( " MaxUnitCount " ) + " : " + intToStr ( faction - > getCountForMaxUnitCount ( type ) ) + " / " + intToStr ( type - > getMaxUnitCount ( ) ) ;
}
2010-12-24 09:43:09 +01:00
2011-07-07 00:45:44 +02:00
//str += "\n"+lang.get("Hp")+ ": " + intToStr(hp) + "/" + intToStr(type->getTotalMaxHp(&totalUpgrade)) + " [" + floatToStr(getHpRatio()) + "] [" + floatToStr(animProgress) + "]";
str + = " \n " + lang . get ( " Hp " ) + " : " + intToStr ( hp ) + " / " + intToStr ( type - > getTotalMaxHp ( & totalUpgrade ) ) ;
2011-07-22 22:06:48 +02:00
if ( type - > getHpRegeneration ( ) ! = 0 | | totalUpgrade . getMaxHpRegeneration ( ) ! = 0 ) {
2011-07-22 09:05:47 +02:00
str + = " ( " + lang . get ( " Regeneration " ) + " : " + intToStr ( type - > getHpRegeneration ( ) ) ;
2011-07-22 22:06:48 +02:00
if ( totalUpgrade . getMaxHpRegeneration ( ) ! = 0 ) {
str + = " + " + intToStr ( totalUpgrade . getMaxHpRegeneration ( ) ) ;
2011-07-22 09:05:47 +02:00
}
str + = " ) " ;
2010-03-12 08:42:55 +01:00
}
//ep
if ( getType ( ) - > getMaxEp ( ) ! = 0 ) {
str + = " \n " + lang . get ( " Ep " ) + " : " + intToStr ( ep ) + " / " + intToStr ( type - > getTotalMaxEp ( & totalUpgrade ) ) ;
}
2011-07-22 22:06:48 +02:00
if ( type - > getEpRegeneration ( ) ! = 0 | | totalUpgrade . getMaxEpRegeneration ( ) ! = 0 ) {
2011-07-22 09:05:47 +02:00
str + = " ( " + lang . get ( " Regeneration " ) + " : " + intToStr ( type - > getEpRegeneration ( ) ) ;
2011-07-22 22:06:48 +02:00
if ( totalUpgrade . getMaxEpRegeneration ( ) ! = 0 ) {
str + = " + " + intToStr ( totalUpgrade . getMaxEpRegeneration ( ) ) ;
2011-07-22 09:05:47 +02:00
}
str + = " ) " ;
2010-03-12 08:42:55 +01:00
}
//armor
str + = " \n " + lang . get ( " Armor " ) + " : " + intToStr ( getType ( ) - > getArmor ( ) ) ;
if ( totalUpgrade . getArmor ( ) ! = 0 ) {
str + = " + " + intToStr ( totalUpgrade . getArmor ( ) ) ;
}
2013-01-16 22:16:59 +01:00
str + = " ( " + getType ( ) - > getArmorType ( ) - > getName ( true ) + " ) " ;
2010-03-12 08:42:55 +01:00
//sight
str + = " \n " + lang . get ( " Sight " ) + " : " + intToStr ( getType ( ) - > getSight ( ) ) ;
if ( totalUpgrade . getSight ( ) ! = 0 ) {
str + = " + " + intToStr ( totalUpgrade . getSight ( ) ) ;
}
//kills
const Level * nextLevel = getNextLevel ( ) ;
2011-04-20 18:46:47 +02:00
if ( enemyKills > 0 | | nextLevel ! = NULL ) {
str + = " \n " + lang . get ( " Kills " ) + " : " + intToStr ( enemyKills ) ;
if ( nextLevel ! = NULL ) {
2013-01-16 22:16:59 +01:00
str + = " ( " + nextLevel - > getName ( true ) + " : " + intToStr ( nextLevel - > getKills ( ) ) + " ) " ;
2010-03-12 08:42:55 +01:00
}
}
//str+= "\nskl: "+scToStr(currSkill->getClass());
//load
if ( loadCount ! = 0 ) {
2012-05-02 22:46:47 +02:00
str + = " \n " + lang . get ( " Load " ) + " : " + intToStr ( loadCount ) + " " + loadType - > getName ( true ) ;
2010-03-12 08:42:55 +01:00
}
//consumable production
2011-04-28 02:16:26 +02:00
for ( int i = 0 ; i < getType ( ) - > getCostCount ( ) ; + + i ) {
2010-03-12 08:42:55 +01:00
const Resource * r = getType ( ) - > getCost ( i ) ;
2011-04-28 02:16:26 +02:00
if ( r - > getType ( ) - > getClass ( ) = = rcConsumable ) {
2010-03-12 08:42:55 +01:00
str + = " \n " ;
2011-04-28 02:16:26 +02:00
str + = r - > getAmount ( ) < 0 ? lang . get ( " Produce " ) + " : " : lang . get ( " Consume " ) + " : " ;
2012-05-02 22:46:47 +02:00
str + = intToStr ( abs ( r - > getAmount ( ) ) ) + " " + r - > getType ( ) - > getName ( true ) ;
2010-03-12 08:42:55 +01:00
}
}
//command info
2011-05-01 22:19:41 +02:00
if ( commands . empty ( ) = = false ) {
2012-05-02 22:46:47 +02:00
str + = " \n " + commands . front ( ) - > getCommandType ( ) - > getName ( true ) ;
2011-05-01 22:19:41 +02:00
if ( commands . size ( ) > 1 ) {
str + = " \n " + lang . get ( " OrdersOnQueue " ) + " : " + intToStr ( commands . size ( ) ) ;
2010-03-12 08:42:55 +01:00
}
}
2011-05-01 22:19:41 +02:00
else {
2010-03-12 08:42:55 +01:00
//can store
2011-04-28 02:16:26 +02:00
if ( getType ( ) - > getStoredResourceCount ( ) > 0 ) {
for ( int i = 0 ; i < getType ( ) - > getStoredResourceCount ( ) ; + + i ) {
2010-03-12 08:42:55 +01:00
const Resource * r = getType ( ) - > getStoredResource ( i ) ;
2011-04-28 02:16:26 +02:00
str + = " \n " + lang . get ( " Store " ) + " : " ;
2012-05-02 22:46:47 +02:00
str + = intToStr ( r - > getAmount ( ) ) + " " + r - > getType ( ) - > getName ( true ) ;
2010-03-12 08:42:55 +01:00
}
}
}
return str ;
}
void Unit : : applyUpgrade ( const UpgradeType * upgradeType ) {
2010-06-14 08:38:24 +02:00
if ( upgradeType = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: upgradeType == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
if ( upgradeType - > isAffected ( type ) ) {
2011-06-26 09:06:32 +02:00
totalUpgrade . sum ( upgradeType , this ) ;
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = upgradeType - > getMaxHp ( ) ;
2011-06-26 05:50:42 +02:00
hp = max ( 0 , hp ) ;
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2010-03-12 08:42:55 +01:00
}
}
void Unit : : computeTotalUpgrade ( ) {
faction - > getUpgradeManager ( ) - > computeTotalUpgrade ( this , & totalUpgrade ) ;
}
2011-04-20 18:46:47 +02:00
void Unit : : incKills ( int team ) {
2010-03-12 08:42:55 +01:00
+ + kills ;
2011-04-20 18:46:47 +02:00
if ( team ! = this - > getTeam ( ) ) {
+ + enemyKills ;
}
2010-03-12 08:42:55 +01:00
2012-03-25 22:38:05 +02:00
checkUnitLevel ( ) ;
}
void Unit : : checkUnitLevel ( ) {
2010-03-12 08:42:55 +01:00
const Level * nextLevel = getNextLevel ( ) ;
2011-04-20 18:46:47 +02:00
if ( nextLevel ! = NULL & & enemyKills > = nextLevel - > getKills ( ) ) {
2010-03-12 08:42:55 +01:00
level = nextLevel ;
int maxHp = totalUpgrade . getMaxHp ( ) ;
totalUpgrade . incLevel ( type ) ;
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
2011-04-20 18:46:47 +02:00
hp + = totalUpgrade . getMaxHp ( ) - maxHp ;
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2010-03-12 08:42:55 +01:00
}
}
2012-11-22 02:52:01 +01:00
void Unit : : morphAttackBoosts ( Unit * unit ) {
// Remove any units that were previously in range
if ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . empty ( ) = = false & & currentAttackBoostOriginatorEffect . skillType ! = NULL ) {
for ( int i = currentAttackBoostOriginatorEffect . currentAttackBoostUnits . size ( ) - 1 ; i > = 0 ; - - i ) {
// Remove attack boost upgrades from unit
int findUnitId = currentAttackBoostOriginatorEffect . currentAttackBoostUnits [ i ] ;
Unit * affectedUnit = game - > getWorld ( ) - > findUnitById ( findUnitId ) ;
if ( affectedUnit ! = NULL & & affectedUnit - > getId ( ) = = unit - > getId ( ) ) {
affectedUnit - > deapplyAttackBoost ( currentAttackBoostOriginatorEffect . skillType - > getAttackBoost ( ) , this ) ;
currentAttackBoostOriginatorEffect . currentAttackBoostUnits . erase ( currentAttackBoostOriginatorEffect . currentAttackBoostUnits . begin ( ) + i ) ;
}
//printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
2010-03-12 08:42:55 +01:00
bool Unit : : morph ( const MorphCommandType * mct ) {
2010-06-14 08:38:24 +02:00
if ( mct = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: mct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
const UnitType * morphUnitType = mct - > getMorphUnit ( ) ;
2010-06-14 08:38:24 +02:00
if ( morphUnitType = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: morphUnitType == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
Field morphUnitField = fLand ;
if ( morphUnitType - > getField ( fAir ) ) morphUnitField = fAir ;
if ( morphUnitType - > getField ( fLand ) ) morphUnitField = fLand ;
2012-09-13 23:50:07 +02:00
map - > clearUnitCells ( this , pos , false ) ;
2012-03-27 05:23:03 +02:00
if ( map - > isFreeCellsOrHasUnit ( pos , morphUnitType - > getSize ( ) , morphUnitField , this , morphUnitType ) ) {
2012-09-13 23:50:07 +02:00
map - > clearUnitCells ( this , pos , true ) ;
2012-03-27 05:23:03 +02:00
faction - > deApplyStaticCosts ( type , mct ) ;
2011-01-15 00:51:15 +01:00
2012-11-22 02:52:01 +01:00
//printf("Now unapply attack-boost for unit [%d - %s]\n",this->getId(),this->getType()->getName().c_str());
// De apply attack boosts for morphed unit
for ( int i = currentAttackBoostEffects . size ( ) - 1 ; i > = 0 ; - - i ) {
UnitAttackBoostEffect * effect = currentAttackBoostEffects [ i ] ;
if ( effect ! = NULL ) {
Unit * sourceUnit = game - > getWorld ( ) - > findUnitById ( effect - > source - > getId ( ) ) ;
sourceUnit - > morphAttackBoosts ( this ) ;
}
}
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = morphUnitType - > getMaxHp ( ) - type - > getMaxHp ( ) ;
addItemToVault ( & this - > hp , this - > hp ) ;
2012-03-24 19:30:49 +01:00
checkModelStateInfoForNewHpValue ( ) ;
2010-03-12 08:42:55 +01:00
type = morphUnitType ;
currField = morphUnitField ;
computeTotalUpgrade ( ) ;
map - > putUnitCells ( this , pos ) ;
faction - > applyDiscount ( morphUnitType , mct - > getDiscount ( ) ) ;
2011-01-07 06:15:39 +01:00
faction - > addStore ( type ) ;
2012-03-27 05:23:03 +02:00
faction - > applyStaticProduction ( morphUnitType , mct ) ;
2012-03-25 22:38:05 +02:00
level = NULL ;
checkUnitLevel ( ) ;
2010-03-12 08:42:55 +01:00
return true ;
}
else {
return false ;
}
}
// ==================== PRIVATE ====================
float Unit : : computeHeight ( const Vec2i & pos ) const {
2012-04-12 17:38:53 +02:00
//printf("CRASHING FOR UNIT: %d alive = %d\n",this->getId(),this->isAlive());
//printf("[%s]\n",this->getType()->getName().c_str());
2011-02-23 08:03:38 +01:00
if ( map - > isInside ( pos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( pos ) ) = = false ) {
2012-04-12 17:38:53 +02:00
//printf("CRASHING FOR UNIT: %d [%s] alive = %d\n",this->getId(),this->getType()->getName().c_str(),this->isAlive());
//abort();
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #7 Invalid path position = " + pos . getString ( ) ) ;
2011-02-23 08:03:38 +01:00
}
2010-03-12 08:42:55 +01:00
float height = map - > getCell ( pos ) - > getHeight ( ) ;
2010-10-30 06:05:48 +02:00
if ( currField = = fAir ) {
height + = World : : airHeight ;
Unit * unit = map - > getCell ( pos ) - > getUnit ( fLand ) ;
if ( unit ! = NULL & & unit - > getType ( ) - > getHeight ( ) > World : : airHeight ) {
height + = ( std : : min ( ( float ) unit - > getType ( ) - > getHeight ( ) , World : : airHeight * 3 ) - World : : airHeight ) ;
}
else {
SurfaceCell * sc = map - > getSurfaceCell ( map - > toSurfCoords ( pos ) ) ;
if ( sc ! = NULL & & sc - > getObject ( ) ! = NULL & & sc - > getObject ( ) - > getType ( ) ! = NULL ) {
if ( sc - > getObject ( ) - > getType ( ) - > getHeight ( ) > World : : airHeight ) {
height + = ( std : : min ( ( float ) sc - > getObject ( ) - > getType ( ) - > getHeight ( ) , World : : airHeight * 3 ) - World : : airHeight ) ;
}
}
}
2010-03-12 08:42:55 +01:00
}
return height ;
}
void Unit : : updateTarget ( ) {
Unit * target = targetRef . getUnit ( ) ;
if ( target ! = NULL ) {
//update target pos
targetPos = target - > getCellPos ( ) ;
Vec2i relPos = targetPos - pos ;
2010-04-27 22:38:34 +02:00
Vec2f relPosf = Vec2f ( ( float ) relPos . x , ( float ) relPos . y ) ;
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2012-02-10 07:21:06 +01:00
targetRotation = radToDeg ( streflop : : atan2 ( static_cast < streflop : : Simple > ( relPosf . x ) , static_cast < streflop : : Simple > ( relPosf . y ) ) ) ;
2010-05-01 22:14:25 +02:00
# else
targetRotation = radToDeg ( atan2 ( relPosf . x , relPosf . y ) ) ;
# endif
2010-03-12 08:42:55 +01:00
//update target vec
targetVec = target - > getCurrVector ( ) ;
2010-04-27 05:36:36 +02:00
2010-04-29 19:00:14 +02:00
//if(getFrameCount() % 40 == 0) {
2010-04-27 16:10:53 +02:00
//logSynchData(string(__FILE__) + string("::") + string(__FUNCTION__) + string(" Line: ") + intToStr(__LINE__));
2010-04-29 19:00:14 +02:00
//logSynchData();
//}
2010-03-12 08:42:55 +01:00
}
}
2010-09-01 06:42:10 +02:00
void Unit : : clearCommands ( ) {
2011-07-05 17:43:39 +02:00
2010-09-01 06:42:10 +02:00
this - > setCurrentUnitTitle ( " " ) ;
2010-12-23 11:44:11 +01:00
this - > unitPath - > clear ( ) ;
2011-01-08 22:53:05 +01:00
while ( commands . empty ( ) = = false ) {
2010-03-12 08:42:55 +01:00
undoCommand ( commands . back ( ) ) ;
2011-07-06 08:38:56 +02:00
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2011-12-02 17:07:59 +01:00
MutexSafeWrapper safeMutex ( mutexCommands , mutexOwnerId ) ;
2011-07-06 08:38:56 +02:00
2010-03-12 08:42:55 +01:00
delete commands . back ( ) ;
commands . pop_back ( ) ;
2011-07-06 08:38:56 +02:00
safeMutex . ReleaseLock ( ) ;
2010-03-12 08:42:55 +01:00
}
2011-10-28 03:11:42 +02:00
changedActiveCommand = false ;
2010-03-12 08:42:55 +01:00
}
2010-12-23 11:44:11 +01:00
void Unit : : deleteQueuedCommand ( Command * command ) {
2011-01-08 22:53:05 +01:00
if ( getCurrCommand ( ) = = command ) {
2010-12-23 11:44:11 +01:00
this - > setCurrentUnitTitle ( " " ) ;
2010-12-24 09:43:09 +01:00
this - > unitPath - > clear ( ) ;
2010-12-23 11:44:11 +01:00
}
undoCommand ( command ) ;
delete command ;
}
2012-11-10 20:39:55 +01:00
std : : pair < CommandResult , string > Unit : : checkCommand ( Command * command ) const {
std : : pair < CommandResult , string > result ( crSuccess , " " ) ;
2010-06-12 20:27:39 +02:00
if ( command = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-12 20:27:39 +02:00
}
2010-11-09 10:06:52 +01:00
2010-03-12 08:42:55 +01:00
//if not operative or has not command type => fail
2011-01-08 22:53:05 +01:00
if ( isOperative ( ) = = false | |
command - > getUnit ( ) = = this | |
getType ( ) - > hasCommandType ( command - > getCommandType ( ) ) = = false | |
2011-01-29 13:42:18 +01:00
( ignoreCheckCommand = = false & & this - > getFaction ( ) - > reqsOk ( command - > getCommandType ( ) ) = = false ) ) {
2011-03-28 05:54:23 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugLUA ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] isOperative() = %d, command->getUnit() = %p, getType()->hasCommandType(command->getCommandType()) = %d, this->getFaction()->reqsOk(command->getCommandType()) = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , isOperative ( ) , command - > getUnit ( ) , getType ( ) - > hasCommandType ( command - > getCommandType ( ) ) , this - > getFaction ( ) - > reqsOk ( command - > getCommandType ( ) ) ) ;
2011-04-17 08:25:08 +02:00
// Allow self healing if able to heal own unit type
if ( command - > getUnit ( ) = = this & &
command - > getCommandType ( ) - > getClass ( ) = = ccRepair & &
this - > getType ( ) - > getFirstRepairCommand ( this - > getType ( ) ) ! = NULL ) {
}
else {
2012-11-10 20:39:55 +01:00
result . first = crFailUndefined ;
return result ;
2011-04-17 08:25:08 +02:00
}
2010-03-12 08:42:55 +01:00
}
//if pos is not inside the world (if comand has not a pos, pos is (0, 0) and is inside world
2011-01-08 22:53:05 +01:00
if ( map - > isInside ( command - > getPos ( ) ) = = 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__ ) ;
2012-11-10 20:39:55 +01:00
result . first = crFailUndefined ;
return result ;
2010-03-12 08:42:55 +01:00
}
//check produced
2010-06-12 20:27:39 +02:00
if ( command - > getCommandType ( ) = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-12 20:27:39 +02:00
}
2010-03-12 08:42:55 +01:00
const ProducibleType * produced = command - > getCommandType ( ) - > getProduced ( ) ;
2012-03-27 05:23:03 +02:00
if ( produced ! = NULL ) {
2011-01-29 13:42:18 +01:00
if ( ignoreCheckCommand = = false & & faction - > reqsOk ( produced ) = = false ) {
2012-11-10 20:39:55 +01:00
//printf("To produce this unit you need:\n%s\n",produced->getUnitAndUpgradeReqDesc().c_str());
result . first = crFailReqs ;
Lang & lang = Lang : : getInstance ( ) ;
result . second = " - " + lang . get ( " Reqs " ) + " : " + produced - > getUnitAndUpgradeReqDesc ( false ) ;
return result ;
2010-03-12 08:42:55 +01:00
}
2010-11-09 10:06:52 +01:00
2012-03-27 05:23:03 +02:00
if ( ignoreCheckCommand = = false & &
faction - > checkCosts ( produced , command - > getCommandType ( ) ) = = false ) {
2012-11-10 20:39:55 +01:00
//printf("To produce this unit you need:\n%s\n",produced->getResourceReqDesc().c_str());
result . first = crFailRes ;
Lang & lang = Lang : : getInstance ( ) ;
result . second = " - " + lang . get ( " Reqs " ) + " : " + produced - > getResourceReqDesc ( false ) ;
return result ;
2010-03-12 08:42:55 +01:00
}
}
//build command specific, check resources and requirements for building
2011-01-08 22:53:05 +01:00
if ( command - > getCommandType ( ) - > getClass ( ) = = ccBuild ) {
2010-03-12 08:42:55 +01:00
const UnitType * builtUnit = command - > getUnitType ( ) ;
2010-06-12 20:27:39 +02:00
if ( builtUnit = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: builtUnit == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-12 20:27:39 +02:00
}
2010-11-09 10:06:52 +01:00
if ( faction - > reqsOk ( builtUnit ) = = false ) {
2012-11-10 20:39:55 +01:00
//printf("To build this unit you need:\n%s\n",builtUnit->getUnitAndUpgradeReqDesc().c_str());
result . first = crFailReqs ;
Lang & lang = Lang : : getInstance ( ) ;
result . second = " - " + lang . get ( " Reqs " ) + " : " + builtUnit - > getUnitAndUpgradeReqDesc ( false ) ;
return result ;
2010-03-12 08:42:55 +01:00
}
2012-03-27 05:23:03 +02:00
if ( faction - > checkCosts ( builtUnit , NULL ) = = false ) {
2012-11-10 20:39:55 +01:00
//printf("To build this unit you need:\n%s\n",builtUnit->getResourceReqDesc().c_str());
result . first = crFailRes ;
Lang & lang = Lang : : getInstance ( ) ;
result . second = " - " + lang . get ( " Reqs " ) + " : " + builtUnit - > getResourceReqDesc ( false ) ;
return result ;
2010-11-09 10:06:52 +01:00
}
2010-03-12 08:42:55 +01:00
}
//upgrade command specific, check that upgrade is not upgraded
2011-01-29 13:42:18 +01:00
else if ( command - > getCommandType ( ) - > getClass ( ) = = ccUpgrade ) {
2010-03-12 08:42:55 +01:00
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( command - > getCommandType ( ) ) ;
2010-06-12 20:27:39 +02:00
if ( uct = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-12 20:27:39 +02:00
}
2010-03-12 08:42:55 +01:00
if ( faction - > getUpgradeManager ( ) - > 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] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2012-11-10 20:39:55 +01:00
result . first = crFailUndefined ;
return result ;
2010-03-12 08:42:55 +01:00
}
}
2012-11-10 20:39:55 +01:00
return result ;
2010-03-12 08:42:55 +01:00
}
void Unit : : applyCommand ( Command * command ) {
2010-06-14 08:38:24 +02:00
if ( command = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
else if ( command - > getCommandType ( ) = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
//check produced
const ProducibleType * produced = command - > getCommandType ( ) - > getProduced ( ) ;
2010-11-09 10:06:52 +01:00
if ( produced ! = NULL ) {
2012-03-27 05:23:03 +02:00
faction - > applyCosts ( produced , command - > getCommandType ( ) ) ;
2010-03-12 08:42:55 +01:00
}
//build command specific
if ( command - > getCommandType ( ) - > getClass ( ) = = ccBuild ) {
2012-03-27 05:23:03 +02:00
faction - > applyCosts ( command - > getUnitType ( ) , command - > getCommandType ( ) ) ;
2010-03-12 08:42:55 +01:00
}
//upgrade command specific
else if ( command - > getCommandType ( ) - > getClass ( ) = = ccUpgrade ) {
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( command - > getCommandType ( ) ) ;
2010-06-14 08:38:24 +02:00
if ( uct = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
faction - > startUpgrade ( uct - > getProducedUpgrade ( ) ) ;
2010-03-12 08:42:55 +01:00
}
}
CommandResult Unit : : undoCommand ( Command * command ) {
2010-06-14 08:38:24 +02:00
if ( command = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
else if ( command - > getCommandType ( ) = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
2012-09-21 02:21:23 +02:00
if ( getCurrCommand ( ) = = command & & command - > getCommandType ( ) - > getClass ( ) = = ccMorph
& & this - > currSkill - > getClass ( ) = = scMorph ) {
2012-09-11 23:16:24 +02:00
// clear cells of morphed unit and set those of current unit!
map - > clearUnitCells ( this , this - > getPos ( ) ) ;
map - > putUnitCells ( this , this - > getPos ( ) , true ) ;
}
2010-03-12 08:42:55 +01:00
//return cost
const ProducibleType * produced = command - > getCommandType ( ) - > getProduced ( ) ;
if ( produced ! = NULL ) {
2012-03-27 05:23:03 +02:00
faction - > deApplyCosts ( produced , command - > getCommandType ( ) ) ;
2010-03-12 08:42:55 +01:00
}
//return building cost if not already building it or dead
if ( command - > getCommandType ( ) - > getClass ( ) = = ccBuild ) {
2010-10-30 10:54:00 +02:00
if ( currSkill - > getClass ( ) ! = scBuild & & currSkill - > getClass ( ) ! = scDie ) {
2012-03-27 05:23:03 +02:00
faction - > deApplyCosts ( command - > getUnitType ( ) , command - > getCommandType ( ) ) ;
2010-03-12 08:42:55 +01:00
}
}
//upgrade command cancel from list
if ( command - > getCommandType ( ) - > getClass ( ) = = ccUpgrade ) {
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( command - > getCommandType ( ) ) ;
2010-06-14 08:38:24 +02:00
if ( uct = = NULL ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-14 08:38:24 +02:00
}
faction - > cancelUpgrade ( uct - > getProducedUpgrade ( ) ) ;
2010-03-12 08:42:55 +01:00
}
2010-08-28 03:46:26 +02:00
retryCurrCommandCount = 0 ;
2010-09-01 06:42:10 +02:00
this - > setCurrentUnitTitle ( " " ) ;
2010-08-28 03:46:26 +02:00
2010-03-12 08:42:55 +01:00
return crSuccess ;
}
2011-07-01 23:47:54 +02:00
void Unit : : stopDamageParticles ( bool force ) {
if ( force = = true | | ( hp > type - > getTotalMaxHp ( & totalUpgrade ) / 2 ) ) {
2011-07-02 05:59:46 +02:00
//printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp);
2011-07-01 23:47:54 +02:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( fire , rsGame ) = = false ) {
fire = NULL ;
}
2010-09-07 19:30:13 +02:00
2011-07-01 23:47:54 +02:00
// stop fire
if ( fire ! = NULL ) {
fire - > fade ( ) ;
fire = NULL ;
}
// stop additional particles
2011-07-04 17:55:13 +02:00
2011-09-01 03:11:23 +02:00
if ( smokeParticleSystems . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
//printf("Checking to stop smokeparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp);
2011-07-04 17:55:13 +02:00
for ( int i = smokeParticleSystems . size ( ) - 1 ; i > = 0 ; - - i ) {
UnitParticleSystem * ps = smokeParticleSystems [ i ] ;
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
ps - > fade ( ) ;
}
2011-07-04 17:55:13 +02:00
smokeParticleSystems . pop_back ( ) ;
}
}
2011-09-01 03:11:23 +02:00
if ( damageParticleSystems . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
//printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp);
2011-07-02 05:59:46 +02:00
for ( int i = damageParticleSystems . size ( ) - 1 ; i > = 0 ; - - i ) {
UnitParticleSystem * ps = damageParticleSystems [ i ] ;
UnitParticleSystemType * pst = NULL ;
int foundParticleIndexType = - 2 ;
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
for ( std : : map < int , UnitParticleSystem * > : : iterator iterMap = damageParticleSystemsInUse . begin ( ) ;
iterMap ! = damageParticleSystemsInUse . end ( ) ; + + iterMap ) {
if ( iterMap - > second = = ps ) {
foundParticleIndexType = iterMap - > first ;
if ( foundParticleIndexType > = 0 ) {
pst = type - > damageParticleSystemTypes [ foundParticleIndexType ] ;
break ;
}
2011-07-02 05:59:46 +02:00
}
2011-07-02 04:52:30 +02:00
}
2011-07-01 23:47:54 +02:00
}
2011-07-02 18:07:04 +02:00
if ( force = = true | | ( pst ! = NULL & & pst - > getMinmaxEnabled ( ) = = false ) ) {
2011-07-02 05:59:46 +02:00
damageParticleSystemsInUse . erase ( foundParticleIndexType ) ;
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
ps - > fade ( ) ;
}
2011-07-02 05:59:46 +02:00
damageParticleSystems . pop_back ( ) ;
}
2011-07-01 23:47:54 +02:00
}
}
2010-09-07 19:30:13 +02:00
}
2011-07-01 23:47:54 +02:00
checkCustomizedParticleTriggers ( force ) ;
2010-03-12 08:42:55 +01:00
}
2011-07-01 23:47:54 +02:00
void Unit : : checkCustomizedParticleTriggers ( bool force ) {
// Now check if we have special hp triggered particles
2011-09-01 03:11:23 +02:00
if ( damageParticleSystems . empty ( ) = = false ) {
2011-07-02 05:59:46 +02:00
for ( int i = damageParticleSystems . size ( ) - 1 ; i > = 0 ; - - i ) {
UnitParticleSystem * ps = damageParticleSystems [ i ] ;
UnitParticleSystemType * pst = NULL ;
int foundParticleIndexType = - 2 ;
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
for ( std : : map < int , UnitParticleSystem * > : : iterator iterMap = damageParticleSystemsInUse . begin ( ) ;
iterMap ! = damageParticleSystemsInUse . end ( ) ; + + iterMap ) {
if ( iterMap - > second = = ps ) {
foundParticleIndexType = iterMap - > first ;
if ( foundParticleIndexType > = 0 ) {
pst = type - > damageParticleSystemTypes [ foundParticleIndexType ] ;
break ;
}
2011-07-02 05:59:46 +02:00
}
2011-07-02 04:52:30 +02:00
}
2011-07-01 23:47:54 +02:00
}
2011-07-02 05:59:46 +02:00
if ( force = = true | | ( pst ! = NULL & & pst - > getMinmaxEnabled ( ) = = true ) ) {
bool stopParticle = force ;
if ( force = = false ) {
if ( pst - > getMinmaxIsPercent ( ) = = false ) {
if ( hp < pst - > getMinHp ( ) | | hp > pst - > getMaxHp ( ) ) {
stopParticle = true ;
}
2011-07-02 01:13:55 +02:00
}
2011-07-02 05:59:46 +02:00
else {
int hpPercent = ( hp / type - > getTotalMaxHp ( & totalUpgrade ) * 100 ) ;
if ( hpPercent < pst - > getMinHp ( ) | | hpPercent > pst - > getMaxHp ( ) ) {
stopParticle = true ;
}
2011-07-02 01:13:55 +02:00
}
2011-07-01 23:47:54 +02:00
}
2011-07-02 05:59:46 +02:00
//printf("CHECKING to STOP customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d stopParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,stopParticle);
2011-07-01 23:47:54 +02:00
2011-07-02 05:59:46 +02:00
if ( stopParticle = = true ) {
//printf("STOPPING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp);
2011-07-01 23:47:54 +02:00
2011-07-02 05:59:46 +02:00
damageParticleSystemsInUse . erase ( foundParticleIndexType ) ;
2011-11-05 06:45:02 +01:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
ps - > fade ( ) ;
}
2011-07-02 05:59:46 +02:00
damageParticleSystems . pop_back ( ) ;
}
2011-07-01 23:47:54 +02:00
}
}
}
// Now check if we have special hp triggered particles
2010-03-12 08:42:55 +01:00
//start additional particles
2011-12-03 01:39:03 +01:00
if ( showUnitParticles & &
type - > damageParticleSystemTypes . empty ( ) = = false & &
2011-07-02 05:59:46 +02:00
force = = false & & alive = = true ) {
2011-07-01 23:47:54 +02:00
for ( unsigned int i = 0 ; i < type - > damageParticleSystemTypes . size ( ) ; + + i ) {
UnitParticleSystemType * pst = type - > damageParticleSystemTypes [ i ] ;
if ( pst - > getMinmaxEnabled ( ) = = true & & damageParticleSystemsInUse . find ( i ) = = damageParticleSystemsInUse . end ( ) ) {
bool showParticle = false ;
if ( pst - > getMinmaxIsPercent ( ) = = false ) {
if ( hp > = pst - > getMinHp ( ) & & hp < = pst - > getMaxHp ( ) ) {
showParticle = true ;
}
}
2011-07-02 01:13:55 +02:00
else {
int hpPercent = ( hp / type - > getTotalMaxHp ( & totalUpgrade ) * 100 ) ;
if ( hpPercent > = pst - > getMinHp ( ) & & hpPercent < = pst - > getMaxHp ( ) ) {
showParticle = true ;
}
}
2011-07-01 23:47:54 +02:00
//printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle);
if ( showParticle = = true ) {
//printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp);
UnitParticleSystem * ups = new UnitParticleSystem ( 200 ) ;
pst - > setValues ( ups ) ;
ups - > setPos ( getCurrVector ( ) ) ;
2011-09-27 09:01:08 +02:00
if ( getFaction ( ) - > getTexture ( ) ) {
ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
2011-07-01 23:47:54 +02:00
damageParticleSystems . push_back ( ups ) ;
damageParticleSystemsInUse [ i ] = ups ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
}
2010-03-12 08:42:55 +01:00
}
}
2011-07-01 23:47:54 +02:00
}
void Unit : : startDamageParticles ( ) {
2011-07-02 05:59:46 +02:00
if ( hp < type - > getMaxHp ( ) / 2 & & hp > 0 & & alive = = true ) {
2011-07-01 23:47:54 +02:00
//start additional particles
2011-12-03 01:39:03 +01:00
if ( showUnitParticles & &
type - > damageParticleSystemTypes . empty ( ) = = false ) {
2011-07-01 23:47:54 +02:00
for ( unsigned int i = 0 ; i < type - > damageParticleSystemTypes . size ( ) ; + + i ) {
UnitParticleSystemType * pst = type - > damageParticleSystemTypes [ i ] ;
if ( pst - > getMinmaxEnabled ( ) = = false & & damageParticleSystemsInUse . find ( i ) = = damageParticleSystemsInUse . end ( ) ) {
UnitParticleSystem * ups = new UnitParticleSystem ( 200 ) ;
pst - > setValues ( ups ) ;
ups - > setPos ( getCurrVector ( ) ) ;
2011-09-27 09:01:08 +02:00
if ( getFaction ( ) - > getTexture ( ) ) {
ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
}
2011-07-01 23:47:54 +02:00
damageParticleSystems . push_back ( ups ) ;
damageParticleSystemsInUse [ i ] = ups ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
}
2010-03-12 08:42:55 +01:00
}
2011-07-01 23:47:54 +02:00
// start fire
if ( type - > getProperty ( UnitType : : pBurnable ) & & fire = = NULL ) {
FireParticleSystem * fps = new FireParticleSystem ( 200 ) ;
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
fps - > setSpeed ( 2.5f / game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
fps - > setPos ( getCurrVector ( ) ) ;
fps - > setRadius ( type - > getSize ( ) / 3.f ) ;
fps - > setTexture ( CoreData : : getInstance ( ) . getFireTexture ( ) ) ;
fps - > setParticleSize ( type - > getSize ( ) / 3.f ) ;
fire = fps ;
fireParticleSystems . push_back ( fps ) ;
Renderer : : getInstance ( ) . manageParticleSystem ( fps , rsGame ) ;
2011-12-03 01:39:03 +01:00
if ( showUnitParticles = = true ) {
2011-07-01 23:47:54 +02:00
// smoke
UnitParticleSystem * ups = new UnitParticleSystem ( 400 ) ;
ups - > setColorNoEnergy ( Vec4f ( 0.0f , 0.0f , 0.0f , 0.13f ) ) ;
ups - > setColor ( Vec4f ( 0.115f , 0.115f , 0.115f , 0.22f ) ) ;
ups - > setPos ( getCurrVector ( ) ) ;
ups - > setBlendMode ( ups - > strToBlendMode ( " black " ) ) ;
ups - > setOffset ( Vec3f ( 0 , 2 , 0 ) ) ;
ups - > setDirection ( Vec3f ( 0 , 1 , - 0.2f ) ) ;
ups - > setRadius ( type - > getSize ( ) / 3.f ) ;
2011-07-08 08:36:36 +02:00
ups - > setShape ( Shared : : Graphics : : UnitParticleSystem : : sLinear ) ;
2011-07-01 23:47:54 +02:00
ups - > setTexture ( CoreData : : getInstance ( ) . getFireTexture ( ) ) ;
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
ups - > setSpeed ( 2.0f / game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
ups - > setGravity ( 0.0004f ) ;
ups - > setEmissionRate ( 1 ) ;
ups - > setMaxParticleEnergy ( 150 ) ;
ups - > setSizeNoEnergy ( type - > getSize ( ) * 0.6f ) ;
ups - > setParticleSize ( type - > getSize ( ) * 0.8f ) ;
2011-07-04 17:55:13 +02:00
smokeParticleSystems . push_back ( ups ) ;
//damageParticleSystemsInUse[-1] = ups;
2011-07-01 23:47:54 +02:00
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
}
2010-03-12 08:42:55 +01:00
}
2011-07-01 23:47:54 +02:00
checkCustomizedParticleTriggers ( false ) ;
2010-03-12 08:42:55 +01:00
}
2010-04-27 05:36:36 +02:00
void Unit : : setTargetVec ( const Vec3f & targetVec ) {
this - > targetVec = targetVec ;
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2010-04-27 05:36:36 +02:00
}
void Unit : : setMeetingPos ( const Vec2i & meetingPos ) {
2011-02-25 05:15:22 +01:00
this - > meetingPos = meetingPos ;
map - > clampPos ( this - > meetingPos ) ;
if ( map - > isInside ( this - > meetingPos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( this - > meetingPos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #8 Invalid path position = " + this - > meetingPos . getString ( ) ) ;
2011-02-23 08:03:38 +01:00
}
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2010-04-27 16:10:53 +02:00
}
2010-05-11 01:56:55 +02:00
bool Unit : : isMeetingPointSettable ( ) const {
return ( type ! = NULL ? type - > getMeetingPoint ( ) : false ) ;
}
2011-04-04 06:32:01 +02:00
int Unit : : getFrameCount ( ) const {
2010-04-27 16:10:53 +02:00
int frameCount = 0 ;
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
if ( game ! = NULL & & game - > getWorld ( ) ! = NULL ) {
frameCount = game - > getWorld ( ) - > getFrameCount ( ) ;
}
return frameCount ;
2010-04-27 05:36:36 +02:00
}
2010-09-09 03:44:25 +02:00
void Unit : : exploreCells ( ) {
if ( this - > isOperative ( ) ) {
const Vec2i & newPos = this - > getCenteredPos ( ) ;
int sightRange = this - > getType ( ) - > getSight ( ) ;
int teamIndex = this - > getTeam ( ) ;
if ( game = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " game == NULL " ) ;
2010-09-09 03:44:25 +02:00
}
else if ( game - > getWorld ( ) = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " game->getWorld() = = NULL " ) ;
2010-09-09 03:44:25 +02:00
}
game - > getWorld ( ) - > exploreCells ( newPos , sightRange , teamIndex ) ;
}
}
2010-12-02 00:38:03 +01:00
void Unit : : logSynchData ( string file , int line , string source ) {
2010-04-27 05:36:36 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2010-12-26 02:13:04 +01:00
2012-10-19 03:31:20 +02:00
snprintf ( szBuf , 8096 ,
2010-12-26 02:13:04 +01:00
" FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [%f], progress2 [%d] \n Unit Path [%s] \n " ,
getFrameCount ( ) ,
id ,
getFullName ( ) . c_str ( ) ,
faction - > getType ( ) - > getName ( ) . c_str ( ) ,
//getDesc().c_str(),
pos . getString ( ) . c_str ( ) ,
lastPos . getString ( ) . c_str ( ) ,
targetPos . getString ( ) . c_str ( ) ,
targetVec . getString ( ) . c_str ( ) ,
meetingPos . getString ( ) . c_str ( ) ,
// lastRotation,
// targetRotation,
// rotation,
progress ,
progress2 ,
( unitPath ! = NULL ? unitPath - > toString ( ) . c_str ( ) : " NULL " ) ) ;
2010-12-02 00:38:03 +01:00
if ( lastSynchDataString ! = string ( szBuf ) | |
lastFile ! = file | |
lastLine ! = line | |
lastSource ! = source ) {
2010-04-27 05:36:36 +02:00
lastSynchDataString = string ( szBuf ) ;
2010-12-02 00:38:03 +01:00
lastFile = file ;
2010-12-01 00:32:39 +01:00
lastSource = source ;
2010-04-27 05:36:36 +02:00
2010-12-01 00:32:39 +01:00
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 ) ;
if ( source ! = " " ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " %s " , source . c_str ( ) ) ;
}
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " %s \n " , szBuf ) ;
2010-12-01 00:32:39 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugWorldSynch , " ------------------------------------ END [%d] ------------------------------------------------- \n " , getFrameCount ( ) ) ;
2010-04-27 05:36:36 +02:00
}
}
}
2010-10-17 10:50:27 +02:00
void Unit : : addBadHarvestPos ( const Vec2i & value ) {
2010-12-01 00:32:39 +01:00
//Chrono chron;
//chron.start();
badHarvestPosList [ value ] = getFrameCount ( ) ;
2010-10-17 10:50:27 +02:00
cleanupOldBadHarvestPos ( ) ;
}
void Unit : : removeBadHarvestPos ( const Vec2i & value ) {
2010-12-01 00:32:39 +01:00
std : : map < Vec2i , int > : : iterator iter = badHarvestPosList . find ( value ) ;
2010-10-24 03:49:25 +02:00
if ( iter ! = badHarvestPosList . end ( ) ) {
badHarvestPosList . erase ( value ) ;
}
cleanupOldBadHarvestPos ( ) ;
2010-10-17 10:50:27 +02:00
}
void Unit : : cleanupOldBadHarvestPos ( ) {
2010-12-01 00:32:39 +01:00
const int cleanupInterval = ( GameConstants : : updateFps * 5 ) ;
bool needToCleanup = ( getFrameCount ( ) % cleanupInterval = = 0 ) ;
2011-01-28 08:17:32 +01:00
//printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld] cleanupInterval [%d] getFrameCount() [%d] needToCleanup [%d]\n",getFrameCount(),badHarvestPosList.size(),cleanupInterval,getFrameCount(),needToCleanup);
2010-12-01 00:32:39 +01:00
if ( needToCleanup = = true ) {
//printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld]\n",getFrameCount(),badHarvestPosList.size());
2010-10-24 03:49:25 +02:00
std : : vector < Vec2i > purgeList ;
2011-12-02 18:46:02 +01:00
for ( std : : map < Vec2i , int > : : iterator iter = badHarvestPosList . begin ( ) ; iter ! = badHarvestPosList . end ( ) ; + + iter ) {
2010-12-01 00:32:39 +01:00
if ( getFrameCount ( ) - iter - > second > = cleanupInterval ) {
//printf("cleanupOldBadHarvestPos() [%d][%d]\n",getFrameCount(),iter->second);
2010-10-24 03:49:25 +02:00
purgeList . push_back ( iter - > first ) ;
}
}
2010-12-01 00:32:39 +01:00
2011-09-01 03:11:23 +02:00
if ( purgeList . empty ( ) = = false ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [cleaning old bad harvest targets] purgeList.size() [ " MG_SIZE_T_SPECIFIER " ] " , purgeList . size ( ) ) ;
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2010-12-01 00:32:39 +01:00
for ( int i = 0 ; i < purgeList . size ( ) ; + + i ) {
const Vec2i & item = purgeList [ i ] ;
badHarvestPosList . erase ( item ) ;
}
2010-10-24 03:49:25 +02:00
}
}
2010-10-17 10:50:27 +02:00
}
void Unit : : setLastHarvestResourceTarget ( const Vec2i * pos ) {
if ( pos = = NULL ) {
lastHarvestResourceTarget . first = Vec2i ( 0 ) ;
//lastHarvestResourceTarget.second = 0;
}
else {
const Vec2i resourceLocation = * pos ;
if ( resourceLocation ! = lastHarvestResourceTarget . first ) {
lastHarvestResourceTarget . first = resourceLocation ;
2010-12-01 00:32:39 +01:00
//Chrono chron;
//chron.start();
lastHarvestResourceTarget . second = getFrameCount ( ) ;
2010-10-17 10:50:27 +02:00
}
else {
// If we cannot harvest for > 10 seconds tag the position
// as a bad one
2010-12-01 00:32:39 +01:00
const int addInterval = ( GameConstants : : updateFps * 5 ) ;
if ( lastHarvestResourceTarget . second - getFrameCount ( ) > = addInterval ) {
2011-06-25 22:44:46 +02:00
//printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second);
2010-10-17 10:50:27 +02:00
addBadHarvestPos ( resourceLocation ) ;
}
}
}
}
2011-03-29 18:27:01 +02:00
//void Unit::addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell) {
// if(currentTargetPathTaken.first != target) {
// currentTargetPathTaken.second.clear();
// }
// currentTargetPathTaken.first = target;
// currentTargetPathTaken.second.push_back(cell);
//}
2010-10-20 00:26:49 +02:00
2011-04-14 04:51:13 +02:00
void Unit : : setLastPathfindFailedFrameToCurrentFrame ( ) {
lastPathfindFailedFrame = getFrameCount ( ) ;
}
bool Unit : : isLastPathfindFailedFrameWithinCurrentFrameTolerance ( ) const {
static const bool enablePathfinderEnlargeMaxNodes = Config : : getInstance ( ) . getBool ( " EnablePathfinderEnlargeMaxNodes " , " false " ) ;
2011-04-26 23:51:18 +02:00
bool result = enablePathfinderEnlargeMaxNodes ;
2011-04-14 04:51:13 +02:00
if ( enablePathfinderEnlargeMaxNodes ) {
const int MIN_FRAME_ELAPSED_RETRY = 960 ;
result = ( getFrameCount ( ) - lastPathfindFailedFrame > = MIN_FRAME_ELAPSED_RETRY ) ;
}
return result ;
}
2011-04-04 06:32:01 +02:00
void Unit : : setLastStuckFrameToCurrentFrame ( ) {
lastStuckFrame = getFrameCount ( ) ;
}
bool Unit : : isLastStuckFrameWithinCurrentFrameTolerance ( ) const {
2011-04-14 04:51:13 +02:00
const int MIN_FRAME_ELAPSED_RETRY = 300 ;
bool result ( getFrameCount ( ) - lastStuckFrame < = MIN_FRAME_ELAPSED_RETRY ) ;
2011-04-04 06:32:01 +02:00
return result ;
}
2011-05-01 07:36:04 +02:00
Vec2i Unit : : getPosWithCellMapSet ( ) const {
Vec2i cellMapPos = this - > getType ( ) - > getFirstOccupiedCellInCellMap ( pos ) ;
return cellMapPos ;
}
2011-12-13 02:30:52 +01:00
string Unit : : getUniquePickName ( ) const {
string result = intToStr ( id ) + " - " + type - > getName ( ) + " : " ;
result + = pos . getString ( ) ;
return result ;
}
2010-05-18 05:53:57 +02:00
std : : string Unit : : toString ( ) const {
std : : string result = " " ;
result + = " id = " + intToStr ( this - > id ) ;
if ( this - > type ! = NULL ) {
2011-01-02 01:39:13 +01:00
result + = " name [ " + this - > type - > getName ( ) + " ][ " + intToStr ( this - > type - > getId ( ) ) + " ] " ;
2010-05-18 05:53:57 +02:00
}
2010-05-29 07:41:40 +02:00
2010-05-29 18:55:55 +02:00
if ( this - > faction ! = NULL ) {
2010-05-31 08:11:31 +02:00
result + = " \n FactionIndex = " + intToStr ( this - > faction - > getIndex ( ) ) + " \n " ;
2010-05-29 18:55:55 +02:00
result + = " teamIndex = " + intToStr ( this - > faction - > getTeam ( ) ) + " \n " ;
result + = " startLocationIndex = " + intToStr ( this - > faction - > getStartLocationIndex ( ) ) + " \n " ;
result + = " thisFaction = " + intToStr ( this - > faction - > getThisFaction ( ) ) + " \n " ;
result + = " control = " + intToStr ( this - > faction - > getControlType ( ) ) + " \n " ;
if ( this - > faction - > getType ( ) ! = NULL ) {
result + = " factionName = " + this - > faction - > getType ( ) - > getName ( ) + " \n " ;
}
}
2010-05-29 07:41:40 +02:00
2010-05-18 05:53:57 +02:00
result + = " hp = " + intToStr ( this - > hp ) ;
result + = " ep = " + intToStr ( this - > ep ) ;
result + = " loadCount = " + intToStr ( this - > loadCount ) ;
result + = " deadCount = " + intToStr ( this - > deadCount ) ;
result + = " progress = " + floatToStr ( this - > progress ) ;
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " lastAnimProgress = " + floatToStr ( this - > lastAnimProgress ) ;
result + = " animProgress = " + floatToStr ( this - > animProgress ) ;
result + = " highlight = " + floatToStr ( this - > highlight ) ;
result + = " progress2 = " + intToStr ( this - > progress2 ) ;
result + = " kills = " + intToStr ( this - > kills ) ;
2011-04-20 18:46:47 +02:00
result + = " enemyKills = " + intToStr ( this - > enemyKills ) ;
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-29 07:41:40 +02:00
2010-06-02 10:03:56 +02:00
// WARNING!!! Don't access the Unit pointer in this->targetRef in this method or it causes
// a stack overflow
if ( this - > targetRef . getUnitId ( ) > = 0 ) {
//result += " targetRef = " + this->targetRef.getUnit()->toString();
result + = " targetRef = " + intToStr ( this - > targetRef . getUnitId ( ) ) + " - factionIndex = " + intToStr ( this - > targetRef . getUnitFaction ( ) - > getIndex ( ) ) ;
2010-05-18 05:53:57 +02:00
}
2010-05-29 07:41:40 +02:00
2010-05-18 05:53:57 +02:00
result + = " currField = " + intToStr ( this - > currField ) ;
result + = " targetField = " + intToStr ( this - > targetField ) ;
if ( level ! = NULL ) {
result + = " level = " + level - > getName ( ) ;
}
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " pos = " + pos . getString ( ) ;
result + = " lastPos = " + lastPos . getString ( ) ;
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " targetPos = " + targetPos . getString ( ) ;
result + = " targetVec = " + targetVec . getString ( ) ;
result + = " meetingPos = " + meetingPos . getString ( ) ;
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " lastRotation = " + floatToStr ( this - > lastRotation ) ;
result + = " targetRotation = " + floatToStr ( this - > targetRotation ) ;
result + = " rotation = " + floatToStr ( this - > rotation ) ;
if ( loadType ! = NULL ) {
result + = " loadType = " + loadType - > getName ( ) ;
}
if ( currSkill ! = NULL ) {
result + = " currSkill = " + currSkill - > getName ( ) ;
}
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " toBeUndertaken = " + intToStr ( this - > toBeUndertaken ) ;
result + = " alive = " + intToStr ( this - > alive ) ;
result + = " showUnitParticles = " + intToStr ( this - > showUnitParticles ) ;
result + = " totalUpgrade = " + totalUpgrade . toString ( ) ;
2010-07-21 20:21:40 +02:00
result + = " " + this - > unitPath - > toString ( ) + " \n " ;
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " Command count = " + intToStr ( commands . size ( ) ) + " \n " ;
int cmdIdx = 0 ;
for ( Commands : : const_iterator iterList = commands . begin ( ) ; iterList ! = commands . end ( ) ; + + iterList ) {
result + = " index = " + intToStr ( cmdIdx ) + " " ;
const Command * cmd = * iterList ;
if ( cmd ! = NULL ) {
result + = cmd - > toString ( ) + " \n " ;
}
cmdIdx + + ;
}
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-18 05:53:57 +02:00
result + = " modelFacing = " + intToStr ( modelFacing . asInt ( ) ) + " \n " ;
2010-08-28 03:46:26 +02:00
result + = " retryCurrCommandCount = " + intToStr ( retryCurrCommandCount ) + " \n " ;
2010-09-01 01:14:15 +02:00
result + = " screenPos = " + screenPos . getString ( ) + " \n " ;
result + = " currentUnitTitle = " + currentUnitTitle + " \n " ;
2010-10-17 08:34:42 +02:00
result + = " inBailOutAttempt = " + intToStr ( inBailOutAttempt ) + " \n " ;
2012-05-12 03:06:55 +02:00
result + = " random = " + intToStr ( random . getLastNumber ( ) ) + " \n " ;
result + = " pathFindRefreshCellCount = " + intToStr ( pathFindRefreshCellCount ) + " \n " ;
2010-05-18 05:53:57 +02:00
return result ;
}
2012-03-10 04:27:25 +01:00
void Unit : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * unitNode = rootNode - > addChild ( " Unit " ) ;
// const int id;
unitNode - > addAttribute ( " id " , intToStr ( id ) , mapTagReplacements ) ;
2012-03-30 05:20:33 +02:00
// For info purposes only
unitNode - > addAttribute ( " name " , type - > getName ( ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// int hp;
unitNode - > addAttribute ( " hp " , intToStr ( hp ) , mapTagReplacements ) ;
// int ep;
unitNode - > addAttribute ( " ep " , intToStr ( ep ) , mapTagReplacements ) ;
// int loadCount;
unitNode - > addAttribute ( " loadCount " , intToStr ( loadCount ) , mapTagReplacements ) ;
// int deadCount;
unitNode - > addAttribute ( " deadCount " , intToStr ( deadCount ) , mapTagReplacements ) ;
// float progress; //between 0 and 1
unitNode - > addAttribute ( " progress " , floatToStr ( progress ) , mapTagReplacements ) ;
// float lastAnimProgress; //between 0 and 1
unitNode - > addAttribute ( " lastAnimProgress " , floatToStr ( lastAnimProgress ) , mapTagReplacements ) ;
// float animProgress; //between 0 and 1
unitNode - > addAttribute ( " animProgress " , floatToStr ( animProgress ) , mapTagReplacements ) ;
// float highlight;
unitNode - > addAttribute ( " highlight " , floatToStr ( highlight ) , mapTagReplacements ) ;
// int progress2;
unitNode - > addAttribute ( " progress2 " , intToStr ( progress2 ) , mapTagReplacements ) ;
// int kills;
unitNode - > addAttribute ( " kills " , intToStr ( kills ) , mapTagReplacements ) ;
// int enemyKills;
unitNode - > addAttribute ( " enemyKills " , intToStr ( enemyKills ) , mapTagReplacements ) ;
// UnitReference targetRef;
targetRef . saveGame ( unitNode ) ;
//
// Field currField;
unitNode - > addAttribute ( " currField " , intToStr ( currField ) , mapTagReplacements ) ;
// Field targetField;
unitNode - > addAttribute ( " targetField " , intToStr ( targetField ) , mapTagReplacements ) ;
// const Level *level;
if ( level ! = NULL ) {
level - > saveGame ( unitNode ) ;
}
// Vec2i pos;
unitNode - > addAttribute ( " pos " , pos . getString ( ) , mapTagReplacements ) ;
// Vec2i lastPos;
unitNode - > addAttribute ( " lastPos " , lastPos . getString ( ) , mapTagReplacements ) ;
// Vec2i targetPos; //absolute target pos
unitNode - > addAttribute ( " targetPos " , targetPos . getString ( ) , mapTagReplacements ) ;
// Vec3f targetVec;
unitNode - > addAttribute ( " targetVec " , targetVec . getString ( ) , mapTagReplacements ) ;
// Vec2i meetingPos;
unitNode - > addAttribute ( " meetingPos " , meetingPos . getString ( ) , mapTagReplacements ) ;
//
// float lastRotation; //in degrees
unitNode - > addAttribute ( " lastRotation " , floatToStr ( lastRotation ) , mapTagReplacements ) ;
// float targetRotation;
unitNode - > addAttribute ( " targetRotation " , floatToStr ( targetRotation ) , mapTagReplacements ) ;
// float rotation;
unitNode - > addAttribute ( " rotation " , floatToStr ( rotation ) , mapTagReplacements ) ;
// float targetRotationZ;
unitNode - > addAttribute ( " targetRotationZ " , floatToStr ( targetRotationZ ) , mapTagReplacements ) ;
// float targetRotationX;
unitNode - > addAttribute ( " targetRotationX " , floatToStr ( targetRotationX ) , mapTagReplacements ) ;
// float rotationZ;
unitNode - > addAttribute ( " rotationZ " , floatToStr ( rotationZ ) , mapTagReplacements ) ;
// float rotationX;
unitNode - > addAttribute ( " rotationX " , floatToStr ( rotationX ) , mapTagReplacements ) ;
// const UnitType *type;
unitNode - > addAttribute ( " type " , type - > getName ( ) , mapTagReplacements ) ;
// const ResourceType *loadType;
if ( loadType ! = NULL ) {
unitNode - > addAttribute ( " loadType " , loadType - > getName ( ) , mapTagReplacements ) ;
}
// const SkillType *currSkill;
if ( currSkill ! = NULL ) {
2012-03-13 16:21:25 +01:00
unitNode - > addAttribute ( " currSkillName " , currSkill - > getName ( ) , mapTagReplacements ) ;
unitNode - > addAttribute ( " currSkillClass " , intToStr ( currSkill - > getClass ( ) ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
}
// int lastModelIndexForCurrSkillType;
unitNode - > addAttribute ( " lastModelIndexForCurrSkillType " , intToStr ( lastModelIndexForCurrSkillType ) , mapTagReplacements ) ;
// int animationRandomCycleCount;
unitNode - > addAttribute ( " animationRandomCycleCount " , intToStr ( animationRandomCycleCount ) , mapTagReplacements ) ;
//
// bool toBeUndertaken;
unitNode - > addAttribute ( " toBeUndertaken " , intToStr ( toBeUndertaken ) , mapTagReplacements ) ;
// bool alive;
unitNode - > addAttribute ( " alive " , intToStr ( alive ) , mapTagReplacements ) ;
// bool showUnitParticles;
unitNode - > addAttribute ( " showUnitParticles " , intToStr ( showUnitParticles ) , mapTagReplacements ) ;
// Faction *faction;
// ParticleSystem *fire;
2012-03-30 05:20:33 +02:00
int linkFireIndex = - 1 ;
2012-03-14 00:18:09 +01:00
if ( fire ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( fire , rsGame ) = = true ) {
2012-03-30 05:20:33 +02:00
//fire->saveGame(unitNode);
bool fireInSystemList = false ;
if ( fireParticleSystems . empty ( ) = = false ) {
for ( unsigned int i = 0 ; i < fireParticleSystems . size ( ) ; + + i ) {
ParticleSystem * ps = fireParticleSystems [ i ] ;
if ( ps = = fire ) {
linkFireIndex = i ;
fireInSystemList = true ;
break ;
}
}
}
if ( fireInSystemList = = false ) {
fire - > saveGame ( unitNode ) ;
}
2012-03-10 04:27:25 +01:00
}
// TotalUpgrade totalUpgrade;
totalUpgrade . saveGame ( unitNode ) ;
// Map *map;
//
// UnitPathInterface *unitPath;
unitPath - > saveGame ( unitNode ) ;
// WaypointPath waypointPath;
//
// Commands commands;
for ( Commands : : iterator it = commands . begin ( ) ; it ! = commands . end ( ) ; + + it ) {
2012-03-13 16:21:25 +01:00
( * it ) - > saveGame ( unitNode , faction ) ;
2012-03-10 04:27:25 +01:00
}
// Observers observers;
2012-03-13 00:08:22 +01:00
//for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) {
// (*it)->saveGame(unitNode);
//}
2012-03-10 04:27:25 +01:00
// vector<UnitParticleSystem*> unitParticleSystems;
2012-03-28 08:25:57 +02:00
if ( unitParticleSystems . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
XmlNode * unitParticleSystemsNode = unitNode - > addChild ( " unitParticleSystems " ) ;
2012-03-14 08:23:41 +01:00
for ( unsigned int i = 0 ; i < unitParticleSystems . size ( ) ; + + i ) {
UnitParticleSystem * ups = unitParticleSystems [ i ] ;
if ( ups ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ups , rsGame ) = = true ) {
ups - > saveGame ( unitParticleSystemsNode ) ;
}
2012-03-13 23:37:47 +01:00
}
2012-03-10 04:27:25 +01:00
}
// vector<UnitParticleSystemType*> queuedUnitParticleSystemTypes;
2012-03-28 08:25:57 +02:00
if ( queuedUnitParticleSystemTypes . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
XmlNode * queuedUnitParticleSystemTypesNode = unitNode - > addChild ( " queuedUnitParticleSystemTypes " ) ;
2012-03-14 08:23:41 +01:00
for ( unsigned int i = 0 ; i < queuedUnitParticleSystemTypes . size ( ) ; + + i ) {
UnitParticleSystemType * upst = queuedUnitParticleSystemTypes [ i ] ;
if ( upst ! = NULL ) {
upst - > saveGame ( queuedUnitParticleSystemTypesNode ) ;
}
2012-03-13 23:37:47 +01:00
}
2012-03-10 04:27:25 +01:00
}
// UnitParticleSystems damageParticleSystems;
2012-03-28 08:25:57 +02:00
if ( damageParticleSystems . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
XmlNode * damageParticleSystemsNode = unitNode - > addChild ( " damageParticleSystems " ) ;
2012-03-14 08:23:41 +01:00
for ( unsigned int i = 0 ; i < damageParticleSystems . size ( ) ; + + i ) {
UnitParticleSystem * ups = damageParticleSystems [ i ] ;
if ( ups ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ups , rsGame ) = = true ) {
ups - > saveGame ( damageParticleSystemsNode ) ;
}
2012-03-13 23:37:47 +01:00
}
2012-03-10 04:27:25 +01:00
}
// std::map<int, UnitParticleSystem *> damageParticleSystemsInUse;
2012-03-28 08:25:57 +02:00
if ( damageParticleSystemsInUse . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
XmlNode * damageParticleSystemsInUseNode = unitNode - > addChild ( " damageParticleSystemsInUse " ) ;
2012-03-14 08:23:41 +01:00
for ( std : : map < int , UnitParticleSystem * > : : const_iterator iterMap = damageParticleSystemsInUse . begin ( ) ;
iterMap ! = damageParticleSystemsInUse . end ( ) ; + + iterMap ) {
if ( iterMap - > second ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( iterMap - > second , rsGame ) = = true ) {
XmlNode * damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode - > addChild ( " damageParticleSystemsInUse " ) ;
2012-03-10 04:27:25 +01:00
2012-03-14 08:23:41 +01:00
damageParticleSystemsInUseNode2 - > addAttribute ( " key " , intToStr ( iterMap - > first ) , mapTagReplacements ) ;
iterMap - > second - > saveGame ( damageParticleSystemsInUseNode2 ) ;
}
2012-03-13 23:37:47 +01:00
}
2012-03-10 04:27:25 +01:00
}
2012-03-14 08:23:41 +01:00
2012-03-10 04:27:25 +01:00
// vector<ParticleSystem*> fireParticleSystems;
2012-03-28 08:25:57 +02:00
if ( fireParticleSystems . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
XmlNode * fireParticleSystemsNode = unitNode - > addChild ( " fireParticleSystems " ) ;
2012-03-30 05:20:33 +02:00
if ( linkFireIndex > = 0 ) {
fireParticleSystemsNode - > addAttribute ( " fireParticleLink " , intToStr ( linkFireIndex ) , mapTagReplacements ) ;
}
2012-03-14 08:23:41 +01:00
for ( unsigned int i = 0 ; i < fireParticleSystems . size ( ) ; + + i ) {
ParticleSystem * ps = fireParticleSystems [ i ] ;
if ( ps ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ps , rsGame ) = = true ) {
ps - > saveGame ( fireParticleSystemsNode ) ;
}
2012-03-13 23:37:47 +01:00
}
2012-03-10 04:27:25 +01:00
}
// vector<UnitParticleSystem*> smokeParticleSystems;
2012-03-28 08:25:57 +02:00
if ( smokeParticleSystems . empty ( ) = = false ) {
2012-03-19 22:35:54 +01:00
XmlNode * smokeParticleSystemsNode = unitNode - > addChild ( " smokeParticleSystems " ) ;
2012-03-14 08:23:41 +01:00
for ( unsigned int i = 0 ; i < smokeParticleSystems . size ( ) ; + + i ) {
UnitParticleSystem * ups = smokeParticleSystems [ i ] ;
if ( ups ! = NULL & & Renderer : : getInstance ( ) . validateParticleSystemStillExists ( ups , rsGame ) = = true ) {
ups - > saveGame ( smokeParticleSystemsNode ) ;
2012-03-19 22:35:54 +01:00
//printf("Saving smoke particles:\n[%s]\n",ups->toString().c_str());
2012-03-14 08:23:41 +01:00
}
2012-03-13 23:37:47 +01:00
}
2012-03-10 04:27:25 +01:00
}
// CardinalDir modelFacing;
unitNode - > addAttribute ( " modelFacing " , intToStr ( modelFacing ) , mapTagReplacements ) ;
// std::string lastSynchDataString;
unitNode - > addAttribute ( " lastSynchDataString " , lastSynchDataString , mapTagReplacements ) ;
// std::string lastFile;
unitNode - > addAttribute ( " lastFile " , lastFile , mapTagReplacements ) ;
// int lastLine;
unitNode - > addAttribute ( " lastLine " , intToStr ( lastLine ) , mapTagReplacements ) ;
// std::string lastSource;
unitNode - > addAttribute ( " lastSource " , lastSource , mapTagReplacements ) ;
// int lastRenderFrame;
unitNode - > addAttribute ( " lastRenderFrame " , intToStr ( lastRenderFrame ) , mapTagReplacements ) ;
// bool visible;
unitNode - > addAttribute ( " visible " , intToStr ( visible ) , mapTagReplacements ) ;
// int retryCurrCommandCount;
unitNode - > addAttribute ( " retryCurrCommandCount " , intToStr ( retryCurrCommandCount ) , mapTagReplacements ) ;
// Vec3f screenPos;
unitNode - > addAttribute ( " screenPos " , screenPos . getString ( ) , mapTagReplacements ) ;
// string currentUnitTitle;
unitNode - > addAttribute ( " currentUnitTitle " , currentUnitTitle , mapTagReplacements ) ;
//
// bool inBailOutAttempt;
unitNode - > addAttribute ( " inBailOutAttempt " , intToStr ( inBailOutAttempt ) , mapTagReplacements ) ;
// //std::vector<std::pair<Vec2i,Chrono> > badHarvestPosList;
// std::map<Vec2i,int> badHarvestPosList;
for ( std : : map < Vec2i , int > : : const_iterator iterMap = badHarvestPosList . begin ( ) ;
iterMap ! = badHarvestPosList . end ( ) ; + + iterMap ) {
XmlNode * badHarvestPosListNode = unitNode - > addChild ( " badHarvestPosList " ) ;
badHarvestPosListNode - > addAttribute ( " key " , iterMap - > first . getString ( ) , mapTagReplacements ) ;
badHarvestPosListNode - > addAttribute ( " value " , intToStr ( iterMap - > second ) , mapTagReplacements ) ;
}
// //time_t lastBadHarvestListPurge;
// std::pair<Vec2i,int> lastHarvestResourceTarget;
XmlNode * lastHarvestResourceTargetNode = unitNode - > addChild ( " lastHarvestResourceTarget " ) ;
lastHarvestResourceTargetNode - > addAttribute ( " key " , lastHarvestResourceTarget . first . getString ( ) , mapTagReplacements ) ;
lastHarvestResourceTargetNode - > addAttribute ( " value " , intToStr ( lastHarvestResourceTarget . second ) , mapTagReplacements ) ;
// //std::pair<Vec2i,std::vector<Vec2i> > currentTargetPathTaken;
// static Game *game;
//
// bool ignoreCheckCommand;
unitNode - > addAttribute ( " ignoreCheckCommand " , intToStr ( ignoreCheckCommand ) , mapTagReplacements ) ;
// uint32 lastStuckFrame;
unitNode - > addAttribute ( " lastStuckFrame " , intToStr ( lastStuckFrame ) , mapTagReplacements ) ;
// Vec2i lastStuckPos;
unitNode - > addAttribute ( " lastStuckPos " , lastStuckPos . getString ( ) , mapTagReplacements ) ;
// uint32 lastPathfindFailedFrame;
unitNode - > addAttribute ( " lastPathfindFailedFrame " , intToStr ( lastPathfindFailedFrame ) , mapTagReplacements ) ;
// Vec2i lastPathfindFailedPos;
unitNode - > addAttribute ( " lastPathfindFailedPos " , lastPathfindFailedPos . getString ( ) , mapTagReplacements ) ;
// bool usePathfinderExtendedMaxNodes;
unitNode - > addAttribute ( " usePathfinderExtendedMaxNodes " , intToStr ( usePathfinderExtendedMaxNodes ) , mapTagReplacements ) ;
// int maxQueuedCommandDisplayCount;
unitNode - > addAttribute ( " maxQueuedCommandDisplayCount " , intToStr ( maxQueuedCommandDisplayCount ) , mapTagReplacements ) ;
// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
currentAttackBoostOriginatorEffect . saveGame ( unitNode ) ;
// std::vector<UnitAttackBoostEffect *> currentAttackBoostEffects;
for ( unsigned int i = 0 ; i < currentAttackBoostEffects . size ( ) ; + + i ) {
UnitAttackBoostEffect * uabe = currentAttackBoostEffects [ i ] ;
2012-03-14 00:51:39 +01:00
if ( uabe ! = NULL ) {
uabe - > saveGame ( unitNode ) ;
}
2012-03-10 04:27:25 +01:00
}
// Mutex *mutexCommands;
//
// //static Mutex mutexDeletedUnits;
// //static std::map<void *,bool> deletedUnits;
//
// bool changedActiveCommand;
unitNode - > addAttribute ( " changedActiveCommand " , intToStr ( changedActiveCommand ) , mapTagReplacements ) ;
// int lastAttackerUnitId;
unitNode - > addAttribute ( " lastAttackerUnitId " , intToStr ( lastAttackerUnitId ) , mapTagReplacements ) ;
// int lastAttackedUnitId;
unitNode - > addAttribute ( " lastAttackedUnitId " , intToStr ( lastAttackedUnitId ) , mapTagReplacements ) ;
// CauseOfDeathType causeOfDeath;
unitNode - > addAttribute ( " causeOfDeath " , intToStr ( causeOfDeath ) , mapTagReplacements ) ;
2012-04-29 06:45:51 +02:00
//pathfindFailedConsecutiveFrameCount
unitNode - > addAttribute ( " pathfindFailedConsecutiveFrameCount " , intToStr ( pathfindFailedConsecutiveFrameCount ) , mapTagReplacements ) ;
2012-05-04 16:57:59 +02:00
unitNode - > addAttribute ( " currentPathFinderDesiredFinalPos " , currentPathFinderDesiredFinalPos . getString ( ) , mapTagReplacements ) ;
2012-05-12 03:06:55 +02:00
unitNode - > addAttribute ( " random " , intToStr ( random . getLastNumber ( ) ) , mapTagReplacements ) ;
unitNode - > addAttribute ( " pathFindRefreshCellCount " , intToStr ( pathFindRefreshCellCount ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
}
2012-03-13 00:08:22 +01:00
Unit * Unit : : loadGame ( const XmlNode * rootNode , GameSettings * settings , Faction * faction , World * world ) {
const XmlNode * unitNode = rootNode ;
int newUnitId = unitNode - > getAttribute ( " id " ) - > getIntValue ( ) ;
Vec2i newUnitPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " pos " ) - > getValue ( ) ) ;
string newUnitType = unitNode - > getAttribute ( " type " ) - > getValue ( ) ;
const UnitType * ut = faction - > getType ( ) - > getUnitType ( newUnitType ) ;
CardinalDir newModelFacing = static_cast < CardinalDir > ( unitNode - > getAttribute ( " modelFacing " ) - > getIntValue ( ) ) ;
// Unit *result = new Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos,
// const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) {
UnitPathInterface * newpath = NULL ;
switch ( settings - > getPathFinderType ( ) ) {
case pfBasic :
newpath = new UnitPathBasic ( ) ;
break ;
default :
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " detected unsupported pathfinder type! " ) ;
2012-03-13 00:08:22 +01:00
}
//Unit *result = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH);
//Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
Unit * result = new Unit ( newUnitId , newpath , newUnitPos , ut , faction , world - > getMapPtr ( ) , newModelFacing ) ;
result - > lastRotation = unitNode - > getAttribute ( " lastRotation " ) - > getFloatValue ( ) ;
result - > targetRotation = unitNode - > getAttribute ( " targetRotation " ) - > getFloatValue ( ) ;
result - > rotation = unitNode - > getAttribute ( " rotation " ) - > getFloatValue ( ) ;
//world->placeUnitAtLocation(newUnitPos, generationArea, unit, true);
result - > setPos ( newUnitPos ) ;
Vec2i meetingPos = newUnitPos - Vec2i ( 1 ) ;
result - > setMeetingPos ( meetingPos ) ;
2012-03-13 02:34:14 +01:00
// --------------------------
result - > hp = unitNode - > getAttribute ( " hp " ) - > getIntValue ( ) ;
// int ep;
result - > ep = unitNode - > getAttribute ( " ep " ) - > getIntValue ( ) ;
// int loadCount;
result - > loadCount = unitNode - > getAttribute ( " loadCount " ) - > getIntValue ( ) ;
// int deadCount;
result - > deadCount = unitNode - > getAttribute ( " deadCount " ) - > getIntValue ( ) ;
// float progress; //between 0 and 1
result - > progress = unitNode - > getAttribute ( " progress " ) - > getFloatValue ( ) ;
// float lastAnimProgress; //between 0 and 1
result - > lastAnimProgress = unitNode - > getAttribute ( " lastAnimProgress " ) - > getFloatValue ( ) ;
// float animProgress; //between 0 and 1
result - > animProgress = unitNode - > getAttribute ( " animProgress " ) - > getFloatValue ( ) ;
// float highlight;
result - > highlight = unitNode - > getAttribute ( " highlight " ) - > getFloatValue ( ) ;
// int progress2;
result - > progress2 = unitNode - > getAttribute ( " progress2 " ) - > getIntValue ( ) ;
// int kills;
result - > kills = unitNode - > getAttribute ( " kills " ) - > getIntValue ( ) ;
// int enemyKills;
result - > enemyKills = unitNode - > getAttribute ( " enemyKills " ) - > getIntValue ( ) ;
// UnitReference targetRef;
// targetRef.saveGame(unitNode);
result - > targetRef . loadGame ( unitNode , world ) ;
//
// Field currField;
result - > currField = static_cast < Field > ( unitNode - > getAttribute ( " currField " ) - > getIntValue ( ) ) ;
// Field targetField;
result - > targetField = static_cast < Field > ( unitNode - > getAttribute ( " targetField " ) - > getIntValue ( ) ) ;
// const Level *level;
// if(level != NULL) {
// level->saveGame(unitNode);
// }
2012-03-13 16:21:25 +01:00
result - > level = Level : : loadGame ( unitNode , ut ) ;
2012-03-13 02:34:14 +01:00
// Vec2i pos;
2012-03-13 23:55:11 +01:00
result - > pos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " pos " ) - > getValue ( ) ) ;
2012-03-13 02:34:14 +01:00
// Vec2i lastPos;
2012-03-13 23:55:11 +01:00
result - > lastPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " lastPos " ) - > getValue ( ) ) ;
2012-03-13 02:34:14 +01:00
// Vec2i targetPos; //absolute target pos
result - > targetPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " targetPos " ) - > getValue ( ) ) ;
// Vec3f targetVec;
result - > targetVec = Vec3f : : strToVec3 ( unitNode - > getAttribute ( " targetVec " ) - > getValue ( ) ) ;
// Vec2i meetingPos;
2012-03-13 23:55:11 +01:00
result - > meetingPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " meetingPos " ) - > getValue ( ) ) ;
2012-03-13 02:34:14 +01:00
//
// float lastRotation; //in degrees
result - > lastRotation = unitNode - > getAttribute ( " lastRotation " ) - > getFloatValue ( ) ;
// float targetRotation;
result - > targetRotation = unitNode - > getAttribute ( " targetRotation " ) - > getFloatValue ( ) ;
// float rotation;
result - > rotation = unitNode - > getAttribute ( " rotation " ) - > getFloatValue ( ) ;
// float targetRotationZ;
result - > targetRotationZ = unitNode - > getAttribute ( " targetRotationZ " ) - > getFloatValue ( ) ;
// float targetRotationX;
result - > targetRotationX = unitNode - > getAttribute ( " targetRotationX " ) - > getFloatValue ( ) ;
// float rotationZ;
result - > rotationZ = unitNode - > getAttribute ( " rotationZ " ) - > getFloatValue ( ) ;
// float rotationX;
result - > rotationX = unitNode - > getAttribute ( " rotationX " ) - > getFloatValue ( ) ;
// const UnitType *type;
// unitNode->addAttribute("type",type->getName(), mapTagReplacements);
// const ResourceType *loadType;
// if(loadType != NULL) {
// unitNode->addAttribute("loadType",loadType->getName(), mapTagReplacements);
// }
2012-03-13 16:21:25 +01:00
if ( unitNode - > hasAttribute ( " loadType " ) = = true ) {
string loadTypeName = unitNode - > getAttribute ( " loadType " ) - > getValue ( ) ;
result - > loadType = world - > getTechTree ( ) - > getResourceType ( loadTypeName ) ;
}
2012-03-13 02:34:14 +01:00
// const SkillType *currSkill;
// if(currSkill != NULL) {
// unitNode->addAttribute("currSkill",currSkill->getName(), mapTagReplacements);
// }
2012-03-13 16:21:25 +01:00
if ( unitNode - > hasAttribute ( " currSkillName " ) = = true ) {
string skillTypeName = unitNode - > getAttribute ( " currSkillName " ) - > getValue ( ) ;
SkillClass skillClass = static_cast < SkillClass > ( unitNode - > getAttribute ( " currSkillClass " ) - > getIntValue ( ) ) ;
result - > currSkill = ut - > getSkillType ( skillTypeName , skillClass ) ;
}
2012-03-13 02:34:14 +01:00
// int lastModelIndexForCurrSkillType;
result - > lastModelIndexForCurrSkillType = unitNode - > getAttribute ( " lastModelIndexForCurrSkillType " ) - > getIntValue ( ) ;
// int animationRandomCycleCount;
result - > animationRandomCycleCount = unitNode - > getAttribute ( " animationRandomCycleCount " ) - > getIntValue ( ) ;
//
// bool toBeUndertaken;
2012-04-16 22:15:57 +02:00
result - > toBeUndertaken = unitNode - > getAttribute ( " toBeUndertaken " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// bool alive;
2012-04-16 22:15:57 +02:00
result - > alive = unitNode - > getAttribute ( " alive " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// bool showUnitParticles;
2012-04-16 22:15:57 +02:00
result - > showUnitParticles = unitNode - > getAttribute ( " showUnitParticles " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// Faction *faction;
// ParticleSystem *fire;
// if(fire != NULL) {
// fire->saveGame(unitNode);
// }
2012-03-14 08:23:41 +01:00
if ( unitNode - > hasChild ( " FireParticleSystem " ) = = true ) {
XmlNode * fireNode = unitNode - > getChild ( " FireParticleSystem " ) ;
result - > fire = new FireParticleSystem ( ) ;
result - > fire - > loadGame ( fireNode ) ;
2012-03-19 22:35:54 +01:00
//result->fire->setTexture(CoreData::getInstance().getFireTexture());
2012-03-14 08:23:41 +01:00
result - > fireParticleSystems . push_back ( result - > fire ) ;
//Renderer::getInstance().manageParticleSystem(result->fire, rsGame);
Renderer : : getInstance ( ) . addToDeferredParticleSystemList ( make_pair ( result - > fire , rsGame ) ) ;
}
2012-03-13 02:34:14 +01:00
// TotalUpgrade totalUpgrade;
2012-03-13 16:21:25 +01:00
result - > totalUpgrade . loadGame ( unitNode ) ;
2012-03-13 02:34:14 +01:00
// Map *map;
//
// UnitPathInterface *unitPath;
// unitPath->saveGame(unitNode);
// WaypointPath waypointPath;
//
// Commands commands;
// for(Commands::iterator it = commands.begin(); it != commands.end(); ++it) {
// (*it)->saveGame(unitNode);
// }
2012-03-13 16:21:25 +01:00
vector < XmlNode * > commandNodeList = unitNode - > getChildList ( " Command " ) ;
for ( unsigned int i = 0 ; i < commandNodeList . size ( ) ; + + i ) {
XmlNode * node = commandNodeList [ i ] ;
Command * command = Command : : loadGame ( node , ut , world ) ;
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( result - > mutexCommands , mutexOwnerId ) ;
result - > commands . push_back ( command ) ;
safeMutex . ReleaseLock ( ) ;
}
2012-03-13 02:34:14 +01:00
// Observers observers;
//for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) {
// (*it)->saveGame(unitNode);
//}
// vector<UnitParticleSystem*> unitParticleSystems;
// for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) {
// UnitParticleSystem *ups= unitParticleSystems[i];
// ups->saveGame(unitNode);
// }
2012-03-14 08:23:41 +01:00
if ( unitNode - > hasChild ( " unitParticleSystems " ) = = true ) {
XmlNode * unitParticleSystemsNode = unitNode - > getChild ( " unitParticleSystems " ) ;
vector < XmlNode * > unitParticleSystemNodeList = unitParticleSystemsNode - > getChildList ( " UnitParticleSystem " ) ;
for ( unsigned int i = 0 ; i < unitParticleSystemNodeList . size ( ) ; + + i ) {
XmlNode * node = unitParticleSystemNodeList [ i ] ;
UnitParticleSystem * ups = new UnitParticleSystem ( ) ;
ups - > loadGame ( node ) ;
result - > unitParticleSystems . push_back ( ups ) ;
//Renderer::getInstance().manageParticleSystem(result->fire, rsGame);
Renderer : : getInstance ( ) . addToDeferredParticleSystemList ( make_pair ( ups , rsGame ) ) ;
}
}
2012-03-13 22:58:31 +01:00
2012-03-13 02:34:14 +01:00
// vector<UnitParticleSystemType*> queuedUnitParticleSystemTypes;
// for(unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); ++i) {
// UnitParticleSystemType *upst= queuedUnitParticleSystemTypes[i];
// upst->saveGame(unitNode);
// }
// UnitParticleSystems damageParticleSystems;
// for(unsigned int i = 0; i < damageParticleSystems.size(); ++i) {
// UnitParticleSystem *ups= damageParticleSystems[i];
// ups->saveGame(unitNode);
// }
2012-03-14 08:23:41 +01:00
if ( unitNode - > hasChild ( " damageParticleSystems " ) = = true ) {
XmlNode * damageParticleSystemsNode = unitNode - > getChild ( " damageParticleSystems " ) ;
vector < XmlNode * > unitParticleSystemNodeList = damageParticleSystemsNode - > getChildList ( " UnitParticleSystem " ) ;
for ( unsigned int i = 0 ; i < unitParticleSystemNodeList . size ( ) ; + + i ) {
XmlNode * node = unitParticleSystemNodeList [ i ] ;
UnitParticleSystem * ups = new UnitParticleSystem ( ) ;
ups - > loadGame ( node ) ;
result - > damageParticleSystems . push_back ( ups ) ;
result - > damageParticleSystemsInUse [ i ] = ups ;
//Renderer::getInstance().manageParticleSystem(result->fire, rsGame);
Renderer : : getInstance ( ) . addToDeferredParticleSystemList ( make_pair ( ups , rsGame ) ) ;
}
}
2012-03-13 02:34:14 +01:00
// std::map<int, UnitParticleSystem *> damageParticleSystemsInUse;
// for(std::map<int, UnitParticleSystem *>::const_iterator iterMap = damageParticleSystemsInUse.begin();
// iterMap != damageParticleSystemsInUse.end(); ++iterMap) {
// XmlNode *damageParticleSystemsInUseNode = unitNode->addChild("damageParticleSystemsInUse");
//
// damageParticleSystemsInUseNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements);
// iterMap->second->saveGame(damageParticleSystemsInUseNode);
// }
2012-03-14 08:23:41 +01:00
// if(unitNode->hasChild("damageParticleSystemsInUse") == true) {
// XmlNode *damageParticleSystemsInUseNode = unitNode->getChild("damageParticleSystemsInUse");
// vector<XmlNode *> damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode->getChildList("damageParticleSystemsInUse");
// for(unsigned int i = 0; i < damageParticleSystemsInUseNode2.size(); ++i) {
// XmlNode *d2Node = damageParticleSystemsInUseNode2[i];
//
// vector<XmlNode *> unitParticleSystemNodeList = damageParticleSystemsInUseNode->getChildList("UnitParticleSystem");
// for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) {
// XmlNode *node = unitParticleSystemNodeList[i];
//
// UnitParticleSystem *ups = new UnitParticleSystem();
// ups->loadGame(node);
// result->unitParticleSystems.push_back(ups);
//
// //Renderer::getInstance().manageParticleSystem(result->fire, rsGame);
// Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame));
// }
//
// }
2012-03-13 02:34:14 +01:00
// vector<ParticleSystem*> fireParticleSystems;
// for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) {
// ParticleSystem *ps= fireParticleSystems[i];
// ps->saveGame(unitNode);
// }
2012-03-14 08:23:41 +01:00
if ( unitNode - > hasChild ( " fireParticleSystems " ) = = true ) {
XmlNode * fireParticleSystemsNode = unitNode - > getChild ( " fireParticleSystems " ) ;
2012-03-30 05:20:33 +02:00
int linkFireIndex = - 1 ;
if ( fireParticleSystemsNode - > hasAttribute ( " fireParticleLink " ) = = true ) {
linkFireIndex = fireParticleSystemsNode - > getAttribute ( " fireParticleLink " ) - > getIntValue ( ) ;
}
2012-03-14 08:23:41 +01:00
vector < XmlNode * > unitParticleSystemNodeList = fireParticleSystemsNode - > getChildList ( " FireParticleSystem " ) ;
for ( unsigned int i = 0 ; i < unitParticleSystemNodeList . size ( ) ; + + i ) {
XmlNode * node = unitParticleSystemNodeList [ i ] ;
FireParticleSystem * ups = new FireParticleSystem ( ) ;
ups - > loadGame ( node ) ;
2012-03-19 22:35:54 +01:00
//ups->setTexture(CoreData::getInstance().getFireTexture());
2012-03-14 08:23:41 +01:00
result - > fireParticleSystems . push_back ( ups ) ;
2012-03-30 05:20:33 +02:00
if ( linkFireIndex > = 0 & & linkFireIndex = = i ) {
result - > fire = ups ;
}
2012-03-14 08:23:41 +01:00
//Renderer::getInstance().manageParticleSystem(result->fire, rsGame);
Renderer : : getInstance ( ) . addToDeferredParticleSystemList ( make_pair ( ups , rsGame ) ) ;
}
}
2012-03-13 02:34:14 +01:00
// vector<UnitParticleSystem*> smokeParticleSystems;
// for(unsigned int i = 0; i < smokeParticleSystems.size(); ++i) {
// UnitParticleSystem *ups= smokeParticleSystems[i];
// ups->saveGame(unitNode);
// }
2012-03-14 08:23:41 +01:00
if ( unitNode - > hasChild ( " smokeParticleSystems " ) = = true ) {
XmlNode * smokeParticleSystemsNode = unitNode - > getChild ( " smokeParticleSystems " ) ;
vector < XmlNode * > unitParticleSystemNodeList = smokeParticleSystemsNode - > getChildList ( " UnitParticleSystem " ) ;
for ( unsigned int i = 0 ; i < unitParticleSystemNodeList . size ( ) ; + + i ) {
XmlNode * node = unitParticleSystemNodeList [ i ] ;
2012-03-19 22:35:54 +01:00
// printf("Load Smoke particle i = %d\n",i);
2012-03-14 08:23:41 +01:00
UnitParticleSystem * ups = new UnitParticleSystem ( ) ;
ups - > loadGame ( node ) ;
2012-03-19 22:35:54 +01:00
//ups->setTexture(CoreData::getInstance().getFireTexture());
2012-03-14 08:23:41 +01:00
result - > smokeParticleSystems . push_back ( ups ) ;
2012-03-19 22:35:54 +01:00
// UnitParticleSystem *ups= new UnitParticleSystem(400);
// ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f));
// ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f));
// ups->setPos(result->getCurrVector());
// ups->setBlendMode(ups->strToBlendMode("black"));
// ups->setOffset(Vec3f(0,2,0));
// ups->setDirection(Vec3f(0,1,-0.2f));
// ups->setRadius(result->type->getSize()/3.f);
// ups->setShape(Shared::Graphics::UnitParticleSystem::sLinear);
// ups->setTexture(CoreData::getInstance().getFireTexture());
// const Game *game = Renderer::getInstance().getGame();
// ups->setSpeed(2.0f / game->getWorld()->getUpdateFps(result->getFactionIndex()));
// ups->setGravity(0.0004f);
// ups->setEmissionRate(1);
// ups->setMaxParticleEnergy(150);
// ups->setSizeNoEnergy(result->type->getSize()*0.6f);
// ups->setParticleSize(result->type->getSize()*0.8f);
// result->smokeParticleSystems.push_back(ups);
2012-03-14 08:23:41 +01:00
//Renderer::getInstance().manageParticleSystem(result->fire, rsGame);
Renderer : : getInstance ( ) . addToDeferredParticleSystemList ( make_pair ( ups , rsGame ) ) ;
2012-03-19 22:35:54 +01:00
//printf("Loading smoke particles:\n[%s]\n",ups->toString().c_str());
2012-03-14 08:23:41 +01:00
}
}
2012-03-13 02:34:14 +01:00
// CardinalDir modelFacing;
// unitNode->addAttribute("modelFacing",intToStr(modelFacing), mapTagReplacements);
// std::string lastSynchDataString;
// unitNode->addAttribute("lastSynchDataString",lastSynchDataString, mapTagReplacements);
// std::string lastFile;
// unitNode->addAttribute("lastFile",lastFile, mapTagReplacements);
// int lastLine;
// unitNode->addAttribute("lastLine",intToStr(lastLine), mapTagReplacements);
// std::string lastSource;
// unitNode->addAttribute("lastSource",lastSource, mapTagReplacements);
// int lastRenderFrame;
result - > lastRenderFrame = unitNode - > getAttribute ( " lastRenderFrame " ) - > getIntValue ( ) ;
// bool visible;
2012-04-16 22:15:57 +02:00
result - > visible = unitNode - > getAttribute ( " visible " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// int retryCurrCommandCount;
result - > retryCurrCommandCount = unitNode - > getAttribute ( " retryCurrCommandCount " ) - > getIntValue ( ) ;
// Vec3f screenPos;
result - > screenPos = Vec3f : : strToVec3 ( unitNode - > getAttribute ( " screenPos " ) - > getValue ( ) ) ;
// string currentUnitTitle;
result - > currentUnitTitle = unitNode - > getAttribute ( " currentUnitTitle " ) - > getValue ( ) ;
//
// bool inBailOutAttempt;
2012-04-16 22:15:57 +02:00
result - > inBailOutAttempt = unitNode - > getAttribute ( " inBailOutAttempt " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// //std::vector<std::pair<Vec2i,Chrono> > badHarvestPosList;
// std::map<Vec2i,int> badHarvestPosList;
// for(std::map<Vec2i,int>::const_iterator iterMap = badHarvestPosList.begin();
// iterMap != badHarvestPosList.end(); ++iterMap) {
// XmlNode *badHarvestPosListNode = unitNode->addChild("badHarvestPosList");
//
// badHarvestPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements);
// badHarvestPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements);
// }
// //time_t lastBadHarvestListPurge;
// std::pair<Vec2i,int> lastHarvestResourceTarget;
const XmlNode * lastHarvestResourceTargetNode = unitNode - > getChild ( " lastHarvestResourceTarget " ) ;
// lastHarvestResourceTargetNode->addAttribute("key",lastHarvestResourceTarget.first.getString(), mapTagReplacements);
// lastHarvestResourceTargetNode->addAttribute("value",intToStr(lastHarvestResourceTarget.second), mapTagReplacements);
result - > lastHarvestResourceTarget =
make_pair ( Vec2i : : strToVec2 ( lastHarvestResourceTargetNode - > getAttribute ( " key " ) - > getValue ( ) ) ,
lastHarvestResourceTargetNode - > getAttribute ( " value " ) - > getIntValue ( ) ) ;
// //std::pair<Vec2i,std::vector<Vec2i> > currentTargetPathTaken;
// static Game *game;
//
// bool ignoreCheckCommand;
2012-04-16 22:15:57 +02:00
result - > ignoreCheckCommand = unitNode - > getAttribute ( " ignoreCheckCommand " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// uint32 lastStuckFrame;
result - > lastStuckFrame = unitNode - > getAttribute ( " lastStuckFrame " ) - > getIntValue ( ) ;
// Vec2i lastStuckPos;
result - > lastStuckPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " lastStuckPos " ) - > getValue ( ) ) ;
// uint32 lastPathfindFailedFrame;
result - > lastPathfindFailedFrame = unitNode - > getAttribute ( " lastPathfindFailedFrame " ) - > getIntValue ( ) ;
// Vec2i lastPathfindFailedPos;
result - > lastPathfindFailedPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " lastPathfindFailedPos " ) - > getValue ( ) ) ;
// bool usePathfinderExtendedMaxNodes;
2012-04-16 22:15:57 +02:00
result - > usePathfinderExtendedMaxNodes = unitNode - > getAttribute ( " usePathfinderExtendedMaxNodes " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// int maxQueuedCommandDisplayCount;
result - > maxQueuedCommandDisplayCount = unitNode - > getAttribute ( " maxQueuedCommandDisplayCount " ) - > getIntValue ( ) ;
// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
// currentAttackBoostOriginatorEffect.saveGame(unitNode);
// std::vector<UnitAttackBoostEffect *> currentAttackBoostEffects;
// for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
// UnitAttackBoostEffect *uabe= currentAttackBoostEffects[i];
// uabe->saveGame(unitNode);
// }
// Mutex *mutexCommands;
//
// //static Mutex mutexDeletedUnits;
// //static std::map<void *,bool> deletedUnits;
//
// bool changedActiveCommand;
2012-04-16 22:15:57 +02:00
result - > changedActiveCommand = unitNode - > getAttribute ( " changedActiveCommand " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 02:34:14 +01:00
// int lastAttackerUnitId;
result - > lastAttackerUnitId = unitNode - > getAttribute ( " lastAttackerUnitId " ) - > getIntValue ( ) ;
// int lastAttackedUnitId;
result - > lastAttackedUnitId = unitNode - > getAttribute ( " lastAttackedUnitId " ) - > getIntValue ( ) ;
// CauseOfDeathType causeOfDeath;
result - > causeOfDeath = static_cast < CauseOfDeathType > ( unitNode - > getAttribute ( " causeOfDeath " ) - > getIntValue ( ) ) ;
2012-04-29 06:45:51 +02:00
result - > pathfindFailedConsecutiveFrameCount = unitNode - > getAttribute ( " pathfindFailedConsecutiveFrameCount " ) - > getIntValue ( ) ;
2012-03-14 00:51:39 +01:00
if ( result - > alive ) {
world - > getMapPtr ( ) - > putUnitCells ( result , newUnitPos ) ;
//result->born();
}
2012-03-17 23:08:04 +01:00
result - > meetingPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " meetingPos " ) - > getValue ( ) ) ;
2012-05-04 16:57:59 +02:00
if ( unitNode - > hasAttribute ( " currentPathFinderDesiredFinalPos " ) ) {
result - > currentPathFinderDesiredFinalPos = Vec2i : : strToVec2 ( unitNode - > getAttribute ( " currentPathFinderDesiredFinalPos " ) - > getValue ( ) ) ;
}
2012-05-12 03:06:55 +02:00
if ( unitNode - > hasAttribute ( " random " ) ) {
result - > random . setLastNumber ( unitNode - > getAttribute ( " random " ) - > getIntValue ( ) ) ;
}
if ( unitNode - > hasAttribute ( " pathFindRefreshCellCount " ) ) {
result - > pathFindRefreshCellCount = unitNode - > getAttribute ( " pathFindRefreshCellCount " ) - > getIntValue ( ) ;
}
2013-01-04 19:00:51 +01:00
result - > calculateFogOfWarRadius ( ) ;
2012-03-13 00:08:22 +01:00
return result ;
}
2010-03-12 08:42:55 +01:00
} } //end namespace