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
// ==============================================================
# include "faction.h"
# 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 {
2010-08-25 09:29:35 +02:00
const int UnitPathBasic : : maxBlockCount = GameConstants : : updateFps / 2 ;
2010-07-21 20:21:40 +02:00
UnitPathBasic : : UnitPathBasic ( ) {
this - > blockCount = 0 ;
this - > pathQueue . clear ( ) ;
}
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 ( ) ;
blockCount = 0 ;
}
void UnitPathBasic : : incBlockCount ( ) {
pathQueue . clear ( ) ;
blockCount + + ;
}
2010-09-07 23:01:22 +02:00
void UnitPathBasic : : add ( const Vec2i & path ) {
2010-07-21 20:21:40 +02:00
pathQueue . push_back ( path ) ;
}
Vec2i UnitPathBasic : : pop ( ) {
Vec2i p = pathQueue . front ( ) ;
pathQueue . erase ( pathQueue . begin ( ) ) ;
return p ;
}
std : : string UnitPathBasic : : toString ( ) const {
std : : string result = " " ;
result = " unit path blockCount = " + intToStr ( blockCount ) + " pathQueue size = " + intToStr ( pathQueue . size ( ) ) ;
for ( int idx = 0 ; idx < pathQueue . size ( ) ; idx + + ) {
result + = " index = " + intToStr ( idx ) + " " + pathQueue [ idx ] . getString ( ) ;
}
return result ;
}
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 {
std : : string result = " " ;
2010-07-11 20:31:02 +02:00
result = " unit path blockCount = " + intToStr ( blockCount ) + " pathQueue size = " + intToStr ( size ( ) ) ;
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 ;
}
void UnitReference : : operator = ( const Unit * unit ) {
if ( unit = = NULL ) {
id = - 1 ;
faction = NULL ;
}
else {
id = unit - > getId ( ) ;
faction = unit - > getFaction ( ) ;
}
}
Unit * UnitReference : : getUnit ( ) const {
2010-06-02 10:03:56 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
2010-03-12 08:42:55 +01:00
if ( faction ! = NULL ) {
2010-06-02 10:03:56 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
2010-03-12 08:42:55 +01:00
return faction - > findUnit ( id ) ;
}
2010-06-02 10:03:56 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
2010-03-12 08:42:55 +01:00
return NULL ;
}
// =====================================================
// 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 float Unit : : highlightTime = 0.5f ;
const int Unit : : invalidId = - 1 ;
2010-04-18 09:35:48 +02:00
set < int > Unit : : livingUnits ;
set < Unit * > Unit : : livingUnitsp ;
2010-03-12 08:42:55 +01:00
// ============================ Constructor & destructor =============================
2010-09-09 03:44:25 +02:00
Game * Unit : : game = NULL ;
2010-07-21 20:21:40 +02:00
Unit : : Unit ( int id , UnitPathInterface * unitpath , const Vec2i & pos , const UnitType * type , Faction * faction , Map * map , CardinalDir placeFacing ) : id ( id ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-01 11:27:08 +02:00
2010-03-25 13:15:10 +01:00
modelFacing = CardinalDir : : NORTH ;
2010-03-12 08:42:55 +01:00
2010-04-24 13:15:15 +02:00
RandomGen random ;
2010-03-12 08:42:55 +01:00
2010-07-21 20:21:40 +02:00
this - > unitPath = unitpath ;
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 ) ;
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 ( ) ;
2010-03-12 08:42:55 +01:00
showUnitParticles = config . getBool ( " UnitParticles " ) ;
lastPos = pos ;
progress = 0 ;
lastAnimProgress = 0 ;
animProgress = 0 ;
progress2 = 0 ;
kills = 0 ;
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
2010-09-06 19:52:33 +02:00
this - > currSkill = getType ( ) - > getFirstStOfClass ( scStop ) ;
2010-11-07 03:37:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Unit ID = %d [%s], this->currSkill = %s\n",__FILE__,__FUNCTION__,__LINE__,this->getId(),this->getFullName().c_str(), (this->currSkill == NULL ? "" : this->currSkill->toString().c_str()));
2010-03-12 08:42:55 +01:00
2010-11-07 03:37:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-01 11:27:08 +02:00
2010-03-20 00:26:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
2010-04-18 09:35:48 +02:00
livingUnits . insert ( id ) ;
livingUnitsp . insert ( 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 ) ;
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
}
2010-11-07 03:37:00 +01:00
Unit : : ~ Unit ( ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] delete unitid = %d\n",__FILE__,__FUNCTION__,__LINE__,id);
2010-06-02 10:03:56 +02:00
2010-10-17 10:50:27 +02:00
badHarvestPosList . clear ( ) ;
2010-04-18 09:35:48 +02:00
//Just to be sure, should already be removed
if ( livingUnits . erase ( id ) ) {
2010-06-02 10:03:56 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-04-18 09:35:48 +02:00
//Only an error if not called at end
}
//Just to be sure, should already be removed
if ( livingUnitsp . erase ( this ) ) {
2010-06-02 10:03:56 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-12-24 09:43:09 +01:00
2010-04-18 09:35:48 +02:00
}
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
//remove commands
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-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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
2010-09-06 19:52:33 +02:00
while ( unitParticleSystems . empty ( ) = = false ) {
2010-03-25 13:15:10 +01:00
unitParticleSystems . back ( ) - > fade ( ) ;
unitParticleSystems . pop_back ( ) ;
}
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
stopDamageParticles ( ) ;
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-07-21 20:21:40 +02:00
delete this - > unitPath ;
this - > unitPath = NULL ;
2010-09-10 17:51:16 +02:00
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-09-10 17:51:16 +02:00
Renderer & renderer = Renderer : : getInstance ( ) ;
2010-09-10 21:44:00 +02:00
renderer . removeUnitFromQuadCache ( this ) ;
2010-09-10 17:51:16 +02:00
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-25 13:15:10 +01:00
}
2010-03-12 08:42:55 +01:00
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 ======================================
int Unit : : getFactionIndex ( ) const {
return faction - > getIndex ( ) ;
}
int Unit : : getTeam ( ) const {
return faction - > getTeam ( ) ;
}
2010-06-14 08:38:24 +02:00
Vec2i Unit : : getCenteredPos ( ) const {
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ;
}
float Unit : : getVerticalRotation ( ) const {
/*if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){
float heightDiff = map - > getCell ( pos ) - > getHeight ( ) - map - > getCell ( targetPos ) - > getHeight ( ) ;
float dist = pos . dist ( targetPos ) ;
2010-04-24 05:57:38 +02:00
return radToDeg ( streflop : : atan2 ( heightDiff , dist ) ) ;
2010-03-12 08:42:55 +01:00
} */
return 0.f ;
}
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 ;
}
2010-06-14 08:38:24 +02:00
float Unit : : getHpRatio ( ) const {
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
str + = ( level - > getName ( ) + " " ) ;
}
if ( type = = NULL ) {
throw runtime_error ( " type == NULL in Unit::getFullName() ! " ) ;
}
str + = type - > getName ( ) ;
return str ;
}
// ====================================== is ======================================
bool Unit : : isOperative ( ) const {
return isAlive ( ) & & isBuilt ( ) ;
}
bool Unit : : isBeingBuilt ( ) const {
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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
}
bool Unit : : isPutrefacting ( ) const {
return deadCount ! = 0 ;
}
2010-06-14 08:38:24 +02:00
bool Unit : : isAlly ( const Unit * unit ) const {
if ( unit = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
if ( this - > currSkill = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: this->currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-11-07 03:37:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Unit ID = %d [%s], this->currSkill = %s\n currSkill = %s\n",__FILE__,__FUNCTION__,__LINE__,this->getId(), this->getFullName().c_str(), this->currSkill->toString().c_str(),currSkill->toString().c_str());
2010-10-30 10:54:00 +02:00
2010-09-06 19:52:33 +02:00
if ( currSkill - > getClass ( ) ! = this - > currSkill - > getClass ( ) ) {
2010-03-12 08:42:55 +01:00
animProgress = 0 ;
lastAnimProgress = 0 ;
2010-09-06 19:52:33 +02:00
while ( unitParticleSystems . empty ( ) = = false ) {
2010-03-12 08:42:55 +01:00
unitParticleSystems . back ( ) - > fade ( ) ;
unitParticleSystems . pop_back ( ) ;
}
}
2010-09-06 19:52:33 +02:00
if ( showUnitParticles & & ( currSkill - > unitParticleSystemTypes . empty ( ) = = false ) & &
( unitParticleSystems . empty ( ) = = true ) ) {
for ( UnitParticleSystemTypes : : const_iterator it = currSkill - > unitParticleSystemTypes . begin ( ) ; it ! = currSkill - > unitParticleSystemTypes . end ( ) ; + + it ) {
UnitParticleSystem * ups = new UnitParticleSystem ( 200 ) ;
2010-03-12 08:42:55 +01:00
( * it ) - > setValues ( ups ) ;
ups - > setPos ( getCurrVector ( ) ) ;
2010-11-09 10:06:52 +01:00
ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
2010-03-12 08:42:55 +01:00
unitParticleSystems . push_back ( ups ) ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
}
progress2 = 0 ;
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ;
}
void Unit : : setPos ( const Vec2i & pos ) {
this - > lastPos = this - > pos ;
this - > pos = pos ;
this - > meetingPos = pos - Vec2i ( 1 ) ;
2010-04-27 05:36:36 +02:00
2010-09-09 03:44:25 +02:00
// Attempt to improve performance
this - > exploreCells ( ) ;
2010-12-02 00:38:03 +01:00
logSynchData ( __FILE__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
}
void Unit : : setTargetPos ( const Vec2i & targetPos ) {
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
2010-04-24 05:57:38 +02:00
targetRotation = radToDeg ( streflop : : atan2 ( relPosf . x , 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 ;
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 ;
2010-09-06 19:52:33 +02:00
for ( UnitParticleSystems : : iterator it = unitParticleSystems . begin ( ) ; it ! = unitParticleSystems . end ( ) ; + + it ) {
2010-03-12 08:42:55 +01:00
( * it ) - > setVisible ( visible ) ;
}
2010-09-06 19:52:33 +02:00
for ( UnitParticleSystems : : iterator it = damageParticleSystems . begin ( ) ; it ! = damageParticleSystems . end ( ) ; + + it ) {
2010-03-12 08:42:55 +01:00
( * it ) - > setVisible ( visible ) ;
}
}
// =============================== Render related ==================================
2011-01-18 08:52:06 +01:00
Model * Unit : : getCurrentModelPtr ( ) const {
if ( currSkill = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
return currSkill - > getAnimation ( ) ;
}
2010-03-12 08:42:55 +01:00
const Model * Unit : : getCurrentModel ( ) const {
2010-06-14 08:38:24 +02:00
if ( currSkill = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
return currSkill - > getAnimation ( ) ;
}
Vec3f Unit : : getCurrVector ( ) const {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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
}
//return current command, assert that there is always one command
2011-01-08 22:53:05 +01:00
Command * Unit : : getCurrCommand ( ) const {
2010-10-20 09:28:27 +02:00
if ( commands . empty ( ) = = false ) {
return commands . front ( ) ;
}
return NULL ;
2010-03-12 08:42:55 +01:00
}
2010-08-28 03:46:26 +02:00
void Unit : : replaceCurrCommand ( Command * cmd ) {
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)
2010-05-31 08:11:31 +02:00
CommandResult Unit : : giveCommand ( Command * command , bool tryQueue ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
2010-03-12 08:42:55 +01:00
2010-06-08 09:40:32 +02:00
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-11-11 09:02:50 +01:00
Chrono chrono ;
chrono . start ( ) ;
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
2010-11-11 09:02:50 +01:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-01-08 22:53:05 +01:00
if ( command - > getCommandType ( ) - > isQueuable ( tryQueue ) ) {
2010-11-11 09:02:50 +01:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-01-08 22:53:05 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Command is Queable \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-09 10:06:52 +01:00
2010-05-18 23:18:51 +02:00
//Delete all lower-prioirty commands
for ( list < Command * > : : iterator i = commands . begin ( ) ; i ! = commands . end ( ) ; ) {
2010-12-23 11:44:11 +01:00
if ( ( * i ) - > getPriority ( ) < command_priority ) {
2011-01-08 22:53:05 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Deleting lower priority command [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( * i ) - > toString ( ) . c_str ( ) ) ;
2010-12-23 11:44:11 +01:00
deleteQueuedCommand ( * i ) ;
2010-05-18 23:18:51 +02:00
i = commands . erase ( i ) ;
2010-05-31 08:11:31 +02:00
}
else {
2010-05-18 23:18:51 +02:00
+ + i ;
}
}
2010-11-09 10:06:52 +01:00
2010-11-11 09:02:50 +01:00
if ( 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
//cancel current command if it is not queuable
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-18 22:26:40 +01:00
2011-01-08 22:53:05 +01:00
if ( commands . empty ( ) = = false & &
commands . back ( ) - > getCommandType ( ) - > isQueueAppendable ( ) = = false ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2011-01-08 22:53:05 +01:00
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
if ( 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-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2011-01-08 22:53:05 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] Clear commands because current is NOT queable. \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
clearCommands ( ) ;
2010-11-11 09:02:50 +01:00
if ( 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-03-20 00:26:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A\n",__FILE__,__FUNCTION__);
2010-03-12 08:42:55 +01:00
2010-11-11 09:02:50 +01:00
if ( 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
//check command
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
CommandResult result = checkCommand ( command ) ;
2011-01-08 22:53:05 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugUnitCommands , " In [%s::%s Line: %d] checkCommand returned: [%d] \n " , __FILE__ , __FUNCTION__ , __LINE__ , result ) ;
2010-11-09 10:06:52 +01:00
2010-11-11 09:02:50 +01:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-05-31 08:11:31 +02:00
if ( result = = crSuccess ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
applyCommand ( command ) ;
}
2010-03-20 00:26:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] B\n",__FILE__,__FUNCTION__);
2010-03-12 08:42:55 +01:00
2010-11-11 09:02:50 +01:00
if ( 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
//push back command
2010-05-31 08:11:31 +02:00
if ( result = = crSuccess ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
commands . push_back ( command ) ;
}
2010-05-31 08:11:31 +02:00
else {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-12 08:42:55 +01:00
delete command ;
}
2010-11-11 09:02:50 +01:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result);
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 ( ) {
2010-03-12 08:42:55 +01:00
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-01-29 13:42:18 +01:00
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
delete commands . front ( ) ;
commands . erase ( commands . begin ( ) ) ;
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 ) {
2010-04-18 09:35:48 +02:00
if ( commands . front ( ) - > getUnit ( ) ! = NULL & & livingUnitsp . find ( commands . front ( ) - > getUnit ( ) ) = = livingUnitsp . end ( ) ) {
delete commands . front ( ) ;
commands . erase ( commands . begin ( ) ) ;
} else {
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 ( ) {
2010-03-12 08:42:55 +01:00
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-01-29 13:42:18 +01:00
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
delete commands . back ( ) ;
commands . pop_back ( ) ;
//clear routes
2010-07-21 20:21:40 +02:00
this - > unitPath - > clear ( ) ;
2010-03-12 08:42:55 +01:00
return crSuccess ;
}
// =================== route stack ===================
void Unit : : create ( bool startingUnit ) {
faction - > addUnit ( this ) ;
map - > putUnitCells ( this , pos ) ;
if ( startingUnit ) {
faction - > applyStaticCosts ( type ) ;
}
}
2010-10-30 10:54:00 +02:00
void Unit : : born ( ) {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-11-07 03:37:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Unit ID = %d [%s], this->currSkill = %s\n",__FILE__,__FUNCTION__,__LINE__,this->getId(),this->getFullName().c_str(), (this->currSkill == NULL ? "" : this->currSkill->toString().c_str()));
2010-10-30 10:54:00 +02:00
2010-03-12 08:42:55 +01:00
faction - > addStore ( type ) ;
faction - > applyStaticProduction ( type ) ;
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-11-07 03:37:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Unit ID = %d [%s], this->currSkill = %s\n",__FILE__,__FUNCTION__,__LINE__,this->getId(),this->getFullName().c_str(), (this->currSkill == NULL ? "" : this->currSkill->toString().c_str()));
2010-03-12 08:42:55 +01:00
//no longer needs static resources
2010-10-30 10:54:00 +02:00
if ( isBeingBuilt ( ) ) {
2010-03-12 08:42:55 +01:00
faction - > deApplyStaticConsumption ( type ) ;
}
2010-10-30 10:54:00 +02:00
else {
2010-03-12 08:42:55 +01:00
faction - > deApplyStaticCosts ( type ) ;
}
//do the cleaning
map - > clearUnitCells ( this , pos ) ;
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 ) ;
//clear commands
clearCommands ( ) ;
}
2010-04-20 04:19:37 +02:00
void Unit : : undertake ( ) {
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-18 09:35:48 +02:00
livingUnits . erase ( id ) ;
livingUnitsp . erase ( 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 ;
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( pos ) ) ;
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ;
}
2010-09-07 07:25:40 +02:00
bool Unit : : update ( ) {
2010-03-12 08:42:55 +01:00
assert ( progress < = 1.f ) ;
//highlight
2010-08-24 03:21:34 +02:00
if ( highlight > 0.f ) {
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
highlight - = 1.f / ( 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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
//speed
int speed = currSkill - > getTotalSpeed ( & totalUpgrade ) ;
//speed modifier
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
Vec2i dest = pos - lastPos ;
2010-10-30 10:54:00 +02:00
if ( abs ( dest . x ) + abs ( dest . y ) = = 2 ) {
2010-03-12 08:42:55 +01:00
diagonalFactor = 0.71f ;
}
//if movig 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 ) ;
}
//update progresses
lastAnimProgress = animProgress ;
2010-08-24 03:21:34 +02:00
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
progress + = ( speed * diagonalFactor * heightFactor ) / ( speedDivider * game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
animProgress + = ( currSkill - > getAnimSpeed ( ) * heightFactor ) / ( speedDivider * game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
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 ;
if ( progress < 1.f / rotFactor ) {
if ( type - > getFirstStOfClass ( scMove ) ) {
2010-04-27 22:38:34 +02:00
if ( abs ( ( int ) ( lastRotation - targetRotation ) ) < 180 )
2010-03-12 08:42:55 +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-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 ) {
2010-03-12 08:42:55 +01:00
( * it ) - > setPos ( getCurrVector ( ) ) ;
( * it ) - > setRotation ( getRotation ( ) ) ;
}
2010-09-06 19:52:33 +02:00
for ( UnitParticleSystems : : iterator it = damageParticleSystems . begin ( ) ; it ! = damageParticleSystems . end ( ) ; + + it ) {
2010-03-12 08:42:55 +01:00
( * it ) - > setPos ( getCurrVector ( ) ) ;
( * it ) - > setRotation ( getRotation ( ) ) ;
}
//checks
2010-09-06 19:52:33 +02:00
if ( animProgress > 1.f ) {
2010-03-12 08:42:55 +01:00
animProgress = currSkill - > getClass ( ) = = scDie ? 1.f : 0.f ;
}
2010-03-18 22:26:40 +01:00
bool return_value = false ;
2010-03-12 08:42:55 +01:00
//checks
2010-09-06 19:52:33 +02: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 ) {
2010-03-12 08:42:55 +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 + + ;
2010-09-06 19:52:33 +02: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
}
}
}
2010-03-18 22:26:40 +01:00
return return_value ;
2010-03-12 08:42:55 +01:00
}
2010-06-14 08:38:24 +02:00
void Unit : : tick ( ) {
if ( isAlive ( ) ) {
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
//regenerate hp
2010-12-28 03:17:44 +01:00
if ( type - > getHpRegeneration ( ) > = 0 ) {
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
2011-01-15 05:13:15 +01:00
hp + = type - > getHpRegeneration ( ) ;
2011-01-15 00:51:15 +01:00
if ( hp > type - > getTotalMaxHp ( & totalUpgrade ) ) {
hp = type - > getTotalMaxHp ( & totalUpgrade ) ;
2010-12-28 03:17:44 +01:00
}
2011-01-15 00:51:15 +01:00
addItemToVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
}
2010-12-28 03:17:44 +01:00
// If we have negative regeneration then check if the unit should die
else {
bool decHpResult = decHp ( - type - > getHpRegeneration ( ) ) ;
if ( decHpResult ) {
Unit : : game - > getWorld ( ) - > getStats ( ) - > die ( getFactionIndex ( ) ) ;
game - > getScriptManager ( ) - > onUnitDied ( this ) ;
}
StaticSound * sound = this - > getType ( ) - > getFirstStOfClass ( scDie ) - > getSound ( ) ;
if ( sound ! = NULL & & this - > getFactionIndex ( ) = = Unit : : game - > getWorld ( ) - > getThisFactionIndex ( ) ) {
SoundRenderer : : getInstance ( ) . playFx ( sound ) ;
}
}
2010-03-12 08:42:55 +01:00
//stop DamageParticles
2010-12-28 03:17:44 +01:00
if ( hp > type - > getTotalMaxHp ( & totalUpgrade ) / 2 ) {
2010-03-12 08:42:55 +01:00
stopDamageParticles ( ) ;
}
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
2010-12-28 03:17:44 +01:00
ep + = type - > getEpRegeneration ( ) ;
2011-01-15 05:13:15 +01:00
if ( ep > type - > getTotalMaxEp ( & totalUpgrade ) ) {
ep = type - > 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
}
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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
bool Unit : : computeHp ( ) {
if ( currSkill = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
if ( ! isBeingBuilt ( ) ) {
//cost hp
if ( currSkill - > getHpCost ( ) > 0 ) {
bool decHpResult = decHp ( currSkill - > getHpCost ( ) ) ;
if ( decHpResult ) {
Unit : : game - > getWorld ( ) - > getStats ( ) - > die ( getFactionIndex ( ) ) ;
game - > getScriptManager ( ) - > onUnitDied ( this ) ;
}
}
// If we have negative costs then add life
else {
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = - currSkill - > getHpCost ( ) ;
if ( hp > type - > getTotalMaxHp ( & totalUpgrade ) ) {
hp = type - > getTotalMaxHp ( & totalUpgrade ) ;
}
addItemToVault ( & this - > hp , this - > hp ) ;
}
}
return true ;
}
2010-03-12 08:42:55 +01:00
bool Unit : : repair ( ) {
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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
//stop DamageParticles
2011-01-15 00:51:15 +01:00
if ( hp > type - > getTotalMaxHp ( & totalUpgrade ) / 2 ) {
2010-03-12 08:42:55 +01:00
stopDamageParticles ( ) ;
}
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 ) ;
2010-06-14 08:38:24 +02:00
if ( type = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
//startDamageParticles
2010-12-28 03:17:44 +01:00
if ( hp < type - > getMaxHp ( ) / 2 ) {
2010-03-12 08:42:55 +01:00
startDamageParticles ( ) ;
}
//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 ) ;
2010-03-12 08:42:55 +01:00
stopDamageParticles ( ) ;
return true ;
}
return false ;
}
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
2010-08-22 23:09:35 +02:00
str + = " \n " + lang . get ( " Hp " ) + " : " + intToStr ( hp ) + " / " + intToStr ( type - > getTotalMaxHp ( & totalUpgrade ) ) ;
2010-03-12 08:42:55 +01:00
if ( type - > getHpRegeneration ( ) ! = 0 ) {
str + = " ( " + lang . get ( " Regeneration " ) + " : " + intToStr ( type - > getHpRegeneration ( ) ) + " ) " ;
}
//ep
if ( getType ( ) - > getMaxEp ( ) ! = 0 ) {
str + = " \n " + lang . get ( " Ep " ) + " : " + intToStr ( ep ) + " / " + intToStr ( type - > getTotalMaxEp ( & totalUpgrade ) ) ;
}
if ( type - > getEpRegeneration ( ) ! = 0 ) {
str + = " ( " + lang . get ( " Regeneration " ) + " : " + intToStr ( type - > getEpRegeneration ( ) ) + " ) " ;
}
//armor
str + = " \n " + lang . get ( " Armor " ) + " : " + intToStr ( getType ( ) - > getArmor ( ) ) ;
if ( totalUpgrade . getArmor ( ) ! = 0 ) {
str + = " + " + intToStr ( totalUpgrade . getArmor ( ) ) ;
}
str + = " ( " + getType ( ) - > getArmorType ( ) - > getName ( ) + " ) " ;
//sight
str + = " \n " + lang . get ( " Sight " ) + " : " + intToStr ( getType ( ) - > getSight ( ) ) ;
if ( totalUpgrade . getSight ( ) ! = 0 ) {
str + = " + " + intToStr ( totalUpgrade . getSight ( ) ) ;
}
//kills
const Level * nextLevel = getNextLevel ( ) ;
if ( kills > 0 | | nextLevel ! = NULL ) {
str + = " \n " + lang . get ( " Kills " ) + " : " + intToStr ( kills ) ;
if ( nextLevel ! = NULL ) {
str + = " ( " + nextLevel - > getName ( ) + " : " + intToStr ( nextLevel - > getKills ( ) ) + " ) " ;
}
}
//str+= "\nskl: "+scToStr(currSkill->getClass());
//load
if ( loadCount ! = 0 ) {
str + = " \n " + lang . get ( " Load " ) + " : " + intToStr ( loadCount ) + " " + loadType - > getName ( ) ;
}
//consumable production
for ( int i = 0 ; i < getType ( ) - > getCostCount ( ) ; + + i ) {
const Resource * r = getType ( ) - > getCost ( i ) ;
if ( r - > getType ( ) - > getClass ( ) = = rcConsumable ) {
str + = " \n " ;
str + = r - > getAmount ( ) < 0 ? lang . get ( " Produce " ) + " : " : lang . get ( " Consume " ) + " : " ;
str + = intToStr ( abs ( r - > getAmount ( ) ) ) + " " + r - > getType ( ) - > getName ( ) ;
}
}
//command info
2011-01-08 22:53:05 +01:00
if ( commands . empty ( ) = = false ) {
2010-03-12 08:42:55 +01:00
str + = " \n " + commands . front ( ) - > getCommandType ( ) - > getName ( ) ;
if ( commands . size ( ) > 1 ) {
str + = " \n " + lang . get ( " OrdersOnQueue " ) + " : " + intToStr ( commands . size ( ) ) ;
}
}
else {
//can store
if ( getType ( ) - > getStoredResourceCount ( ) > 0 ) {
for ( int i = 0 ; i < getType ( ) - > getStoredResourceCount ( ) ; + + i ) {
const Resource * r = getType ( ) - > getStoredResource ( i ) ;
str + = " \n " + lang . get ( " Store " ) + " : " ;
str + = intToStr ( r - > getAmount ( ) ) + " " + r - > getType ( ) - > getName ( ) ;
}
}
}
return str ;
}
void Unit : : applyUpgrade ( const UpgradeType * upgradeType ) {
2010-06-14 08:38:24 +02:00
if ( upgradeType = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: upgradeType == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
if ( upgradeType - > isAffected ( type ) ) {
totalUpgrade . sum ( upgradeType ) ;
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = upgradeType - > getMaxHp ( ) ;
addItemToVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
}
}
void Unit : : computeTotalUpgrade ( ) {
faction - > getUpgradeManager ( ) - > computeTotalUpgrade ( this , & totalUpgrade ) ;
}
void Unit : : incKills ( ) {
+ + kills ;
const Level * nextLevel = getNextLevel ( ) ;
if ( nextLevel ! = NULL & & kills > = nextLevel - > getKills ( ) ) {
level = nextLevel ;
int maxHp = totalUpgrade . getMaxHp ( ) ;
totalUpgrade . incLevel ( type ) ;
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = totalUpgrade . getMaxHp ( ) - maxHp ;
addItemToVault ( & this - > hp , this - > hp ) ;
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: mct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
const UnitType * morphUnitType = mct - > getMorphUnit ( ) ;
2010-06-14 08:38:24 +02:00
if ( morphUnitType = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: morphUnitType == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
Field morphUnitField = fLand ;
if ( morphUnitType - > getField ( fAir ) ) morphUnitField = fAir ;
if ( morphUnitType - > getField ( fLand ) ) morphUnitField = fLand ;
2011-02-06 19:33:49 +01:00
if ( map - > isFreeCellsOrHasUnit ( pos , morphUnitType - > getSize ( ) , morphUnitField , this , morphUnitType ) ) {
2010-03-12 08:42:55 +01:00
map - > clearUnitCells ( this , pos ) ;
faction - > deApplyStaticCosts ( type ) ;
2011-01-15 00:51:15 +01:00
checkItemInVault ( & this - > hp , this - > hp ) ;
hp + = morphUnitType - > getMaxHp ( ) - type - > getMaxHp ( ) ;
addItemToVault ( & this - > hp , this - > hp ) ;
2010-03-12 08:42:55 +01:00
type = morphUnitType ;
level = NULL ;
currField = morphUnitField ;
computeTotalUpgrade ( ) ;
map - > putUnitCells ( this , pos ) ;
faction - > applyDiscount ( morphUnitType , mct - > getDiscount ( ) ) ;
2011-01-07 06:15:39 +01:00
faction - > addStore ( type ) ;
2010-09-25 04:23:47 +02:00
faction - > applyStaticProduction ( morphUnitType ) ;
2010-03-12 08:42:55 +01:00
return true ;
}
else {
return false ;
}
}
// ==================== PRIVATE ====================
float Unit : : computeHeight ( const Vec2i & pos ) const {
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
2010-04-24 05:57:38 +02:00
targetRotation = radToDeg ( streflop : : atan2 ( relPosf . x , 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 ( ) {
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 ( ) ) ;
delete commands . back ( ) ;
commands . pop_back ( ) ;
}
}
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 ;
}
2010-09-01 06:42:10 +02:00
CommandResult Unit : : checkCommand ( Command * command ) const {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-12 20:27:39 +02:00
if ( command = = NULL ) {
2010-06-14 08:38:24 +02:00
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2010-06-12 20:27:39 +02:00
throw runtime_error ( szBuf ) ;
}
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 ) ) {
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 ( ) ) ) ;
2010-03-12 08:42:55 +01:00
return crFailUndefined ;
}
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-12 20:27:39 +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-01-29 13:42:18 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
return crFailUndefined ;
}
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-12 20:27:39 +02:00
2010-03-12 08:42:55 +01:00
//check produced
2010-06-12 20:27:39 +02:00
if ( command - > getCommandType ( ) = = NULL ) {
2010-06-14 08:38:24 +02:00
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2010-06-12 20:27:39 +02:00
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
const ProducibleType * produced = command - > getCommandType ( ) - > getProduced ( ) ;
2010-11-09 10:06:52 +01:00
if ( produced ! = NULL ) {
2011-01-29 13:42:18 +01:00
if ( ignoreCheckCommand = = false & & faction - > reqsOk ( produced ) = = false ) {
2010-03-12 08:42:55 +01:00
return crFailReqs ;
}
2010-11-09 10:06:52 +01:00
2011-01-29 13:42:18 +01:00
if ( ignoreCheckCommand = = false & & faction - > checkCosts ( produced ) = = false ) {
2010-03-12 08:42:55 +01:00
return crFailRes ;
}
}
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-12 20:27:39 +02:00
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 ) {
2010-06-14 08:38:24 +02:00
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: builtUnit == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2010-06-12 20:27:39 +02:00
throw runtime_error ( szBuf ) ;
}
2010-11-09 10:06:52 +01:00
if ( faction - > reqsOk ( builtUnit ) = = false ) {
2010-03-12 08:42:55 +01:00
return crFailReqs ;
}
2010-11-09 10:06:52 +01:00
if ( faction - > checkCosts ( builtUnit ) = = false ) {
2010-03-12 08:42:55 +01:00
return crFailRes ;
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 ) {
2010-06-14 08:38:24 +02:00
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
2010-06-12 20:27:39 +02:00
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
if ( faction - > getUpgradeManager ( ) - > isUpgradingOrUpgraded ( uct - > getProducedUpgrade ( ) ) ) {
2011-01-29 13:42:18 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugLUA , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-12 08:42:55 +01:00
return crFailUndefined ;
}
}
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-12 20:27:39 +02:00
2010-03-12 08:42:55 +01:00
return crSuccess ;
}
void Unit : : applyCommand ( Command * command ) {
2010-06-14 08:38:24 +02:00
if ( command = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
else if ( command - > getCommandType ( ) = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
2010-03-12 08:42:55 +01:00
faction - > applyCosts ( produced ) ;
}
//build command specific
if ( command - > getCommandType ( ) - > getClass ( ) = = ccBuild ) {
faction - > applyCosts ( command - > getUnitType ( ) ) ;
}
//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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
else if ( command - > getCommandType ( ) = = NULL ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
2010-03-12 08:42:55 +01:00
//return cost
const ProducibleType * produced = command - > getCommandType ( ) - > getProduced ( ) ;
if ( produced ! = NULL ) {
faction - > deApplyCosts ( produced ) ;
}
//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 ) {
2010-03-12 08:42:55 +01:00
faction - > deApplyCosts ( command - > getUnitType ( ) ) ;
}
}
//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 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > toString ( ) . c_str ( ) ) ;
throw runtime_error ( szBuf ) ;
}
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 ;
}
2010-09-07 07:25:40 +02:00
void Unit : : stopDamageParticles ( ) {
2010-09-07 19:30:13 +02:00
if ( Renderer : : getInstance ( ) . validateParticleSystemStillExists ( fire , rsGame ) = = false ) {
fire = NULL ;
}
2010-03-12 08:42:55 +01:00
// stop fire
2010-09-06 19:52:33 +02:00
if ( fire ! = NULL ) {
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-14 08:38:24 +02:00
fire - > fade ( ) ;
2010-09-06 19:52:33 +02:00
fire = NULL ;
2011-01-17 17:31:25 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-06-14 08:38:24 +02:00
}
2010-03-12 08:42:55 +01:00
// stop additional particles
2010-09-06 19:52:33 +02:00
while ( damageParticleSystems . empty ( ) = = false ) {
2010-03-12 08:42:55 +01:00
damageParticleSystems . back ( ) - > fade ( ) ;
damageParticleSystems . pop_back ( ) ;
}
}
void Unit : : startDamageParticles ( ) {
//start additional particles
if ( showUnitParticles & & ( ! type - > damageParticleSystemTypes . empty ( ) )
& & ( damageParticleSystems . empty ( ) ) ) {
for ( UnitParticleSystemTypes : : const_iterator it = type - > damageParticleSystemTypes . begin ( ) ; it ! = type - > damageParticleSystemTypes . end ( ) ; + + it ) {
UnitParticleSystem * ups ;
ups = new UnitParticleSystem ( 200 ) ;
( * it ) - > setValues ( ups ) ;
ups - > setPos ( getCurrVector ( ) ) ;
2010-11-09 10:06:52 +01:00
ups - > setFactionColor ( getFaction ( ) - > getTexture ( ) - > getPixmapConst ( ) - > getPixel3f ( 0 , 0 ) ) ;
2010-03-12 08:42:55 +01:00
damageParticleSystems . push_back ( ups ) ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
}
// start fire
2010-09-07 07:25:40 +02:00
if ( type - > getProperty ( UnitType : : pBurnable ) & & fire = = NULL ) {
2010-09-07 19:30:13 +02:00
FireParticleSystem * fps = new FireParticleSystem ( 200 ) ;
2010-08-24 03:21:34 +02:00
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
fps - > setSpeed ( 2.5f / game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
2010-03-12 08:42:55 +01:00
fps - > setPos ( getCurrVector ( ) ) ;
fps - > setRadius ( type - > getSize ( ) / 3.f ) ;
fps - > setTexture ( CoreData : : getInstance ( ) . getFireTexture ( ) ) ;
fps - > setParticleSize ( type - > getSize ( ) / 3.f ) ;
fire = fps ;
2010-09-06 19:52:33 +02:00
fireParticleSystems . push_back ( fps ) ;
2010-03-12 08:42:55 +01:00
Renderer : : getInstance ( ) . manageParticleSystem ( fps , rsGame ) ;
2010-09-06 19:52:33 +02:00
if ( showUnitParticles ) {
2010-03-12 08:42:55 +01: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 ) ;
ups - > setTexture ( CoreData : : getInstance ( ) . getFireTexture ( ) ) ;
2010-08-24 03:21:34 +02:00
const Game * game = Renderer : : getInstance ( ) . getGame ( ) ;
ups - > setSpeed ( 2.0f / game - > getWorld ( ) - > getUpdateFps ( this - > getFactionIndex ( ) ) ) ;
2010-03-12 08:42:55 +01:00
ups - > setGravity ( 0.0004f ) ;
ups - > setEmissionRate ( 1 ) ;
ups - > setMaxParticleEnergy ( 150 ) ;
ups - > setSizeNoEnergy ( type - > getSize ( ) * 0.6f ) ;
ups - > setParticleSize ( type - > getSize ( ) * 0.8f ) ;
damageParticleSystems . push_back ( ups ) ;
Renderer : : getInstance ( ) . manageParticleSystem ( ups , rsGame ) ;
}
}
}
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 ) {
this - > meetingPos = meetingPos ;
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 ) ;
}
2010-04-27 16:10:53 +02:00
int Unit : : getFrameCount ( ) {
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 ) {
throw runtime_error ( " game == NULL " ) ;
}
else if ( game - > getWorld ( ) = = NULL ) {
throw runtime_error ( " game->getWorld() = = NULL " ) ;
}
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 ) {
2010-12-26 02:13:04 +01:00
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf ,
" 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-04-27 05:36:36 +02:00
sprintf ( szBuf ,
2010-11-28 04:46:28 +01:00
" FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, lastRotation [%f], targetRotation [%f], rotation [%f], progress [%f], progress2 [%d] \n Unit Path [%s] \n " ,
2010-04-27 16:10:53 +02:00
getFrameCount ( ) ,
id ,
2010-04-27 05:36:36 +02:00
getFullName ( ) . c_str ( ) ,
2010-11-28 04:46:28 +01:00
faction - > getType ( ) - > getName ( ) . c_str ( ) ,
2010-04-27 05:36:36 +02:00
//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 ,
2010-11-28 04:46:28 +01:00
progress2 ,
( unitPath ! = NULL ? unitPath - > toString ( ) . c_str ( ) : " NULL " ) ) ;
2010-12-26 02:13:04 +01:00
*/
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
}
2010-10-20 00:26:49 +02:00
bool Unit : : isBadHarvestPos ( const Vec2i & value , bool checkPeerUnits ) const {
2010-10-17 10:50:27 +02:00
bool result = false ;
2010-10-24 03:49:25 +02:00
2010-12-01 00:32:39 +01:00
std : : map < Vec2i , int > : : const_iterator iter = badHarvestPosList . find ( value ) ;
2010-10-24 03:49:25 +02:00
if ( iter ! = badHarvestPosList . end ( ) ) {
result = true ;
}
2010-11-09 10:06:52 +01:00
else if ( checkPeerUnits = = true ) {
2010-10-20 00:26:49 +02:00
// Check if any other units of similar type have this position tagged
// as bad?
for ( int i = 0 ; i < this - > getFaction ( ) - > getUnitCount ( ) ; + + i ) {
Unit * peerUnit = this - > getFaction ( ) - > getUnit ( i ) ;
if ( peerUnit ! = NULL & & peerUnit - > getId ( ) ! = this - > getId ( ) & &
peerUnit - > getType ( ) - > getSize ( ) < = this - > getType ( ) - > getSize ( ) ) {
if ( peerUnit - > isBadHarvestPos ( value , false ) = = true ) {
result = true ;
break ;
}
}
}
}
2010-10-17 10:50:27 +02:00
return result ;
}
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 ;
2010-12-01 00:32:39 +01:00
for ( std : : map < Vec2i , int > : : iterator iter = badHarvestPosList . begin ( ) ; iter ! = badHarvestPosList . end ( ) ; iter + + ) {
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
if ( purgeList . size ( ) > 0 ) {
char szBuf [ 4096 ] = " " ;
2010-12-02 00:38:03 +01:00
sprintf ( szBuf , " [cleaning old bad harvest targets] purgeList.size() [%ld] " , purgeList . size ( ) ) ;
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 ) {
printf ( " -----------------------> setLastHarvestResourceTarget() [%d][%d] \n " , getFrameCount ( ) , lastHarvestResourceTarget . second ) ;
2010-10-17 10:50:27 +02:00
addBadHarvestPos ( resourceLocation ) ;
}
}
}
}
2010-10-20 00:26:49 +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-05-18 05:53:57 +02:00
std : : string Unit : : toString ( ) const {
std : : string result = " " ;
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-18 05:53:57 +02:00
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
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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 ) ;
2010-06-08 09:40:32 +02:00
result + = " \n " ;
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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 ) ;
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-18 05:53:57 +02:00
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 ) ;
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-18 05:53:57 +02:00
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
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-18 05:53:57 +02:00
result + = " Command count = " + intToStr ( commands . size ( ) ) + " \n " ;
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-18 05:53:57 +02:00
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
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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 " ;
2010-05-29 07:41:40 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-05-18 05:53:57 +02:00
return result ;
}
2010-03-12 08:42:55 +01:00
} } //end namespace