2010-03-13 22:10:45 +01:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74> o Figueroa
//
// 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 "unit_updater.h"
# include <algorithm>
# include <cassert>
2010-07-22 00:05:50 +02:00
# include "cartographer.h"
2010-03-13 22:10:45 +01:00
# include "core_data.h"
# include "config.h"
# include "game.h"
# include "faction.h"
# include "network_manager.h"
2010-07-22 00:05:50 +02:00
# include "object.h"
# include "particle_type.h"
# include "path_finder.h"
# include "renderer.h"
2010-07-13 07:33:43 +02:00
# include "route_planner.h"
2010-07-22 00:05:50 +02:00
# include "sound.h"
# include "sound_renderer.h"
# include "upgrade.h"
# include "unit.h"
2010-03-13 22:10:45 +01:00
# include "leak_dumper.h"
using namespace Shared : : Graphics ;
using namespace Shared : : Util ;
namespace Glest { namespace Game {
// =====================================================
// class UnitUpdater
// =====================================================
// ===================== PUBLIC ========================
2010-07-30 03:19:31 +02:00
UnitUpdater : : UnitUpdater ( ) {
this - > game = NULL ;
this - > gui = NULL ;
this - > gameCamera = NULL ;
this - > world = NULL ;
this - > map = NULL ;
this - > console = NULL ;
this - > scriptManager = NULL ;
this - > routePlanner = NULL ;
this - > pathFinder = NULL ;
2010-08-25 09:29:35 +02:00
UnitRangeCellsLookupItemCacheTimerCount = 0 ;
2010-07-30 03:19:31 +02:00
}
2010-03-13 22:10:45 +01:00
void UnitUpdater : : init ( Game * game ) {
2010-03-18 22:26:40 +01:00
this - > game = game ;
2010-03-13 22:10:45 +01:00
this - > gui = game - > getGui ( ) ;
this - > gameCamera = game - > getGameCamera ( ) ;
this - > world = game - > getWorld ( ) ;
this - > map = world - > getMap ( ) ;
this - > console = game - > getConsole ( ) ;
this - > scriptManager = game - > getScriptManager ( ) ;
2010-07-21 22:40:11 +02:00
this - > routePlanner = NULL ;
2010-07-22 00:05:50 +02:00
this - > pathFinder = NULL ;
2010-08-25 09:29:35 +02:00
UnitRangeCellsLookupItemCacheTimerCount = 0 ;
2010-07-21 20:21:40 +02:00
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-07-22 00:05:50 +02:00
pathFinder = new PathFinder ( ) ;
pathFinder - > init ( map ) ;
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
routePlanner = world - > getRoutePlanner ( ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
}
2010-07-22 00:05:50 +02:00
UnitUpdater : : ~ UnitUpdater ( ) {
2010-08-25 18:01:24 +02:00
UnitRangeCellsLookupItemCache . clear ( ) ;
2010-07-22 00:05:50 +02:00
delete pathFinder ;
pathFinder = NULL ;
}
2010-03-13 22:10:45 +01:00
// ==================== progress skills ====================
//skill dependent actions
2010-08-25 09:29:35 +02:00
void UnitUpdater : : updateUnit ( Unit * unit ) {
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
SoundRenderer & soundRenderer = SoundRenderer : : getInstance ( ) ;
//play skill sound
const SkillType * currSkill = unit - > getCurrSkill ( ) ;
2010-09-09 07:42:19 +02:00
if ( currSkill - > getSound ( ) ! = NULL ) {
2010-03-13 22:10:45 +01:00
float soundStartTime = currSkill - > getSoundStartTime ( ) ;
2010-09-09 07:42:19 +02:00
if ( soundStartTime > = unit - > getLastAnimProgress ( ) & & soundStartTime < unit - > getAnimProgress ( ) ) {
if ( map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getPos ( ) ) ) - > isVisible ( world - > getThisTeamIndex ( ) ) ) {
2010-03-13 22:10:45 +01:00
soundRenderer . playFx ( currSkill - > getSound ( ) , unit - > getCurrVector ( ) , gameCamera - > getPos ( ) ) ;
}
}
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [play skill sound] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
//start attack particle system
2010-09-09 07:42:19 +02:00
if ( unit - > getCurrSkill ( ) - > getClass ( ) = = scAttack ) {
2010-03-13 22:10:45 +01:00
const AttackSkillType * ast = static_cast < const AttackSkillType * > ( unit - > getCurrSkill ( ) ) ;
float attackStartTime = ast - > getAttackStartTime ( ) ;
if ( attackStartTime > = unit - > getLastAnimProgress ( ) & & attackStartTime < unit - > getAnimProgress ( ) ) {
startAttackParticleSystem ( unit ) ;
}
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [start attack particles] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
//update unit
2010-09-09 07:42:19 +02:00
if ( unit - > update ( ) ) {
2010-03-20 00:26:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-13 22:10:45 +01:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [update unit check] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
updateUnitCommand ( unit ) ;
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [update unit command] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
//if unit is out of EP, it stops
2010-09-09 07:42:19 +02:00
if ( unit - > computeEp ( ) ) {
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( scStop ) ;
unit - > cancelCommand ( ) ;
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [compute ep] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
//move unit in cells
2010-09-09 07:42:19 +02:00
if ( unit - > getCurrSkill ( ) - > getClass ( ) = = scMove ) {
2010-03-13 22:10:45 +01:00
world - > moveUnitCells ( unit ) ;
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [move unit cells] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
//play water sound
if ( map - > getCell ( unit - > getPos ( ) ) - > getHeight ( ) < map - > getWaterLevel ( ) & & unit - > getCurrField ( ) = = fLand ) {
2010-04-14 22:49:14 +02:00
soundRenderer . playFx (
CoreData : : getInstance ( ) . getWaterSound ( ) ,
unit - > getCurrVector ( ) ,
gameCamera - > getPos ( )
) ;
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [play water sound] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
}
}
//unit death
2010-09-09 07:42:19 +02:00
if ( unit - > isDead ( ) & & unit - > getCurrSkill ( ) - > getClass ( ) ! = scDie ) {
2010-03-13 22:10:45 +01:00
unit - > kill ( ) ;
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [kill unit] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
}
// ==================== progress commands ====================
//VERY IMPORTANT: compute next state depending on the first order of the list
2010-09-09 07:42:19 +02:00
void UnitUpdater : : updateUnitCommand ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-07-14 08:59:55 +02:00
//if unit has command process it
2010-03-13 22:10:45 +01:00
if ( unit - > anyCommand ( ) ) {
unit - > getCurrCommand ( ) - > getCommandType ( ) - > update ( this , unit ) ;
}
//if no commands stop and add stop command
2010-09-09 07:42:19 +02:00
if ( unit - > anyCommand ( ) = = false & & unit - > isOperative ( ) ) {
2010-03-20 00:26:00 +01:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( scStop ) ;
2010-09-09 07:42:19 +02:00
if ( unit - > getType ( ) - > hasCommandClass ( ccStop ) ) {
2010-07-14 08:59:55 +02:00
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
2010-03-13 22:10:45 +01:00
unit - > giveCommand ( new Command ( unit - > getType ( ) - > getFirstCtOfClass ( ccStop ) ) ) ;
}
}
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateStop ====================
2010-09-09 07:42:19 +02:00
void UnitUpdater : : updateStop ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const StopCommandType * sct = static_cast < const StopCommandType * > ( command - > getCommandType ( ) ) ;
Unit * sighted ;
unit - > setCurrSkill ( sct - > getStopSkillType ( ) ) ;
//we can attack any unit => attack it
if ( unit - > getType ( ) - > hasSkillClass ( scAttack ) ) {
2010-09-09 07:42:19 +02:00
for ( int i = 0 ; i < unit - > getType ( ) - > getCommandTypeCount ( ) ; + + i ) {
2010-03-13 22:10:45 +01:00
const CommandType * ct = unit - > getType ( ) - > getCommandType ( i ) ;
//look for an attack skill
const AttackSkillType * ast = NULL ;
2010-09-09 07:42:19 +02:00
if ( ct - > getClass ( ) = = ccAttack ) {
2010-03-13 22:10:45 +01:00
ast = static_cast < const AttackCommandType * > ( ct ) - > getAttackSkillType ( ) ;
}
2010-09-09 07:42:19 +02:00
else if ( ct - > getClass ( ) = = ccAttackStopped ) {
2010-03-13 22:10:45 +01:00
ast = static_cast < const AttackStoppedCommandType * > ( ct ) - > getAttackSkillType ( ) ;
}
//use it to attack
if ( ast ! = NULL ) {
2010-09-09 07:42:19 +02:00
if ( attackableOnSight ( unit , & sighted , ast ) ) {
2010-03-20 00:26:00 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > giveCommand ( new Command ( ct , sighted - > getPos ( ) ) ) ;
break ;
}
}
}
}
//see any unit and cant attack it => run
2010-09-09 07:42:19 +02:00
else if ( unit - > getType ( ) - > hasCommandClass ( ccMove ) ) {
if ( attackerOnSight ( unit , & sighted ) ) {
2010-03-13 22:10:45 +01:00
Vec2i escapePos = unit - > getPos ( ) * 2 - sighted - > getPos ( ) ;
2010-03-20 00:26:00 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > giveCommand ( new Command ( unit - > getType ( ) - > getFirstCtOfClass ( ccMove ) , escapePos ) ) ;
}
}
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateMove ====================
2010-09-09 07:42:19 +02:00
void UnitUpdater : : updateMove ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const MoveCommandType * mct = static_cast < const MoveCommandType * > ( command - > getCommandType ( ) ) ;
Vec2i pos = command - > getUnit ( ) ! = NULL ? command - > getUnit ( ) - > getCenteredPos ( ) : command - > getPos ( ) ;
2010-07-21 20:21:40 +02:00
TravelState tsValue = tsImpossible ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-07-22 00:05:50 +02:00
tsValue = pathFinder - > findPath ( unit , pos ) ;
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
tsValue = routePlanner - > findPath ( unit , pos ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-07-21 20:21:40 +02:00
switch ( tsValue ) {
2010-07-22 00:05:50 +02:00
case tsMoving :
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( mct - > getMoveSkillType ( ) ) ;
break ;
2010-07-21 20:21:40 +02:00
case tsBlocked :
2010-07-13 07:33:43 +02:00
unit - > setCurrSkill ( scStop ) ;
2010-03-13 22:10:45 +01:00
if ( unit - > getPath ( ) - > isBlocked ( ) ) {
unit - > finishCommand ( ) ;
}
break ;
default :
unit - > finishCommand ( ) ;
}
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateAttack ====================
void UnitUpdater : : updateAttack ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const AttackCommandType * act = static_cast < const AttackCommandType * > ( command - > getCommandType ( ) ) ;
Unit * target = NULL ;
//if found
2010-09-09 07:42:19 +02:00
if ( attackableOnRange ( unit , & target , act - > getAttackSkillType ( ) ) ) {
if ( unit - > getEp ( ) > = act - > getAttackSkillType ( ) - > getEpCost ( ) ) {
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( act - > getAttackSkillType ( ) ) ;
unit - > setTarget ( target ) ;
}
2010-09-09 07:42:19 +02:00
else {
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( scStop ) ;
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
2010-09-09 07:42:19 +02:00
else {
2010-03-13 22:10:45 +01:00
//compute target pos
Vec2i pos ;
2010-09-09 07:42:19 +02:00
if ( command - > getUnit ( ) ! = NULL ) {
2010-03-13 22:10:45 +01:00
pos = command - > getUnit ( ) - > getCenteredPos ( ) ;
}
2010-09-09 07:42:19 +02:00
else if ( attackableOnSight ( unit , & target , act - > getAttackSkillType ( ) ) ) {
2010-03-13 22:10:45 +01:00
pos = target - > getPos ( ) ;
}
2010-09-09 07:42:19 +02:00
else {
2010-03-13 22:10:45 +01:00
pos = command - > getPos ( ) ;
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-07-21 20:21:40 +02:00
TravelState tsValue = tsImpossible ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-07-22 00:05:50 +02:00
tsValue = pathFinder - > findPath ( unit , pos ) ;
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
tsValue = routePlanner - > findPath ( unit , pos ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
//if unit arrives destPos order has ended
2010-07-21 20:21:40 +02:00
switch ( tsValue ) {
2010-07-22 00:05:50 +02:00
case tsMoving :
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( act - > getMoveSkillType ( ) ) ;
break ;
2010-07-21 20:21:40 +02:00
case tsBlocked :
2010-03-13 22:10:45 +01:00
if ( unit - > getPath ( ) - > isBlocked ( ) ) {
unit - > finishCommand ( ) ;
}
break ;
default :
unit - > finishCommand ( ) ;
}
}
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateAttackStopped ====================
void UnitUpdater : : updateAttackStopped ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const AttackStoppedCommandType * asct = static_cast < const AttackStoppedCommandType * > ( command - > getCommandType ( ) ) ;
Unit * enemy ;
if ( attackableOnRange ( unit , & enemy , asct - > getAttackSkillType ( ) ) ) {
unit - > setCurrSkill ( asct - > getAttackSkillType ( ) ) ;
unit - > setTarget ( enemy ) ;
}
else {
unit - > setCurrSkill ( asct - > getStopSkillType ( ) ) ;
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateBuild ====================
2010-09-01 01:14:15 +02:00
void UnitUpdater : : updateBuild ( Unit * unit ) {
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const BuildCommandType * bct = static_cast < const BuildCommandType * > ( command - > getCommandType ( ) ) ;
2010-09-01 01:14:15 +02:00
std : : pair < float , Vec2i > distance = map - > getUnitDistanceToPos ( unit , command - > getPos ( ) , command - > getUnitType ( ) ) ;
unit - > setCurrentUnitTitle ( " Distance: " + floatToStr ( distance . first ) + " build pos: " + distance . second . getString ( ) + " current pos: " + unit - > getPos ( ) . getString ( ) ) ;
2010-03-13 22:10:45 +01:00
if ( unit - > getCurrSkill ( ) - > getClass ( ) ! = scBuild ) {
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
//if not building
const UnitType * ut = command - > getUnitType ( ) ;
2010-07-21 20:21:40 +02:00
TravelState tsValue = tsImpossible ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-08-28 05:43:14 +02:00
{
//Vec2i buildPos = (command->getPos()-Vec2i(1));
2010-08-29 08:30:41 +02:00
Vec2i buildPos = map - > findBestBuildApproach ( unit - > getPos ( ) , command - > getPos ( ) , ut ) ;
2010-08-28 05:43:14 +02:00
//Vec2i buildPos = (command->getPos() + Vec2i(ut->getSize() / 2));
tsValue = pathFinder - > findPath ( unit , buildPos ) ;
}
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
tsValue = routePlanner - > findPathToBuildSite ( unit , ut , command - > getPos ( ) , command - > getFacing ( ) ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-21 20:21:40 +02:00
switch ( tsValue ) {
2010-07-22 00:05:50 +02:00
case tsMoving :
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] tsMoving \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( bct - > getMoveSkillType ( ) ) ;
break ;
2010-07-21 20:21:40 +02:00
case tsArrived :
{
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] tsArrived: \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-21 20:21:40 +02:00
//if arrived destination
2010-07-14 08:54:43 +02:00
assert ( ut ) ;
2010-07-21 20:21:40 +02:00
bool canOccupyCell = false ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-09-02 07:38:49 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] tsArrived about to call map->isFreeCells() for command->getPos() = %s, ut->getSize() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , command - > getPos ( ) . getString ( ) . c_str ( ) , ut - > getSize ( ) ) ;
2010-07-21 20:21:40 +02:00
canOccupyCell = map - > isFreeCells ( command - > getPos ( ) , ut - > getSize ( ) , fLand ) ;
break ;
case pfRoutePlanner :
canOccupyCell = map - > canOccupy ( command - > getPos ( ) , ut - > getField ( ) , ut , command - > getFacing ( ) ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
if ( canOccupyCell = = true ) {
2010-03-13 22:10:45 +01:00
const UnitType * builtUnitType = command - > getUnitType ( ) ;
2010-03-25 13:15:10 +01:00
CardinalDir facing = command - > getFacing ( ) ;
2010-07-21 20:21:40 +02:00
UnitPathInterface * newpath = NULL ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
newpath = new UnitPathBasic ( ) ;
break ;
case pfRoutePlanner :
newpath = new UnitPath ( ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
Unit * builtUnit = new Unit ( world - > getNextUnitId ( unit - > getFaction ( ) ) , newpath , command - > getPos ( ) , builtUnitType , unit - > getFaction ( ) , world - > getMap ( ) , facing ) ;
2010-03-13 22:10:45 +01:00
builtUnit - > create ( ) ;
if ( ! builtUnitType - > hasSkillClass ( scBeBuilt ) ) {
throw runtime_error ( " Unit " + builtUnitType - > getName ( ) + " has no be_built skill " ) ;
}
builtUnit - > setCurrSkill ( scBeBuilt ) ;
unit - > setCurrSkill ( bct - > getBuildSkillType ( ) ) ;
unit - > setTarget ( builtUnit ) ;
map - > prepareTerrain ( builtUnit ) ;
2010-07-21 20:21:40 +02:00
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
break ;
case pfRoutePlanner :
world - > getCartographer ( ) - > updateMapMetrics ( builtUnit - > getPos ( ) , builtUnit - > getType ( ) - > getSight ( ) ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
command - > setUnit ( builtUnit ) ;
//play start sound
if ( unit - > getFactionIndex ( ) = = world - > getThisFactionIndex ( ) ) {
SoundRenderer : : getInstance ( ) . playFx (
bct - > getStartSound ( ) ,
unit - > getCurrVector ( ) ,
gameCamera - > getPos ( ) ) ;
}
2010-05-29 11:38:00 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unit created for unit [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , builtUnit - > toString ( ) . c_str ( ) ) ;
2010-03-13 22:10:45 +01:00
}
2010-09-02 07:38:49 +02:00
else {
2010-03-13 22:10:45 +01:00
//if there are no free cells
unit - > cancelCommand ( ) ;
unit - > setCurrSkill ( scStop ) ;
2010-09-01 01:14:15 +02:00
2010-03-13 22:10:45 +01:00
if ( unit - > getFactionIndex ( ) = = world - > getThisFactionIndex ( ) ) {
console - > addStdMessage ( " BuildingNoPlace " ) ;
}
2010-09-02 07:38:49 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] got BuildingNoPlace \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
}
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
break ;
2010-07-21 20:21:40 +02:00
case tsBlocked :
2010-09-02 07:38:49 +02:00
if ( unit - > getPath ( ) - > isBlocked ( ) ) {
2010-03-13 22:10:45 +01:00
unit - > cancelCommand ( ) ;
2010-09-01 01:14:15 +02:00
2010-09-02 07:38:49 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] got tsBlocked \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
}
break ;
}
}
2010-08-28 03:46:26 +02:00
else {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] tsArrived: \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
//if building
2010-09-02 07:38:49 +02:00
Unit * builtUnit = map - > getCell ( unit - > getTargetPos ( ) ) - > getUnit ( fLand ) ;
2010-03-13 22:10:45 +01:00
//if u is killed while building then u==NULL;
2010-09-02 07:38:49 +02:00
if ( builtUnit ! = NULL & & builtUnit ! = command - > getUnit ( ) ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( scStop ) ;
}
2010-09-02 07:38:49 +02:00
else if ( builtUnit = = NULL | | builtUnit - > isBuilt ( ) ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > finishCommand ( ) ;
unit - > setCurrSkill ( scStop ) ;
2010-09-01 01:14:15 +02:00
2010-03-13 22:10:45 +01:00
}
2010-09-02 07:38:49 +02:00
else if ( builtUnit - > repair ( ) ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
//building finished
unit - > finishCommand ( ) ;
unit - > setCurrSkill ( scStop ) ;
2010-09-01 01:14:15 +02:00
2010-03-13 22:10:45 +01:00
builtUnit - > born ( ) ;
scriptManager - > onUnitCreated ( builtUnit ) ;
2010-09-02 07:38:49 +02:00
if ( unit - > getFactionIndex ( ) = = world - > getThisFactionIndex ( ) ) {
2010-03-13 22:10:45 +01:00
SoundRenderer : : getInstance ( ) . playFx (
bct - > getBuiltSound ( ) ,
unit - > getCurrVector ( ) ,
gameCamera - > getPos ( ) ) ;
}
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateHarvest ====================
void UnitUpdater : : updateHarvest ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const HarvestCommandType * hct = static_cast < const HarvestCommandType * > ( command - > getCommandType ( ) ) ;
Vec2i targetPos ;
2010-07-21 20:21:40 +02:00
TravelState tsValue = tsImpossible ;
UnitPathInterface * path = unit - > getPath ( ) ;
2010-03-13 22:10:45 +01:00
if ( unit - > getCurrSkill ( ) - > getClass ( ) ! = scHarvest ) {
//if not working
if ( unit - > getLoadCount ( ) = = 0 ) {
//if not loaded go for resources
Resource * r = map - > getSurfaceCell ( Map : : toSurfCoords ( command - > getPos ( ) ) ) - > getResource ( ) ;
if ( r ! = NULL & & hct - > canHarvest ( r - > getType ( ) ) ) {
//if can harvest dest. pos
2010-07-21 20:21:40 +02:00
bool canHarvestDestPos = false ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
canHarvestDestPos = ( unit - > getPos ( ) . dist ( command - > getPos ( ) ) < harvestDistance & &
2010-08-23 00:30:17 +02:00
map - > isResourceNear ( unit - > getPos ( ) , r - > getType ( ) , targetPos , unit - > getType ( ) - > getSize ( ) ) ) ;
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
canHarvestDestPos = map - > isResourceNear ( unit - > getPos ( ) , unit - > getType ( ) - > getSize ( ) , r - > getType ( ) , targetPos ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
if ( canHarvestDestPos = = true ) {
2010-03-13 22:10:45 +01:00
//if it finds resources it starts harvesting
unit - > setCurrSkill ( hct - > getHarvestSkillType ( ) ) ;
unit - > setTargetPos ( targetPos ) ;
2010-07-13 07:33:43 +02:00
command - > setPos ( targetPos ) ;
2010-03-13 22:10:45 +01:00
unit - > setLoadCount ( 0 ) ;
2010-07-21 20:21:40 +02:00
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
unit - > setLoadType ( map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getTargetPos ( ) ) ) - > getResource ( ) - > getType ( ) ) ;
break ;
case pfRoutePlanner :
unit - > setLoadType ( r - > getType ( ) ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
}
2010-07-21 20:21:40 +02:00
else {
2010-03-13 22:10:45 +01:00
//if not continue walking
2010-07-21 20:21:40 +02:00
TravelState tsValue = tsImpossible ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-07-22 00:05:50 +02:00
tsValue = pathFinder - > findPath ( unit , command - > getPos ( ) ) ;
if ( tsValue = = tsMoving ) {
2010-07-21 20:21:40 +02:00
unit - > setCurrSkill ( hct - > getMoveSkillType ( ) ) ;
}
break ;
case pfRoutePlanner :
tsValue = routePlanner - > findPathToResource ( unit , command - > getPos ( ) , r - > getType ( ) ) ;
if ( tsValue = = tsMoving ) {
unit - > setCurrSkill ( hct - > getMoveSkillType ( ) ) ;
}
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
}
}
else {
//if can't harvest, search for another resource
unit - > setCurrSkill ( scStop ) ;
if ( ! searchForResource ( unit , hct ) ) {
unit - > finishCommand ( ) ;
}
}
}
else {
//if loaded, return to store
Unit * store = world - > nearestStore ( unit - > getPos ( ) , unit - > getFaction ( ) - > getIndex ( ) , unit - > getLoadType ( ) ) ;
2010-07-21 20:21:40 +02:00
if ( store ! = NULL ) {
TravelState tsValue = tsImpossible ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-07-22 00:05:50 +02:00
tsValue = pathFinder - > findPath ( unit , store - > getCenteredPos ( ) ) ;
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
tsValue = routePlanner - > findPathToStore ( unit , store ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
switch ( tsValue ) {
2010-07-22 00:05:50 +02:00
case tsMoving :
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( hct - > getMoveLoadedSkillType ( ) ) ;
break ;
default :
break ;
}
//world->changePosCells(unit,unit->getPos()+unit->getDest());
if ( map - > isNextTo ( unit - > getPos ( ) , store ) ) {
//update resources
int resourceAmount = unit - > getLoadCount ( ) ;
if ( unit - > getFaction ( ) - > getCpuUltraControl ( ) ) {
resourceAmount * = ultraResourceFactor ;
}
if ( unit - > getFaction ( ) - > getCpuMegaControl ( ) ) {
resourceAmount * = megaResourceFactor ;
}
unit - > getFaction ( ) - > incResourceAmount ( unit - > getLoadType ( ) , resourceAmount ) ;
world - > getStats ( ) - > harvest ( unit - > getFactionIndex ( ) , resourceAmount ) ;
scriptManager - > onResourceHarvested ( ) ;
//if next to a store unload resources
unit - > getPath ( ) - > clear ( ) ;
unit - > setCurrSkill ( scStop ) ;
unit - > setLoadCount ( 0 ) ;
}
}
else {
unit - > finishCommand ( ) ;
}
}
}
else {
//if working
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getTargetPos ( ) ) ) ;
Resource * r = sc - > getResource ( ) ;
2010-04-06 05:28:20 +02:00
if ( r ! = NULL ) {
if ( ! hct - > canHarvest ( r - > getType ( ) ) | | r - > getType ( ) ! = unit - > getLoadType ( ) ) {
// hct has changed to a different harvest command.
unit - > setCurrSkill ( hct - > getStopLoadedSkillType ( ) ) ; // this is actually the wrong animation
unit - > getPath ( ) - > clear ( ) ;
}
2010-08-25 09:29:35 +02:00
else {
// if there is a resource, continue working, until loaded
unit - > update2 ( ) ;
if ( unit - > getProgress2 ( ) > = hct - > getHitsPerUnit ( ) ) {
if ( unit - > getLoadCount ( ) < hct - > getMaxLoad ( ) ) {
unit - > setProgress2 ( 0 ) ;
unit - > setLoadCount ( unit - > getLoadCount ( ) + 1 ) ;
//if resource exausted, then delete it and stop
if ( r - > decAmount ( 1 ) ) {
const ResourceType * rt = r - > getType ( ) ;
sc - > deleteResource ( ) ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
break ;
case pfRoutePlanner :
world - > getCartographer ( ) - > onResourceDepleted ( Map : : toSurfCoords ( unit - > getTargetPos ( ) ) , rt ) ;
break ;
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
}
2010-04-06 05:28:20 +02:00
2010-08-25 09:29:35 +02:00
unit - > setCurrSkill ( hct - > getStopLoadedSkillType ( ) ) ;
}
}
if ( unit - > getLoadCount ( ) > = hct - > getMaxLoad ( ) ) {
2010-04-06 05:28:20 +02:00
unit - > setCurrSkill ( hct - > getStopLoadedSkillType ( ) ) ;
2010-08-25 09:29:35 +02:00
unit - > getPath ( ) - > clear ( ) ;
2010-04-06 05:28:20 +02:00
}
}
}
}
else {
//if there is no resource, just stop
unit - > setCurrSkill ( hct - > getStopLoadedSkillType ( ) ) ;
}
2010-03-13 22:10:45 +01:00
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
2010-08-28 03:46:26 +02:00
void UnitUpdater : : SwapActiveCommand ( Unit * unitSrc , Unit * unitDest ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( unitSrc - > getCommandSize ( ) > 0 & & unitDest - > getCommandSize ( ) > 0 ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
Command * cmd1 = unitSrc - > getCurrCommand ( ) ;
Command * cmd2 = unitDest - > getCurrCommand ( ) ;
unitSrc - > replaceCurrCommand ( cmd2 ) ;
unitDest - > replaceCurrCommand ( cmd1 ) ;
}
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2010-09-02 07:38:49 +02:00
void UnitUpdater : : SwapActiveCommandState ( Unit * unit , CommandStateType commandStateType ,
const CommandType * commandType ,
int originalValue , int newValue ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( commandStateType = = cst_linkedUnit ) {
if ( dynamic_cast < const BuildCommandType * > ( commandType ) ! = NULL ) {
for ( int i = 0 ; i < unit - > getFaction ( ) - > getUnitCount ( ) ; + + i ) {
Unit * peerUnit = unit - > getFaction ( ) - > getUnit ( i ) ;
if ( peerUnit ! = NULL ) {
if ( peerUnit - > getCommandSize ( ) > 0 ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
Command * peerCommand = peerUnit - > getCurrCommand ( ) ;
//const BuildCommandType *bct = dynamic_cast<const BuildCommandType*>(peerCommand->getCommandType());
//if(bct != NULL) {
if ( peerCommand ! = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
//if(command->getPos() == peerCommand->getPos()) {
if ( peerCommand - > getStateType ( ) = = commandStateType & &
peerCommand - > getStateValue ( ) = = originalValue ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
peerCommand - > setStateValue ( newValue ) ;
}
}
}
}
}
}
}
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2010-08-28 03:46:26 +02:00
Unit * UnitUpdater : : findPeerUnitBuilder ( Unit * unit ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
Unit * foundUnitBuilder = NULL ;
if ( unit - > getCommandSize ( ) > 0 ) {
2010-08-30 22:45:12 +02:00
Command * command = unit - > getCurrCommand ( ) ;
2010-08-28 03:46:26 +02:00
if ( command ! = NULL ) {
const RepairCommandType * rct = dynamic_cast < const RepairCommandType * > ( command - > getCommandType ( ) ) ;
2010-08-30 22:45:12 +02:00
if ( rct ! = NULL & & command - > getStateType ( ) = = cst_linkedUnit ) {
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
for ( int i = 0 ; i < unit - > getFaction ( ) - > getUnitCount ( ) ; + + i ) {
Unit * peerUnit = unit - > getFaction ( ) - > getUnit ( i ) ;
if ( peerUnit ! = NULL ) {
if ( peerUnit - > getCommandSize ( ) > 0 ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
Command * peerCommand = peerUnit - > getCurrCommand ( ) ;
const BuildCommandType * bct = dynamic_cast < const BuildCommandType * > ( peerCommand - > getCommandType ( ) ) ;
if ( bct ! = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-30 22:45:12 +02:00
//if(command->getPos() == peerCommand->getPos()) {
if ( command - > getStateValue ( ) = = peerUnit - > getId ( ) ) {
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
foundUnitBuilder = peerUnit ;
break ;
}
}
}
}
}
}
}
}
return foundUnitBuilder ;
}
2010-03-13 22:10:45 +01:00
// ==================== updateRepair ====================
2010-08-28 03:46:26 +02:00
void UnitUpdater : : updateRepair ( Unit * unit ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unit = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit ) ;
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const RepairCommandType * rct = static_cast < const RepairCommandType * > ( command - > getCommandType ( ) ) ;
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] rct = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , rct ) ;
2010-09-01 06:19:20 +02:00
Unit * repaired = map - > getCell ( command - > getPos ( ) ) - > getUnit ( fLand ) ;
bool nextToRepaired = repaired ! = NULL & & map - > isNextTo ( unit - > getPos ( ) , repaired ) ;
2010-03-13 22:10:45 +01:00
2010-08-28 03:46:26 +02:00
Unit * peerUnitBuilder = NULL ;
if ( repaired = = NULL ) {
peerUnitBuilder = findPeerUnitBuilder ( unit ) ;
if ( peerUnitBuilder ! = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] peerUnitBuilder = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , peerUnitBuilder ) ;
2010-09-02 07:38:49 +02:00
if ( peerUnitBuilder - > getCurrCommand ( ) - > getUnit ( ) ! = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] peerbuilder's unitid = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , peerUnitBuilder - > getCurrCommand ( ) - > getUnit ( ) - > getId ( ) ) ;
2010-09-01 06:19:20 +02:00
2010-09-02 07:38:49 +02:00
repaired = peerUnitBuilder - > getCurrCommand ( ) - > getUnit ( ) ;
nextToRepaired = repaired ! = NULL & & map - > isNextTo ( unit - > getPos ( ) , repaired ) ;
}
else {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-28 03:46:26 +02:00
2010-09-02 07:38:49 +02:00
Vec2i buildPos = map - > findBestBuildApproach ( unit - > getPos ( ) , command - > getPos ( ) , peerUnitBuilder - > getCurrCommand ( ) - > getUnitType ( ) ) ;
2010-08-28 03:46:26 +02:00
2010-09-02 07:38:49 +02:00
//nextToRepaired= (unit->getPos() == (command->getPos()-Vec2i(1)));
nextToRepaired = ( unit - > getPos ( ) = = buildPos ) ;
2010-08-28 03:46:26 +02:00
2010-09-02 07:38:49 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] peerUnitBuilder = %p, nextToRepaired = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , peerUnitBuilder , nextToRepaired ) ;
if ( nextToRepaired = = true ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
CommandStateType commandStateType = unit - > getCurrCommand ( ) - > getStateType ( ) ;
SwapActiveCommand ( unit , peerUnitBuilder ) ;
int oldPeerUnitId = peerUnitBuilder - > getId ( ) ;
int newPeerUnitId = unit - > getId ( ) ;
SwapActiveCommandState ( unit , commandStateType , unit - > getCurrCommand ( ) - > getCommandType ( ) , oldPeerUnitId , newPeerUnitId ) ;
// Give the swapped unit a fresh chance to help build in case they
// were or are about to be blocked
peerUnitBuilder - > getPath ( ) - > clear ( ) ;
peerUnitBuilder - > setRetryCurrCommandCount ( 1 ) ;
updateUnitCommand ( unit ) ;
//updateUnitCommand(peerUnitBuilder);
return ;
}
2010-08-28 03:46:26 +02:00
}
}
}
else {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] unit to repair[%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , repaired - > getFullName ( ) . c_str ( ) ) ;
}
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] repaired = %p, nextToRepaired = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , repaired , nextToRepaired ) ;
2010-07-21 20:21:40 +02:00
UnitPathInterface * path = unit - > getPath ( ) ;
2010-08-28 03:46:26 +02:00
if ( unit - > getCurrSkill ( ) - > getClass ( ) ! = scRepair | |
( nextToRepaired = = false & & peerUnitBuilder = = NULL ) ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
Vec2i repairPos = command - > getPos ( ) ;
bool startRepairing = ( repaired ! = NULL & & rct - > isRepairableUnitType ( repaired - > getType ( ) ) & & repaired - > isDamaged ( ) ) ;
if ( startRepairing = = false & & peerUnitBuilder ! = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
startRepairing = true ;
// Since the unit to be built is not yet existing we need to tell the
// other units to move to the build position or else they get in the way
2010-09-06 07:34:55 +02:00
// No need to adjust repair pos since we already did this above via: Vec2i buildPos = map->findBestBuildApproach(unit->getPos(), command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType());
//repairPos = command->getPos()-Vec2i(1);
2010-08-28 03:46:26 +02:00
}
2010-03-13 22:10:45 +01:00
//if not repairing
2010-08-28 03:46:26 +02:00
if ( startRepairing = = true ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( nextToRepaired = = true ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setTarget ( repaired ) ;
unit - > setCurrSkill ( rct - > getRepairSkillType ( ) ) ;
}
2010-07-21 20:21:40 +02:00
else {
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-14 08:54:43 +02:00
TravelState ts ;
2010-07-21 20:21:40 +02:00
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
ts = pathFinder - > findPath ( unit , repairPos ) ;
2010-07-21 20:21:40 +02:00
break ;
case pfRoutePlanner :
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-07-21 20:21:40 +02:00
if ( repaired & & ! repaired - > getType ( ) - > isMobile ( ) ) {
ts = routePlanner - > findPathToBuildSite ( unit , repaired - > getType ( ) , repaired - > getPos ( ) , repaired - > getModelFacing ( ) ) ;
}
else {
2010-08-28 03:46:26 +02:00
ts = routePlanner - > findPath ( unit , repairPos ) ;
2010-07-21 20:21:40 +02:00
}
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-07-14 08:54:43 +02:00
switch ( ts ) {
2010-07-22 00:05:50 +02:00
case tsMoving :
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] tsMoving \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( rct - > getMoveSkillType ( ) ) ;
break ;
2010-07-21 20:21:40 +02:00
case tsBlocked :
2010-08-28 03:46:26 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] tsBlocked \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( unit - > getPath ( ) - > isBlocked ( ) ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to call [scStop] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( unit - > getRetryCurrCommandCount ( ) > 0 ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] will retry command, unit->getRetryCurrCommandCount() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > getRetryCurrCommandCount ( ) ) ;
unit - > setRetryCurrCommandCount ( 0 ) ;
unit - > getPath ( ) - > clear ( ) ;
updateUnitCommand ( unit ) ;
}
else {
unit - > finishCommand ( ) ;
}
2010-03-13 22:10:45 +01:00
}
break ;
default :
break ;
}
}
}
2010-08-28 03:46:26 +02:00
else {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to call [scStop] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( scStop ) ;
unit - > finishCommand ( ) ;
}
}
2010-08-28 03:46:26 +02:00
else {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
//if repairing
2010-08-28 03:46:26 +02:00
if ( repaired ! = NULL ) {
2010-09-06 07:34:55 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setTarget ( repaired ) ;
}
2010-08-28 03:46:26 +02:00
else if ( peerUnitBuilder ! = NULL ) {
2010-09-06 07:34:55 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-08-28 03:46:26 +02:00
unit - > setTargetPos ( command - > getPos ( ) ) ;
}
if ( ( repaired = = NULL | | repaired - > repair ( ) ) & &
peerUnitBuilder = = NULL ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to call [scStop] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
unit - > setCurrSkill ( scStop ) ;
unit - > finishCommand ( ) ;
2010-08-28 03:46:26 +02:00
if ( repaired ! = NULL & & repaired - > isBuilt ( ) = = false ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
repaired - > born ( ) ;
scriptManager - > onUnitCreated ( repaired ) ;
}
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateProduce ====================
void UnitUpdater : : updateProduce ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const ProduceCommandType * pct = static_cast < const ProduceCommandType * > ( command - > getCommandType ( ) ) ;
Unit * produced ;
if ( unit - > getCurrSkill ( ) - > getClass ( ) ! = scProduce ) {
//if not producing
unit - > setCurrSkill ( pct - > getProduceSkillType ( ) ) ;
}
else {
unit - > update2 ( ) ;
if ( unit - > getProgress2 ( ) > pct - > getProduced ( ) - > getProductionTime ( ) ) {
unit - > finishCommand ( ) ;
unit - > setCurrSkill ( scStop ) ;
2010-07-21 20:21:40 +02:00
UnitPathInterface * newpath = NULL ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
newpath = new UnitPathBasic ( ) ;
break ;
case pfRoutePlanner :
newpath = new UnitPath ( ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
produced = new Unit ( world - > getNextUnitId ( unit - > getFaction ( ) ) , newpath , Vec2i ( 0 ) , pct - > getProducedUnit ( ) , unit - > getFaction ( ) , world - > getMap ( ) , CardinalDir : : NORTH ) ;
2010-03-13 22:10:45 +01:00
2010-05-29 11:04:22 +02:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] about to place unit for unit [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , produced - > toString ( ) . c_str ( ) ) ;
2010-03-13 22:10:45 +01:00
//place unit creates the unit
2010-05-29 11:04:22 +02:00
if ( ! world - > placeUnit ( unit - > getCenteredPos ( ) , 10 , produced ) ) {
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d] \n " , __FILE__ , __FUNCTION__ , __LINE__ , produced - > getId ( ) ) ;
2010-03-13 22:10:45 +01:00
delete produced ;
}
else {
produced - > create ( ) ;
produced - > born ( ) ;
world - > getStats ( ) - > produce ( unit - > getFactionIndex ( ) ) ;
const CommandType * ct = produced - > computeCommandType ( unit - > getMeetingPos ( ) ) ;
if ( ct ! = NULL ) {
2010-03-20 00:26:00 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-13 22:10:45 +01:00
produced - > giveCommand ( new Command ( ct , unit - > getMeetingPos ( ) ) ) ;
}
scriptManager - > onUnitCreated ( produced ) ;
}
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateUpgrade ====================
void UnitUpdater : : updateUpgrade ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const UpgradeCommandType * uct = static_cast < const UpgradeCommandType * > ( command - > getCommandType ( ) ) ;
if ( unit - > getCurrSkill ( ) - > getClass ( ) ! = scUpgrade ) {
//if not producing
unit - > setCurrSkill ( uct - > getUpgradeSkillType ( ) ) ;
}
else {
//if producing
unit - > update2 ( ) ;
if ( unit - > getProgress2 ( ) > uct - > getProduced ( ) - > getProductionTime ( ) ) {
unit - > finishCommand ( ) ;
unit - > setCurrSkill ( scStop ) ;
unit - > getFaction ( ) - > finishUpgrade ( uct - > getProducedUpgrade ( ) ) ;
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== updateMorph ====================
void UnitUpdater : : updateMorph ( Unit * unit ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Command * command = unit - > getCurrCommand ( ) ;
const MorphCommandType * mct = static_cast < const MorphCommandType * > ( command - > getCommandType ( ) ) ;
if ( unit - > getCurrSkill ( ) - > getClass ( ) ! = scMorph ) {
//if not morphing, check space
if ( map - > isFreeCellsOrHasUnit ( unit - > getPos ( ) , mct - > getMorphUnit ( ) - > getSize ( ) , unit - > getCurrField ( ) , unit ) ) {
unit - > setCurrSkill ( mct - > getMorphSkillType ( ) ) ;
}
else {
if ( unit - > getFactionIndex ( ) = = world - > getThisFactionIndex ( ) ) {
console - > addStdMessage ( " InvalidPosition " ) ;
}
unit - > cancelCommand ( ) ;
}
}
else {
unit - > update2 ( ) ;
if ( unit - > getProgress2 ( ) > mct - > getProduced ( ) - > getProductionTime ( ) ) {
2010-07-21 20:21:40 +02:00
int oldSize = 0 ;
bool needMapUpdate = false ;
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
break ;
case pfRoutePlanner :
oldSize = unit - > getType ( ) - > getSize ( ) ;
needMapUpdate = unit - > getType ( ) - > isMobile ( ) ! = mct - > getMorphUnit ( ) - > isMobile ( ) ;
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-07-13 07:33:43 +02:00
2010-03-13 22:10:45 +01:00
//finish the command
if ( unit - > morph ( mct ) ) {
unit - > finishCommand ( ) ;
if ( gui - > isSelected ( unit ) ) {
gui - > onSelectionChanged ( ) ;
}
2010-07-21 20:21:40 +02:00
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
break ;
case pfRoutePlanner :
if ( needMapUpdate ) {
int size = std : : max ( oldSize , unit - > getType ( ) - > getSize ( ) ) ;
world - > getCartographer ( ) - > updateMapMetrics ( unit - > getPos ( ) , size ) ;
}
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
scriptManager - > onUnitCreated ( unit ) ;
}
else {
unit - > cancelCommand ( ) ;
if ( unit - > getFactionIndex ( ) = = world - > getThisFactionIndex ( ) ) {
console - > addStdMessage ( " InvalidPosition " ) ;
}
}
unit - > setCurrSkill ( scStop ) ;
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
// ==================== PRIVATE ====================
// ==================== attack ====================
void UnitUpdater : : hit ( Unit * attacker ) {
hit ( attacker , static_cast < const AttackSkillType * > ( attacker - > getCurrSkill ( ) ) , attacker - > getTargetPos ( ) , attacker - > getTargetField ( ) ) ;
}
void UnitUpdater : : hit ( Unit * attacker , const AttackSkillType * ast , const Vec2i & targetPos , Field targetField ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
//hit attack positions
if ( ast - > getSplash ( ) ) {
PosCircularIterator pci ( map , targetPos , ast - > getSplashRadius ( ) ) ;
while ( pci . next ( ) ) {
Unit * attacked = map - > getCell ( pci . getPos ( ) ) - > getUnit ( targetField ) ;
if ( attacked ! = NULL ) {
if ( ast - > getSplashDamageAll ( )
| | ! attacker - > isAlly ( attacked )
| | ( targetPos . x = = pci . getPos ( ) . x & & targetPos . y = = pci . getPos ( ) . y ) ) {
damage ( attacker , ast , attacked , pci . getPos ( ) . dist ( attacker - > getTargetPos ( ) ) ) ;
}
}
}
}
else {
Unit * attacked = map - > getCell ( targetPos ) - > getUnit ( targetField ) ;
if ( attacked ! = NULL ) {
damage ( attacker , ast , attacked , 0.f ) ;
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
void UnitUpdater : : damage ( Unit * attacker , const AttackSkillType * ast , Unit * attacked , float distance ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
//get vars
2010-05-01 22:14:25 +02:00
float damage = ast - > getTotalAttackStrength ( attacker - > getTotalUpgrade ( ) ) ;
2010-03-13 22:10:45 +01:00
int var = ast - > getAttackVar ( ) ;
int armor = attacked - > getType ( ) - > getTotalArmor ( attacked - > getTotalUpgrade ( ) ) ;
float damageMultiplier = world - > getTechTree ( ) - > getDamageMultiplier ( ast - > getAttackType ( ) , attacked - > getType ( ) - > getArmorType ( ) ) ;
//compute damage
damage + = random . randRange ( - var , var ) ;
damage / = distance + 1 ;
damage - = armor ;
damage * = damageMultiplier ;
if ( damage < 1 ) {
damage = 1 ;
}
//damage the unit
if ( attacked - > decHp ( static_cast < int > ( damage ) ) ) {
world - > getStats ( ) - > kill ( attacker - > getFactionIndex ( ) , attacked - > getFactionIndex ( ) ) ;
attacker - > incKills ( ) ;
2010-07-21 20:21:40 +02:00
switch ( this - > game - > getGameSettings ( ) - > getPathFinderType ( ) ) {
case pfBasic :
break ;
case pfRoutePlanner :
if ( ! attacked - > getType ( ) - > isMobile ( ) ) {
world - > getCartographer ( ) - > updateMapMetrics ( attacked - > getPos ( ) , attacked - > getType ( ) - > getSize ( ) ) ;
}
break ;
2010-07-21 22:40:11 +02:00
default :
throw runtime_error ( " detected unsupported pathfinder type! " ) ;
2010-07-21 20:21:40 +02:00
}
2010-03-13 22:10:45 +01:00
scriptManager - > onUnitDied ( attacked ) ;
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
}
void UnitUpdater : : startAttackParticleSystem ( Unit * unit ) {
Renderer & renderer = Renderer : : getInstance ( ) ;
ProjectileParticleSystem * psProj = 0 ;
SplashParticleSystem * psSplash ;
const AttackSkillType * ast = static_cast < const AttackSkillType * > ( unit - > getCurrSkill ( ) ) ;
ParticleSystemTypeProjectile * pstProj = ast - > getProjParticleType ( ) ;
ParticleSystemTypeSplash * pstSplash = ast - > getSplashParticleType ( ) ;
Vec3f startPos = unit - > getCurrVector ( ) ;
Vec3f endPos = unit - > getTargetVec ( ) ;
//make particle system
const SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getPos ( ) ) ) ;
const SurfaceCell * tsc = map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getTargetPos ( ) ) ) ;
bool visible = sc - > isVisible ( world - > getThisTeamIndex ( ) ) | | tsc - > isVisible ( world - > getThisTeamIndex ( ) ) ;
//projectile
if ( pstProj ! = NULL ) {
psProj = pstProj - > create ( ) ;
psProj - > setPath ( startPos , endPos ) ;
psProj - > setObserver ( new ParticleDamager ( unit , this , gameCamera ) ) ;
psProj - > setVisible ( visible ) ;
psProj - > setFactionColor ( unit - > getFaction ( ) - > getTexture ( ) - > getPixmap ( ) - > getPixel3f ( 0 , 0 ) ) ;
renderer . manageParticleSystem ( psProj , rsGame ) ;
}
else {
hit ( unit ) ;
}
//splash
if ( pstSplash ! = NULL ) {
psSplash = pstSplash - > create ( ) ;
psSplash - > setPos ( endPos ) ;
psSplash - > setVisible ( visible ) ;
psSplash - > setFactionColor ( unit - > getFaction ( ) - > getTexture ( ) - > getPixmap ( ) - > getPixel3f ( 0 , 0 ) ) ;
renderer . manageParticleSystem ( psSplash , rsGame ) ;
if ( pstProj ! = NULL ) {
psProj - > link ( psSplash ) ;
}
}
}
// ==================== misc ====================
//looks for a resource of type rt, if rt==NULL looks for any
//resource the unit can harvest
bool UnitUpdater : : searchForResource ( Unit * unit , const HarvestCommandType * hct ) {
2010-08-25 09:29:35 +02:00
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
Vec2i pos = unit - > getCurrCommand ( ) - > getPos ( ) ;
for ( int radius = 0 ; radius < maxResSearchRadius ; radius + + ) {
for ( int i = pos . x - radius ; i < = pos . x + radius ; + + i ) {
for ( int j = pos . y - radius ; j < = pos . y + radius ; + + j ) {
if ( map - > isInside ( i , j ) ) {
Resource * r = map - > getSurfaceCell ( Map : : toSurfCoords ( Vec2i ( i , j ) ) ) - > getResource ( ) ;
if ( r ! = NULL ) {
if ( hct - > canHarvest ( r - > getType ( ) ) ) {
unit - > getCurrCommand ( ) - > setPos ( Vec2i ( i , j ) ) ;
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
return true ;
}
}
}
}
}
}
2010-08-25 09:29:35 +02:00
if ( chrono . getMillis ( ) > 0 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 0 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
return false ;
}
bool UnitUpdater : : attackerOnSight ( const Unit * unit , Unit * * rangedPtr ) {
int range = unit - > getType ( ) - > getSight ( ) ;
return unitOnRange ( unit , range , rangedPtr , NULL ) ;
}
bool UnitUpdater : : attackableOnSight ( const Unit * unit , Unit * * rangedPtr , const AttackSkillType * ast ) {
int range = unit - > getType ( ) - > getSight ( ) ;
return unitOnRange ( unit , range , rangedPtr , ast ) ;
}
bool UnitUpdater : : attackableOnRange ( const Unit * unit , Unit * * rangedPtr , const AttackSkillType * ast ) {
int range = ast - > getTotalAttackRange ( unit - > getTotalUpgrade ( ) ) ;
return unitOnRange ( unit , range , rangedPtr , ast ) ;
}
2010-08-25 17:55:17 +02:00
bool UnitUpdater : : findCachedCellsEnemies ( Vec2i center , int range , int size , vector < Unit * > & enemies ,
2010-08-25 09:29:35 +02:00
const AttackSkillType * ast , const Unit * unit ,
const Unit * commandTarget ) {
bool result = false ;
2010-08-25 17:55:17 +02:00
//return result;
2010-08-25 09:29:35 +02:00
2010-08-25 17:55:17 +02:00
std : : map < Vec2i , std : : map < int , std : : map < int , UnitRangeCellsLookupItem > > > : : iterator iterFind = UnitRangeCellsLookupItemCache . find ( center ) ;
2010-08-25 09:29:35 +02:00
if ( iterFind ! = UnitRangeCellsLookupItemCache . end ( ) ) {
2010-08-25 17:55:17 +02:00
std : : map < int , std : : map < int , UnitRangeCellsLookupItem > > : : iterator iterFind3 = iterFind - > second . find ( size ) ;
if ( iterFind3 ! = iterFind - > second . end ( ) ) {
std : : map < int , UnitRangeCellsLookupItem > : : iterator iterFind4 = iterFind3 - > second . find ( range ) ;
if ( iterFind4 ! = iterFind3 - > second . end ( ) ) {
result = true ;
std : : vector < Cell * > & cellList = iterFind4 - > second . rangeCellList ;
for ( int idx = 0 ; idx < cellList . size ( ) ; + + idx ) {
Cell * cell = cellList [ idx ] ;
findEnemiesForCell ( ast , cell , unit , commandTarget , enemies ) ;
2010-08-25 09:29:35 +02:00
}
}
}
}
return result ;
}
void UnitUpdater : : findEnemiesForCell ( const AttackSkillType * ast , Cell * cell , const Unit * unit ,
const Unit * commandTarget , vector < Unit * > & enemies ) {
//all fields
for ( int k = 0 ; k < fieldCount ; k + + ) {
Field f = static_cast < Field > ( k ) ;
//check field
if ( ( ast = = NULL | | ast - > getAttackField ( f ) ) ) {
Unit * possibleEnemy = cell - > getUnit ( f ) ;
//check enemy
if ( possibleEnemy ! = NULL & & possibleEnemy - > isAlive ( ) ) {
if ( ( ! unit - > isAlly ( possibleEnemy ) & & commandTarget = = NULL ) | |
commandTarget = = possibleEnemy ) {
enemies . push_back ( possibleEnemy ) ;
}
}
}
}
}
2010-03-13 22:10:45 +01:00
//if the unit has any enemy on range
2010-08-25 09:29:35 +02:00
bool UnitUpdater : : unitOnRange ( const Unit * unit , int range , Unit * * rangedPtr ,
const AttackSkillType * ast ) {
Chrono chrono ;
chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
vector < Unit * > enemies ;
//we check command target
2010-08-25 09:29:35 +02:00
const Unit * commandTarget = NULL ;
if ( unit - > anyCommand ( ) ) {
commandTarget = static_cast < const Unit * > ( unit - > getCurrCommand ( ) - > getUnit ( ) ) ;
2010-03-13 22:10:45 +01:00
}
2010-08-25 09:29:35 +02:00
if ( commandTarget ! = NULL & & commandTarget - > isDead ( ) ) {
commandTarget = NULL ;
2010-03-13 22:10:45 +01:00
}
//aux vars
2010-08-25 09:29:35 +02:00
int size = unit - > getType ( ) - > getSize ( ) ;
Vec2i center = unit - > getPos ( ) ;
Vec2f floatCenter = unit - > getFloatCenteredPos ( ) ;
2010-03-13 22:10:45 +01:00
2010-08-25 09:29:35 +02:00
bool foundInCache = true ;
2010-08-25 17:55:17 +02:00
if ( findCachedCellsEnemies ( center , range , size , enemies , ast ,
2010-08-25 09:29:35 +02:00
unit , commandTarget ) = = false ) {
foundInCache = false ;
2010-03-13 22:10:45 +01:00
2010-08-25 09:29:35 +02:00
//nearby cells
UnitRangeCellsLookupItem cacheItem ;
for ( int i = center . x - range ; i < center . x + range + size ; + + i ) {
for ( int j = center . y - range ; j < center . y + range + size ; + + j ) {
//cells inside map and in range
2010-05-01 22:14:25 +02:00
# ifdef USE_STREFLOP
2010-08-25 09:29:35 +02:00
if ( map - > isInside ( i , j ) & & streflop : : floor ( floatCenter . dist ( Vec2f ( ( float ) i , ( float ) j ) ) ) < = ( range + 1 ) ) {
2010-05-01 22:14:25 +02:00
# else
2010-08-25 09:29:35 +02:00
if ( map - > isInside ( i , j ) & & floor ( floatCenter . dist ( Vec2f ( ( float ) i , ( float ) j ) ) ) < = ( range + 1 ) ) {
2010-05-01 22:14:25 +02:00
# endif
2010-08-25 09:29:35 +02:00
Cell * cell = map - > getCell ( i , j ) ;
findEnemiesForCell ( ast , cell , unit , commandTarget , enemies ) ;
cacheItem . rangeCellList . push_back ( cell ) ;
2010-03-13 22:10:45 +01:00
}
}
}
2010-08-25 09:29:35 +02:00
// Ok update our caches with the latest info
if ( cacheItem . rangeCellList . size ( ) > 0 ) {
cacheItem . UnitRangeCellsLookupItemCacheTimerCountIndex = UnitRangeCellsLookupItemCacheTimerCount + + ;
2010-08-25 17:55:17 +02:00
UnitRangeCellsLookupItemCache [ center ] [ size ] [ range ] = cacheItem ;
2010-08-25 09:29:35 +02:00
}
2010-03-13 22:10:45 +01:00
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld [AFTER LOOP] \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-03-13 22:10:45 +01:00
//attack enemies that can attack first
2010-09-09 07:42:19 +02:00
for ( int i = 0 ; i < enemies . size ( ) ; + + i ) {
if ( enemies [ i ] - > getType ( ) - > hasSkillClass ( scAttack ) ) {
2010-03-13 22:10:45 +01:00
* rangedPtr = enemies [ i ] ;
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld, unit %s, range = %d, size = %d, foundInCache = %d, enemies.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) , unit - > getFullName ( ) . c_str ( ) , range , size , foundInCache , enemies . size ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
return true ;
}
}
//any enemy
2010-09-09 07:42:19 +02:00
if ( enemies . size ( ) > 0 ) {
2010-03-13 22:10:45 +01:00
* rangedPtr = enemies . front ( ) ;
2010-08-25 09:29:35 +02:00
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld, unit %s, range = %d, size = %d, foundInCache = %d, enemies.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) , unit - > getFullName ( ) . c_str ( ) , range , size , foundInCache , enemies . size ( ) ) ;
if ( chrono . getMillis ( ) > 1 ) chrono . start ( ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
return true ;
}
2010-09-09 07:42:19 +02:00
if ( chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld, unit %s, range = %d, size = %d, foundInCache = %d, enemies.size() = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) , unit - > getFullName ( ) . c_str ( ) , range , size , foundInCache , enemies . size ( ) ) ;
2010-08-25 09:29:35 +02:00
2010-03-13 22:10:45 +01:00
return false ;
}
// =====================================================
// class ParticleDamager
// =====================================================
ParticleDamager : : ParticleDamager ( Unit * attacker , UnitUpdater * unitUpdater , const GameCamera * gameCamera ) {
this - > gameCamera = gameCamera ;
this - > attackerRef = attacker ;
this - > ast = static_cast < const AttackSkillType * > ( attacker - > getCurrSkill ( ) ) ;
this - > targetPos = attacker - > getTargetPos ( ) ;
this - > targetField = attacker - > getTargetField ( ) ;
this - > unitUpdater = unitUpdater ;
}
void ParticleDamager : : update ( ParticleSystem * particleSystem ) {
Unit * attacker = attackerRef . getUnit ( ) ;
if ( attacker ! = NULL ) {
unitUpdater - > hit ( attacker , ast , targetPos , targetField ) ;
//play sound
StaticSound * projSound = ast - > getProjSound ( ) ;
if ( particleSystem - > getVisible ( ) & & projSound ! = NULL ) {
SoundRenderer : : getInstance ( ) . playFx ( projSound , attacker - > getCurrVector ( ) , gameCamera - > getPos ( ) ) ;
}
}
particleSystem - > setObserver ( NULL ) ;
delete this ;
}
} } //end namespace