2011-12-14 00:23:17 +03:00
# include "StdInc.h"
2009-05-20 13:08:56 +03:00
# include "NetPacks.h"
2011-12-14 00:23:17 +03:00
2010-12-20 23:22:53 +02:00
# include "CGeneralTextHandler.h"
# include "CDefObjInfoHandler.h"
# include "CArtHandler.h"
# include "CHeroHandler.h"
# include "CObjectHandler.h"
2009-05-20 13:08:56 +03:00
# include "VCMI_Lib.h"
# include "map.h"
2010-12-20 23:22:53 +02:00
# include "CSpellHandler.h"
# include "CCreatureHandler.h"
2010-12-25 21:23:30 +02:00
# include "CGameState.h"
# include "BattleState.h"
2009-03-07 17:55:56 +02:00
2009-08-22 17:39:44 +03:00
# undef min
# undef max
2009-04-15 17:03:31 +03:00
/*
* NetPacksLib . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
2009-05-18 01:52:22 +03:00
# ifdef min
# undef min
# endif
# ifdef max
# undef max
# endif
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetResource : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2011-12-14 00:23:17 +03:00
assert ( player < GameConstants : : PLAYER_LIMIT ) ;
vstd : : amax ( val , 0 ) ; //new value must be >= 0
2009-03-09 12:37:49 +02:00
gs - > getPlayer ( player ) - > resources [ resid ] = val ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetResources : : applyGs ( CGameState * gs )
2011-07-05 09:14:07 +03:00
{
2011-12-14 00:23:17 +03:00
assert ( player < GameConstants : : PLAYER_LIMIT ) ;
2011-07-05 09:14:07 +03:00
gs - > getPlayer ( player ) - > resources = res ;
}
2009-03-07 17:55:56 +02:00
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetPrimSkill : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * hero = gs - > getHero ( id ) ;
2010-05-02 21:20:26 +03:00
assert ( hero ) ;
2009-03-07 17:55:56 +02:00
if ( which < 4 )
{
2010-05-02 21:20:26 +03:00
Bonus * skill = hero - > getBonus ( Selector : : type ( Bonus : : PRIMARY_SKILL ) & & Selector : : subtype ( which ) & & Selector : : sourceType ( Bonus : : HERO_BASE_SKILL ) ) ;
assert ( skill ) ;
2009-03-07 17:55:56 +02:00
if ( abs )
2010-05-02 21:20:26 +03:00
skill - > val = val ;
2009-03-07 17:55:56 +02:00
else
2010-05-02 21:20:26 +03:00
skill - > val + = val ;
2009-03-07 17:55:56 +02:00
}
else if ( which = = 4 ) //XP
{
if ( abs )
hero - > exp = val ;
else
hero - > exp + = val ;
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetSecSkill : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * hero = gs - > getHero ( id ) ;
2010-12-23 22:18:10 +02:00
hero - > setSecSkillLevel ( static_cast < CGHeroInstance : : SecondarySkill > ( which ) , val , abs ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void HeroVisitCastle : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * h = gs - > getHero ( hid ) ;
CGTownInstance * t = gs - > getTown ( tid ) ;
2011-02-04 16:58:14 +02:00
2009-03-07 17:55:56 +02:00
if ( start ( ) )
2011-02-04 16:58:14 +02:00
t - > setVisitingHero ( h ) ;
2009-03-07 17:55:56 +02:00
else
2011-02-04 16:58:14 +02:00
t - > setVisitingHero ( NULL ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void ChangeSpells : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * hero = gs - > getHero ( hid ) ;
if ( learn )
BOOST_FOREACH ( ui32 sid , spells )
2011-01-22 05:43:20 +02:00
hero - > spells . insert ( sid ) ;
2009-03-07 17:55:56 +02:00
else
BOOST_FOREACH ( ui32 sid , spells )
2011-01-22 05:43:20 +02:00
hero - > spells . erase ( sid ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetMana : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * hero = gs - > getHero ( hid ) ;
2011-12-14 00:23:17 +03:00
vstd : : amax ( val , 0 ) ; //not less than 0
2009-03-07 17:55:56 +02:00
hero - > mana = val ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetMovePoints : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * hero = gs - > getHero ( hid ) ;
hero - > movement = val ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void FoWChange : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2010-08-03 15:34:06 +03:00
TeamState * team = gs - > getPlayerTeam ( player ) ;
BOOST_FOREACH ( int3 t , tiles )
team - > fogOfWarMap [ t . x ] [ t . y ] [ t . z ] = mode ;
2010-06-06 09:05:39 +03:00
if ( mode = = 0 ) //do not hide too much
{
2011-01-20 19:25:15 +02:00
boost : : unordered_set < int3 , ShashInt3 > tilesRevealed ;
2010-06-06 09:05:39 +03:00
for ( size_t i = 0 ; i < gs - > map - > objects . size ( ) ; i + + )
{
2010-08-03 15:34:06 +03:00
if ( gs - > map - > objects [ i ] )
2010-06-06 09:05:39 +03:00
{
switch ( gs - > map - > objects [ i ] - > ID )
{
case 34 : //hero
case 53 : //mine
case 98 : //town
case 220 :
2010-08-19 14:03:33 +03:00
if ( vstd : : contains ( team - > players , gs - > map - > objects [ i ] - > tempOwner ) ) //check owned observators
2010-08-03 15:34:06 +03:00
gs - > map - > objects [ i ] - > getSightTiles ( tilesRevealed ) ;
2010-06-06 09:05:39 +03:00
break ;
}
}
}
BOOST_FOREACH ( int3 t , tilesRevealed ) //probably not the most optimal solution ever
2010-08-03 15:34:06 +03:00
team - > fogOfWarMap [ t . x ] [ t . y ] [ t . z ] = 1 ;
2010-06-06 09:05:39 +03:00
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetAvailableHeroes : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2010-07-08 08:52:11 +03:00
PlayerState * p = gs - > getPlayer ( player ) ;
p - > availableHeroes . clear ( ) ;
2009-03-07 17:55:56 +02:00
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : AVAILABLE_HEROES_PER_PLAYER ; i + + )
2009-03-07 17:55:56 +02:00
{
2010-12-26 16:34:11 +02:00
CGHeroInstance * h = ( hid [ i ] > = 0 ? ( CGHeroInstance * ) gs - > hpool . heroesPool [ hid [ i ] ] : NULL ) ;
2010-07-08 08:52:11 +03:00
if ( h & & army [ i ] )
2011-01-28 04:11:58 +02:00
h - > setToArmy ( army [ i ] ) ;
2010-07-08 08:52:11 +03:00
p - > availableHeroes . push_back ( h ) ;
2009-03-07 17:55:56 +02:00
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void GiveBonus : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2010-11-19 00:06:56 +02:00
CBonusSystemNode * cbsn = NULL ;
2010-02-10 04:56:00 +02:00
switch ( who )
{
case HERO :
2010-11-19 00:06:56 +02:00
cbsn = gs - > getHero ( id ) ;
2010-02-10 04:56:00 +02:00
break ;
case PLAYER :
2010-11-19 00:06:56 +02:00
cbsn = gs - > getPlayer ( id ) ;
2010-02-10 04:56:00 +02:00
break ;
2010-06-07 08:28:12 +03:00
case TOWN :
2010-11-19 00:06:56 +02:00
cbsn = gs - > getTown ( id ) ;
break ;
2010-02-10 04:56:00 +02:00
}
2009-04-21 01:57:07 +03:00
2010-11-19 00:06:56 +02:00
assert ( cbsn ) ;
Bonus * b = new Bonus ( bonus ) ;
cbsn - > addNewBonus ( b ) ;
std : : string & descr = b - > description ;
2009-04-21 01:57:07 +03:00
2009-07-09 22:15:22 +03:00
if ( ! bdescr . message . size ( )
2010-05-02 21:20:26 +03:00
& & bonus . source = = Bonus : : OBJECT
& & ( bonus . type = = Bonus : : LUCK | | bonus . type = = Bonus : : MORALE )
2011-12-14 00:23:17 +03:00
& & gs - > map - > objects [ bonus . sid ] - > ID = = GameConstants : : EVENTI_TYPE ) //it's morale/luck bonus from an event without description
2009-04-21 01:57:07 +03:00
{
descr = VLC - > generaltexth - > arraytxt [ bonus . val > 0 ? 110 : 109 ] ; //+/-%d Temporary until next battle"
boost : : replace_first ( descr , " %d " , boost : : lexical_cast < std : : string > ( std : : abs ( bonus . val ) ) ) ;
}
else
{
2009-07-09 22:15:22 +03:00
bdescr . toString ( descr ) ;
2009-04-21 01:57:07 +03:00
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void ChangeObjPos : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGObjectInstance * obj = gs - > map - > objects [ objid ] ;
if ( ! obj )
{
tlog1 < < " Wrong ChangeObjPos: object " < < objid < < " doesn't exist! \n " ;
return ;
}
gs - > map - > removeBlockVisTiles ( obj ) ;
obj - > pos = nPos ;
gs - > map - > addBlockVisTiles ( obj ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void PlayerEndsGame : : applyGs ( CGameState * gs )
2010-01-29 22:52:45 +02:00
{
PlayerState * p = gs - > getPlayer ( player ) ;
p - > status = victory ? 2 : 1 ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void RemoveBonus : : applyGs ( CGameState * gs )
2010-02-10 04:56:00 +02:00
{
2011-07-13 21:39:02 +03:00
CBonusSystemNode * node ;
if ( who = = HERO )
node = gs - > getHero ( whoID ) ;
else
node = gs - > getPlayer ( whoID ) ;
2010-02-10 04:56:00 +02:00
2011-07-13 21:39:02 +03:00
BonusList & bonuses = node - > getBonusList ( ) ;
for ( int i = 0 ; i < bonuses . size ( ) ; i + + )
2010-02-10 04:56:00 +02:00
{
2011-07-13 21:39:02 +03:00
Bonus * b = bonuses [ i ] ;
if ( b - > source = = source & & b - > sid = = id )
2010-02-10 04:56:00 +02:00
{
2011-07-13 21:39:02 +03:00
bonus = * b ; //backup bonus (to show to interfaces later)
2011-07-16 16:57:25 +03:00
bonuses . erase ( i ) ;
2010-02-10 04:56:00 +02:00
break ;
}
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void RemoveObject : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGObjectInstance * obj = gs - > map - > objects [ id ] ;
2010-02-11 17:51:26 +02:00
//unblock tiles
if ( obj - > defInfo )
{
gs - > map - > removeBlockVisTiles ( obj ) ;
}
2011-12-14 00:23:17 +03:00
if ( obj - > ID = = GameConstants : : HEROI_TYPE )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * h = static_cast < CGHeroInstance * > ( obj ) ;
2011-02-12 18:12:48 +02:00
PlayerState * p = gs - > getPlayer ( h - > tempOwner ) ;
2011-02-11 14:27:38 +02:00
gs - > map - > heroes - = h ;
2011-02-12 18:12:48 +02:00
p - > heroes - = h ;
2011-02-22 11:47:25 +02:00
h - > detachFrom ( h - > whereShouldBeAttached ( gs ) ) ;
2010-01-29 22:52:45 +02:00
h - > tempOwner = 255 ; //no one owns beaten hero
2011-02-22 11:47:25 +02:00
if ( h - > visitedTown )
2009-03-07 17:55:56 +02:00
{
if ( h - > inTownGarrison )
2011-02-22 11:47:25 +02:00
h - > visitedTown - > garrisonHero = NULL ;
2009-03-07 17:55:56 +02:00
else
2011-02-22 11:47:25 +02:00
h - > visitedTown - > visitingHero = NULL ;
2009-03-07 17:55:56 +02:00
h - > visitedTown = NULL ;
}
2010-07-08 08:52:11 +03:00
//return hero to the pool, so he may reappear in tavern
gs - > hpool . heroesPool [ h - > subID ] = h ;
if ( ! vstd : : contains ( gs - > hpool . pavailable , h - > subID ) )
gs - > hpool . pavailable [ h - > subID ] = 0xff ;
2011-01-18 20:56:14 +02:00
2011-02-11 14:27:38 +02:00
gs - > map - > objects [ id ] = NULL ;
2011-01-18 20:56:14 +02:00
return ;
2009-03-07 17:55:56 +02:00
}
2011-02-11 14:27:38 +02:00
// else if (obj->ID==CREI_TYPE && gs->map->version > CMapHeader::RoE) //only fixed monsters can be a part of quest
// {
// CGCreature *cre = static_cast<CGCreature*>(obj);
// gs->map->monsters[cre->identifier]->pos = int3 (-1,-1,-1); //use nonexistent monster for quest :>
// }
2010-12-26 16:34:11 +02:00
gs - > map - > objects [ id ] . dellNull ( ) ;
2009-03-07 17:55:56 +02:00
}
2009-07-18 06:13:13 +03:00
static int getDir ( int3 src , int3 dst )
{
int ret = - 1 ;
if ( dst . x + 1 = = src . x & & dst . y + 1 = = src . y ) //tl
{
ret = 1 ;
}
else if ( dst . x = = src . x & & dst . y + 1 = = src . y ) //t
{
ret = 2 ;
}
else if ( dst . x - 1 = = src . x & & dst . y + 1 = = src . y ) //tr
{
ret = 3 ;
}
else if ( dst . x - 1 = = src . x & & dst . y = = src . y ) //r
{
ret = 4 ;
}
else if ( dst . x - 1 = = src . x & & dst . y - 1 = = src . y ) //br
{
ret = 5 ;
}
else if ( dst . x = = src . x & & dst . y - 1 = = src . y ) //b
{
ret = 6 ;
}
else if ( dst . x + 1 = = src . x & & dst . y - 1 = = src . y ) //bl
{
ret = 7 ;
}
else if ( dst . x + 1 = = src . x & & dst . y = = src . y ) //l
{
ret = 8 ;
}
return ret ;
}
2009-03-07 17:55:56 +02:00
void TryMoveHero : : applyGs ( CGameState * gs )
{
CGHeroInstance * h = gs - > getHero ( id ) ;
h - > movement = movePoints ;
2009-07-19 04:00:19 +03:00
2010-05-06 15:13:31 +03:00
if ( ( result = = SUCCESS | | result = = BLOCKING_VISIT | | result = = EMBARK | | result = = DISEMBARK ) & & start ! = end ) {
2009-07-19 06:10:24 +03:00
h - > moveDir = getDir ( start , end ) ;
2010-05-06 15:13:31 +03:00
}
2009-07-19 06:10:24 +03:00
2009-07-19 04:00:19 +03:00
if ( result = = EMBARK ) //hero enters boat at dest tile
{
const TerrainTile & tt = gs - > map - > getTile ( CGHeroInstance : : convertPosition ( end , false ) ) ;
2011-04-23 01:28:13 +03:00
assert ( tt . visitableObjects . size ( ) > = 1 & & tt . visitableObjects . back ( ) - > ID = = 8 ) ; //the only vis obj at dest is Boat
CGBoat * boat = static_cast < CGBoat * > ( tt . visitableObjects . back ( ) ) ;
2009-07-19 04:00:19 +03:00
gs - > map - > removeBlockVisTiles ( boat ) ; //hero blockvis mask will be used, we don't need to duplicate it with boat
h - > boat = boat ;
boat - > hero = h ;
}
2009-07-19 06:10:24 +03:00
else if ( result = = DISEMBARK ) //hero leaves boat to dest tile
{
2010-07-20 21:34:32 +03:00
CGBoat * b = const_cast < CGBoat * > ( h - > boat ) ;
b - > direction = h - > moveDir ;
b - > pos = start ;
b - > hero = NULL ;
gs - > map - > addBlockVisTiles ( b ) ;
2009-07-19 06:10:24 +03:00
h - > boat = NULL ;
}
2009-07-19 04:00:19 +03:00
2009-07-19 06:10:24 +03:00
if ( start ! = end & & ( result = = SUCCESS | | result = = TELEPORTATION | | result = = EMBARK | | result = = DISEMBARK ) )
2009-03-07 17:55:56 +02:00
{
gs - > map - > removeBlockVisTiles ( h ) ;
h - > pos = end ;
2010-07-20 21:34:32 +03:00
if ( CGBoat * b = const_cast < CGBoat * > ( h - > boat ) )
b - > pos = end ;
2009-03-07 17:55:56 +02:00
gs - > map - > addBlockVisTiles ( h ) ;
}
2009-07-18 06:13:13 +03:00
2009-03-07 17:55:56 +02:00
BOOST_FOREACH ( int3 t , fowRevealed )
2010-08-03 15:34:06 +03:00
gs - > getPlayerTeam ( h - > getOwner ( ) ) - > fogOfWarMap [ t . x ] [ t . y ] [ t . z ] = 1 ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void NewStructures : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2009-08-23 18:02:21 +03:00
CGTownInstance * t = gs - > getTown ( tid ) ;
2009-03-07 17:55:56 +02:00
BOOST_FOREACH ( si32 id , bid )
2009-08-23 18:02:21 +03:00
{
2009-03-07 17:55:56 +02:00
t - > builtBuildings . insert ( id ) ;
2009-08-23 18:02:21 +03:00
}
2009-03-07 17:55:56 +02:00
t - > builded = builded ;
2011-02-04 16:58:14 +02:00
t - > recreateBuildingsBonuses ( ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void RazeStructures : : applyGs ( CGameState * gs )
2009-09-22 17:27:46 +03:00
{
CGTownInstance * t = gs - > getTown ( tid ) ;
BOOST_FOREACH ( si32 id , bid )
{
t - > builtBuildings . erase ( id ) ;
}
2009-09-24 20:54:02 +03:00
t - > destroyed = destroyed ; //yeaha
2011-02-04 16:58:14 +02:00
t - > recreateBuildingsBonuses ( ) ;
2009-09-22 17:27:46 +03:00
}
2011-02-04 16:58:14 +02:00
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetAvailableCreatures : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2010-12-19 00:11:28 +02:00
CGDwelling * dw = dynamic_cast < CGDwelling * > ( gs - > map - > objects [ tid ] . get ( ) ) ;
2009-07-26 13:43:22 +03:00
assert ( dw ) ;
dw - > creatures = creatures ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetHeroesInTown : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGTownInstance * t = gs - > getTown ( tid ) ;
CGHeroInstance * v = gs - > getHero ( visiting ) ,
* g = gs - > getHero ( garrison ) ;
2011-02-04 16:58:14 +02:00
bool newVisitorComesFromGarrison = v & & v = = t - > garrisonHero ;
bool newGarrisonComesFromVisiting = g & & g = = t - > visitingHero ;
if ( newVisitorComesFromGarrison )
t - > setGarrisonedHero ( NULL ) ;
if ( newGarrisonComesFromVisiting )
t - > setVisitingHero ( NULL ) ;
if ( ! newGarrisonComesFromVisiting | | v )
t - > setVisitingHero ( v ) ;
if ( ! newVisitorComesFromGarrison | | g )
t - > setGarrisonedHero ( g ) ;
2009-03-07 17:55:56 +02:00
if ( v )
{
gs - > map - > addBlockVisTiles ( v ) ;
}
if ( g )
{
gs - > map - > removeBlockVisTiles ( g ) ;
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void HeroRecruited : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2009-08-05 03:05:37 +03:00
assert ( vstd : : contains ( gs - > hpool . heroesPool , hid ) ) ;
2009-03-07 17:55:56 +02:00
CGHeroInstance * h = gs - > hpool . heroesPool [ hid ] ;
CGTownInstance * t = gs - > getTown ( tid ) ;
2011-02-04 16:58:14 +02:00
PlayerState * p = gs - > getPlayer ( player ) ;
2009-03-07 17:55:56 +02:00
h - > setOwner ( player ) ;
h - > pos = tile ;
h - > movement = h - > maxMovePoints ( true ) ;
gs - > hpool . heroesPool . erase ( hid ) ;
if ( h - > id < 0 )
{
h - > id = gs - > map - > objects . size ( ) ;
gs - > map - > objects . push_back ( h ) ;
}
else
gs - > map - > objects [ h - > id ] = h ;
h - > initHeroDefInfo ( ) ;
gs - > map - > heroes . push_back ( h ) ;
2011-02-04 16:58:14 +02:00
p - > heroes . push_back ( h ) ;
h - > attachTo ( p ) ;
2009-08-01 13:08:16 +03:00
h - > initObj ( ) ;
2009-03-07 17:55:56 +02:00
gs - > map - > addBlockVisTiles ( h ) ;
2010-07-09 02:03:27 +03:00
if ( t )
{
2011-02-04 16:58:14 +02:00
t - > setVisitingHero ( h ) ;
2010-07-09 02:03:27 +03:00
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void GiveHero : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGHeroInstance * h = gs - > getHero ( id ) ;
2012-01-03 04:55:26 +03:00
//bonus system
h - > detachFrom ( & gs - > globalEffects ) ;
h - > attachTo ( gs - > getPlayer ( player ) ) ;
2009-03-07 17:55:56 +02:00
gs - > map - > removeBlockVisTiles ( h , true ) ;
h - > setOwner ( player ) ;
h - > movement = h - > maxMovePoints ( true ) ;
h - > initHeroDefInfo ( ) ;
gs - > map - > heroes . push_back ( h ) ;
2009-03-09 12:37:49 +02:00
gs - > getPlayer ( h - > getOwner ( ) ) - > heroes . push_back ( h ) ;
2009-03-07 17:55:56 +02:00
gs - > map - > addBlockVisTiles ( h ) ;
h - > inTownGarrison = false ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void NewObject : : applyGs ( CGameState * gs )
2009-07-26 06:33:13 +03:00
{
CGObjectInstance * o = NULL ;
switch ( ID )
{
case 8 :
o = new CGBoat ( ) ;
break ;
2010-08-22 10:11:46 +03:00
case 54 : //probably more options will be needed
o = new CGCreature ( ) ;
{
2010-11-22 02:34:46 +02:00
//CStackInstance hlp;
2010-08-22 10:11:46 +03:00
CGCreature * cre = static_cast < CGCreature * > ( o ) ;
2010-11-22 02:34:46 +02:00
//cre->slots[0] = hlp;
2010-08-22 10:11:46 +03:00
cre - > notGrowingTeam = cre - > neverFlees = 0 ;
cre - > character = 2 ;
cre - > gainedArtifact = - 1 ;
2011-05-28 04:02:28 +03:00
cre - > identifier = - 1 ;
2011-06-25 17:22:19 +03:00
cre - > addToSlot ( 0 , new CStackInstance ( subID , - 1 ) ) ; //add placeholder stack
2010-08-22 10:11:46 +03:00
}
break ;
2009-07-26 06:33:13 +03:00
default :
o = new CGObjectInstance ( ) ;
break ;
}
o - > ID = ID ;
o - > subID = subID ;
o - > pos = pos ;
o - > defInfo = VLC - > dobjinfo - > gobjs [ ID ] [ subID ] ;
id = o - > id = gs - > map - > objects . size ( ) ;
o - > hoverName = VLC - > generaltexth - > names [ ID ] ;
2010-08-22 10:11:46 +03:00
switch ( ID )
2010-02-21 17:03:30 +02:00
{
2010-08-22 10:11:46 +03:00
case 54 : //cfreature
o - > defInfo = VLC - > dobjinfo - > gobjs [ ID ] [ subID ] ;
assert ( o - > defInfo ) ;
break ;
case 124 : //hole
const TerrainTile & t = gs - > map - > getTile ( pos ) ;
o - > defInfo = VLC - > dobjinfo - > gobjs [ ID ] [ t . tertype ] ;
assert ( o - > defInfo ) ;
break ;
2010-02-21 17:03:30 +02:00
}
2009-07-26 06:33:13 +03:00
gs - > map - > objects . push_back ( o ) ;
gs - > map - > addBlockVisTiles ( o ) ;
o - > initObj ( ) ;
assert ( o - > defInfo ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void NewArtifact : : applyGs ( CGameState * gs )
2010-11-10 02:06:25 +02:00
{
2010-12-26 16:34:11 +02:00
assert ( ! vstd : : contains ( gs - > map - > artInstances , art ) ) ;
2011-01-22 05:43:20 +02:00
gs - > map - > addNewArtifactInstance ( art ) ;
2010-12-26 16:34:11 +02:00
2011-07-13 21:39:02 +03:00
assert ( ! art - > getParentNodes ( ) . size ( ) ) ;
2011-01-18 20:56:14 +02:00
art - > setType ( art - > artType ) ;
2011-06-21 12:31:08 +03:00
if ( CCombinedArtifactInstance * cart = dynamic_cast < CCombinedArtifactInstance * > ( art . get ( ) ) )
cart - > createConstituents ( ) ;
2010-11-10 02:06:25 +02:00
}
2009-07-26 06:33:13 +03:00
2011-12-14 00:23:17 +03:00
DLL_LINKAGE const CStackInstance * StackLocation : : getStack ( )
2010-12-14 23:55:23 +02:00
{
if ( ! army - > hasStackAtSlot ( slot ) )
{
tlog2 < < " Warning: " < < army - > nodeName ( ) < < " dont have a stack at slot " < < slot < < std : : endl ;
return NULL ;
}
return & army - > getStack ( slot ) ;
}
2012-04-14 05:20:22 +03:00
struct ObjectRetriever : boost : : static_visitor < const CArmedInstance * >
{
const CArmedInstance * operator ( ) ( const ConstTransitivePtr < CGHeroInstance > & h ) const
{
return h ;
}
const CArmedInstance * operator ( ) ( const ConstTransitivePtr < CStackInstance > & s ) const
{
return s - > armyObj ;
}
} ;
template < typename T >
struct GetBase : boost : : static_visitor < T * >
{
template < typename TArg >
T * operator ( ) ( TArg & arg ) const
{
return arg ;
}
} ;
DLL_LINKAGE const CArmedInstance * ArtifactLocation : : relatedObj ( ) const
{
return boost : : apply_visitor ( ObjectRetriever ( ) , artHolder ) ;
}
DLL_LINKAGE int ArtifactLocation : : owningPlayer ( ) const
{
auto obj = relatedObj ( ) ;
return obj ? obj - > tempOwner : GameConstants : : NEUTRAL_PLAYER ;
}
DLL_LINKAGE CArtifactSet * ArtifactLocation : : getHolderArtSet ( )
{
return boost : : apply_visitor ( GetBase < CArtifactSet > ( ) , artHolder ) ;
}
DLL_LINKAGE CBonusSystemNode * ArtifactLocation : : getHolderNode ( )
{
return boost : : apply_visitor ( GetBase < CBonusSystemNode > ( ) , artHolder ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE const CArtifactInstance * ArtifactLocation : : getArt ( ) const
2010-12-26 16:34:11 +02:00
{
const ArtSlotInfo * s = getSlot ( ) ;
2010-12-29 23:04:22 +02:00
if ( s & & s - > artifact )
{
if ( ! s - > locked )
return s - > artifact ;
else
{
tlog3 < < " ArtifactLocation::getArt: That location is locked! \n " ;
return NULL ;
}
}
return NULL ;
2010-12-26 16:34:11 +02:00
}
2012-04-14 05:20:22 +03:00
DLL_LINKAGE const CArtifactSet * ArtifactLocation : : getHolderArtSet ( ) const
{
ArtifactLocation * t = const_cast < ArtifactLocation * > ( this ) ;
return t - > getHolderArtSet ( ) ;
}
DLL_LINKAGE const CBonusSystemNode * ArtifactLocation : : getHolderNode ( ) const
{
ArtifactLocation * t = const_cast < ArtifactLocation * > ( this ) ;
return t - > getHolderNode ( ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE CArtifactInstance * ArtifactLocation : : getArt ( )
2010-12-26 16:34:11 +02:00
{
const ArtifactLocation * t = this ;
return const_cast < CArtifactInstance * > ( t - > getArt ( ) ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE const ArtSlotInfo * ArtifactLocation : : getSlot ( ) const
2010-12-26 16:34:11 +02:00
{
2012-04-14 05:20:22 +03:00
return getHolderArtSet ( ) - > getSlot ( slot ) ;
2010-12-26 16:34:11 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void ChangeStackCount : : applyGs ( CGameState * gs )
2010-11-27 03:46:19 +02:00
{
if ( absoluteValue )
sl . army - > setStackCount ( sl . slot , count ) ;
else
sl . army - > changeStackCount ( sl . slot , count ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetStackType : : applyGs ( CGameState * gs )
2010-11-27 03:46:19 +02:00
{
sl . army - > setStackType ( sl . slot , type ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void EraseStack : : applyGs ( CGameState * gs )
2010-11-27 03:46:19 +02:00
{
sl . army - > eraseStack ( sl . slot ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SwapStacks : : applyGs ( CGameState * gs )
2010-11-27 03:46:19 +02:00
{
2010-11-27 22:17:28 +02:00
CStackInstance * s1 = sl1 . army - > detachStack ( sl1 . slot ) ,
* s2 = sl2 . army - > detachStack ( sl2 . slot ) ;
2010-11-27 03:46:19 +02:00
2010-11-27 22:17:28 +02:00
sl2 . army - > putStack ( sl2 . slot , s1 ) ;
sl1 . army - > putStack ( sl1 . slot , s2 ) ;
2010-11-27 03:46:19 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void InsertNewStack : : applyGs ( CGameState * gs )
2010-11-27 03:46:19 +02:00
{
2010-12-06 01:10:02 +02:00
CStackInstance * s = new CStackInstance ( stack . type , stack . count ) ;
sl . army - > putStack ( sl . slot , s ) ;
2010-11-27 03:46:19 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void RebalanceStacks : : applyGs ( CGameState * gs )
2010-11-27 03:46:19 +02:00
{
2010-12-06 01:10:02 +02:00
const CCreature * srcType = src . army - > getCreature ( src . slot ) ;
TQuantity srcCount = src . army - > getStackCount ( src . slot ) ;
if ( srcCount = = count ) //moving whole stack
{
if ( const CCreature * c = dst . army - > getCreature ( dst . slot ) ) //stack at dest -> merge
{
assert ( c = = srcType ) ;
2011-12-14 00:23:17 +03:00
if ( GameConstants : : STACK_EXP )
2011-03-27 12:31:14 +03:00
{
ui64 totalExp = srcCount * src . army - > getStackExperience ( src . slot ) + dst . army - > getStackCount ( dst . slot ) * dst . army - > getStackExperience ( dst . slot ) ;
src . army - > eraseStack ( src . slot ) ;
dst . army - > changeStackCount ( dst . slot , count ) ;
dst . army - > setStackExp ( dst . slot , totalExp / ( dst . army - > getStackCount ( dst . slot ) ) ) ; //mean
}
else
{
src . army - > eraseStack ( src . slot ) ;
dst . army - > changeStackCount ( dst . slot , count ) ;
}
2010-12-06 01:10:02 +02:00
}
2011-03-27 12:31:14 +03:00
else //move stack to an empty slot, no exp change needed
2010-12-06 01:10:02 +02:00
{
CStackInstance * stackDetached = src . army - > detachStack ( src . slot ) ;
dst . army - > putStack ( dst . slot , stackDetached ) ;
}
}
else
{
if ( const CCreature * c = dst . army - > getCreature ( dst . slot ) ) //stack at dest -> rebalance
{
assert ( c = = srcType ) ;
2011-12-14 00:23:17 +03:00
if ( GameConstants : : STACK_EXP )
2011-03-27 12:31:14 +03:00
{
ui64 totalExp = srcCount * src . army - > getStackExperience ( src . slot ) + dst . army - > getStackCount ( dst . slot ) * dst . army - > getStackExperience ( dst . slot ) ;
src . army - > changeStackCount ( src . slot , - count ) ;
dst . army - > changeStackCount ( dst . slot , count ) ;
dst . army - > setStackExp ( dst . slot , totalExp / ( src . army - > getStackCount ( src . slot ) + dst . army - > getStackCount ( dst . slot ) ) ) ; //mean
}
else
{
src . army - > changeStackCount ( src . slot , - count ) ;
dst . army - > changeStackCount ( dst . slot , count ) ;
}
2010-12-06 01:10:02 +02:00
}
else //split stack to an empty slot
{
src . army - > changeStackCount ( src . slot , - count ) ;
dst . army - > addToSlot ( dst . slot , srcType - > idNumber , count , false ) ;
2011-12-14 00:23:17 +03:00
if ( GameConstants : : STACK_EXP )
2011-03-27 12:31:14 +03:00
dst . army - > setStackExp ( dst . slot , src . army - > getStackExperience ( src . slot ) ) ;
2010-12-06 01:10:02 +02:00
}
}
2012-03-06 19:59:55 +03:00
CBonusSystemNode : : treeHasChanged ( ) ;
2010-11-27 03:46:19 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void PutArtifact : : applyGs ( CGameState * gs )
2010-12-26 16:34:11 +02:00
{
assert ( art - > canBePutAt ( al ) ) ;
2012-04-14 05:20:22 +03:00
art - > putAt ( al ) ;
//al.hero->putArtifact(al.slot, art);
2010-12-26 16:34:11 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void EraseArtifact : : applyGs ( CGameState * gs )
2010-12-26 16:34:11 +02:00
{
CArtifactInstance * a = al . getArt ( ) ;
assert ( a ) ;
2012-04-14 05:20:22 +03:00
a - > removeFrom ( al ) ;
2010-12-26 16:34:11 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void MoveArtifact : : applyGs ( CGameState * gs )
2010-12-26 16:34:11 +02:00
{
2011-01-06 22:00:19 +02:00
CArtifactInstance * a = src . getArt ( ) ;
2011-12-14 00:23:17 +03:00
if ( dst . slot < GameConstants : : BACKPACK_START )
2011-01-15 04:17:56 +02:00
assert ( ! dst . getArt ( ) ) ;
2011-01-22 05:43:20 +02:00
2011-01-15 19:58:08 +02:00
a - > move ( src , dst ) ;
2012-02-17 22:30:40 +03:00
//TODO what'll happen if Titan's thunder is equiped by pickin git up or the start of game?
2012-04-14 05:20:22 +03:00
if ( a - > artType - > id = = 135 & & dst . slot = = ArtifactPosition : : RIGHT_HAND ) //Titan's Thunder creates new spellbook on equip
{
auto hPtr = boost : : get < ConstTransitivePtr < CGHeroInstance > > ( & dst . artHolder ) ;
if ( hPtr )
{
CGHeroInstance * h = * hPtr ;
if ( h & & ! h - > hasSpellbook ( ) )
gs - > giveHeroArtifact ( h , 0 ) ;
}
}
2010-12-26 16:34:11 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void AssembledArtifact : : applyGs ( CGameState * gs )
2011-01-22 05:43:20 +02:00
{
2012-04-14 05:20:22 +03:00
CArtifactSet * artSet = al . getHolderArtSet ( ) ;
2011-01-22 05:43:20 +02:00
const CArtifactInstance * transformedArt = al . getArt ( ) ;
assert ( transformedArt ) ;
2012-04-14 05:20:22 +03:00
assert ( vstd : : contains ( transformedArt - > assemblyPossibilities ( artSet ) , builtArt ) ) ;
2011-01-22 05:43:20 +02:00
CCombinedArtifactInstance * combinedArt = new CCombinedArtifactInstance ( builtArt ) ;
2011-01-28 04:11:58 +02:00
gs - > map - > addNewArtifactInstance ( combinedArt ) ;
2011-09-24 04:15:36 +03:00
//retrieve all constituents
2011-01-22 05:43:20 +02:00
BOOST_FOREACH ( si32 constituentID , * builtArt - > constituents )
{
2012-04-14 05:20:22 +03:00
int pos = artSet - > getArtPos ( constituentID ) ;
2011-01-22 05:43:20 +02:00
assert ( pos > = 0 ) ;
2012-04-14 05:20:22 +03:00
CArtifactInstance * constituentInstance = artSet - > getArt ( pos ) ;
2011-01-22 05:43:20 +02:00
//move constituent from hero to be part of new, combined artifact
2012-04-14 05:20:22 +03:00
constituentInstance - > removeFrom ( al ) ;
2011-01-22 05:43:20 +02:00
combinedArt - > addAsConstituent ( constituentInstance , pos ) ;
2012-04-14 05:20:22 +03:00
if ( ! vstd : : contains ( combinedArt - > artType - > possibleSlots [ artSet - > bearerType ( ) ] , al . slot ) & & vstd : : contains ( combinedArt - > artType - > possibleSlots [ artSet - > bearerType ( ) ] , pos ) )
2011-01-28 04:11:58 +02:00
al . slot = pos ;
2011-01-22 05:43:20 +02:00
}
//put new combined artifacts
2012-04-14 05:20:22 +03:00
combinedArt - > putAt ( al ) ;
2011-01-22 05:43:20 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void DisassembledArtifact : : applyGs ( CGameState * gs )
2011-01-22 05:43:20 +02:00
{
2011-01-24 01:49:17 +02:00
CCombinedArtifactInstance * disassembled = dynamic_cast < CCombinedArtifactInstance * > ( al . getArt ( ) ) ;
assert ( disassembled ) ;
std : : vector < CCombinedArtifactInstance : : ConstituentInfo > constituents = disassembled - > constituentsInfo ;
2012-04-14 05:20:22 +03:00
disassembled - > removeFrom ( al ) ;
2011-01-24 01:49:17 +02:00
BOOST_FOREACH ( CCombinedArtifactInstance : : ConstituentInfo & ci , constituents )
{
2012-04-14 05:20:22 +03:00
ArtifactLocation constituentLoc = al ;
constituentLoc . slot = ( ci . slot > = 0 ? ci . slot : al . slot ) ; //-1 is slot of main constituent -> it'll replace combined artifact in its pos
2011-01-28 04:11:58 +02:00
disassembled - > detachFrom ( ci . art ) ;
2012-04-14 05:20:22 +03:00
ci . art - > putAt ( constituentLoc ) ;
2011-01-24 01:49:17 +02:00
}
2011-01-28 04:11:58 +02:00
gs - > map - > eraseArtifactInstance ( disassembled ) ;
2011-01-22 05:43:20 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void HeroVisit : : applyGs ( CGameState * gs )
2011-05-10 01:20:47 +03:00
{
if ( starting )
gs - > ongoingVisits [ hero ] = obj ;
else
gs - > ongoingVisits . erase ( hero ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetAvailableArtifacts : : applyGs ( CGameState * gs )
2010-06-26 19:02:10 +03:00
{
if ( id > = 0 )
{
2010-12-19 00:11:28 +02:00
if ( CGBlackMarket * bm = dynamic_cast < CGBlackMarket * > ( gs - > map - > objects [ id ] . get ( ) ) )
2010-06-26 19:02:10 +03:00
{
bm - > artifacts = arts ;
}
else
{
tlog1 < < " Wrong black market id! " < < std : : endl ;
}
}
else
{
CGTownInstance : : merchantArtifacts = arts ;
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void NewTurn : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
gs - > day = day ;
BOOST_FOREACH ( NewTurn : : Hero h , heroes ) //give mana/movement point
{
2009-04-04 01:34:31 +03:00
CGHeroInstance * hero = gs - > getHero ( h . id ) ;
hero - > movement = h . move ;
hero - > mana = h . mana ;
2009-03-07 17:55:56 +02:00
}
2011-07-05 09:14:07 +03:00
for ( std : : map < ui8 , TResources > : : iterator i = res . begin ( ) ; i ! = res . end ( ) ; i + + )
2009-11-28 03:42:08 +02:00
{
2011-12-14 00:23:17 +03:00
assert ( i - > first < GameConstants : : PLAYER_LIMIT ) ;
2011-07-05 09:14:07 +03:00
gs - > getPlayer ( i - > first ) - > resources = i - > second ;
2009-11-28 03:42:08 +02:00
}
2009-03-07 17:55:56 +02:00
BOOST_FOREACH ( SetAvailableCreatures h , cres ) //set available creatures in towns
h . applyGs ( gs ) ;
2011-08-26 23:32:05 +03:00
gs - > globalEffects . popBonuses ( Bonus : : OneDay ) ; //works for children -> all game objs
if ( gs - > getDate ( 1 ) ) //new week
gs - > globalEffects . popBonuses ( Bonus : : OneWeek ) ; //works for children -> all game objs
2010-08-24 17:26:57 +03:00
2011-08-26 23:32:05 +03:00
//TODO not really a single root hierarchy, what about bonuses placed elsewhere? [not an issue with H3 mechanics but in the future...]
2010-08-24 17:26:57 +03:00
2011-08-26 23:32:05 +03:00
//count days without town
for ( std : : map < ui8 , PlayerState > : : iterator i = gs - > players . begin ( ) ; i ! = gs - > players . end ( ) ; i + + )
2010-02-02 01:30:03 +02:00
{
2011-08-26 23:32:05 +03:00
if ( i - > second . towns . size ( ) | | gs - > day = = 1 )
i - > second . daysWithoutCastle = 0 ;
else
i - > second . daysWithoutCastle + + ;
2010-02-02 01:30:03 +02:00
}
2011-08-26 23:32:05 +03:00
BOOST_FOREACH ( CGTownInstance * t , gs - > map - > towns )
t - > builded = 0 ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetObjectProperty : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CGObjectInstance * obj = gs - > map - > objects [ id ] ;
if ( ! obj )
2009-08-22 16:59:15 +03:00
{
2009-03-07 17:55:56 +02:00
tlog1 < < " Wrong object ID - property cannot be set! \n " ;
2009-08-22 16:59:15 +03:00
return ;
}
2011-03-08 09:40:14 +02:00
CArmedInstance * cai = dynamic_cast < CArmedInstance * > ( obj ) ;
if ( what = = ObjProperty : : OWNER & & cai )
2009-08-22 16:59:15 +03:00
{
2011-12-14 00:23:17 +03:00
if ( obj - > ID = = GameConstants : : TOWNI_TYPE )
2011-02-21 06:13:00 +02:00
{
2011-03-08 09:40:14 +02:00
CGTownInstance * t = static_cast < CGTownInstance * > ( obj ) ;
2011-12-14 00:23:17 +03:00
if ( t - > tempOwner < GameConstants : : PLAYER_LIMIT )
2011-03-08 09:40:14 +02:00
gs - > getPlayer ( t - > tempOwner ) - > towns - = t ;
2011-12-14 00:23:17 +03:00
if ( val < GameConstants : : PLAYER_LIMIT )
2011-03-08 09:40:14 +02:00
gs - > getPlayer ( val ) - > towns . push_back ( t ) ;
2011-02-21 06:13:00 +02:00
}
2011-03-08 09:40:14 +02:00
CBonusSystemNode * nodeToMove = cai - > whatShouldBeAttached ( ) ;
nodeToMove - > detachFrom ( cai - > whereShouldBeAttached ( gs ) ) ;
obj - > setProperty ( what , val ) ;
nodeToMove - > attachTo ( cai - > whereShouldBeAttached ( gs ) ) ;
2009-08-22 16:59:15 +03:00
}
2011-03-08 09:40:14 +02:00
else //not an armed instance
2011-02-22 11:47:25 +02:00
{
obj - > setProperty ( what , val ) ;
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetHoverName : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2009-07-09 22:15:22 +03:00
name . toString ( gs - > map - > objects [ id ] - > hoverName ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void HeroLevelUp : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2010-07-08 22:10:26 +03:00
CGHeroInstance * h = gs - > getHero ( heroid ) ;
h - > level = level ;
//speciality
2010-07-13 22:55:13 +03:00
h - > UpdateSpeciality ( ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleStart : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
gs - > curB = info ;
2010-12-23 02:33:48 +02:00
gs - > curB - > localInit ( ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleNextRound : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2009-05-12 06:35:51 +03:00
gs - > curB - > castSpells [ 0 ] = gs - > curB - > castSpells [ 1 ] = 0 ;
2011-10-09 10:20:23 +03:00
for ( int i = 0 ; i < 2 ; + + i )
{
2011-12-14 00:23:17 +03:00
vstd : : amax ( - - gs - > curB - > enchanterCounter [ i ] , 0 ) ;
2011-10-09 10:20:23 +03:00
}
2009-03-07 17:55:56 +02:00
gs - > curB - > round = round ;
BOOST_FOREACH ( CStack * s , gs - > curB - > stacks )
{
2011-12-14 00:23:17 +03:00
s - > state - = EBattleStackState : : DEFENDING ;
s - > state - = EBattleStackState : : WAITING ;
s - > state - = EBattleStackState : : MOVED ;
s - > state - = EBattleStackState : : HAD_MORALE ;
s - > state - = EBattleStackState : : FEAR ;
2010-05-02 21:20:26 +03:00
s - > counterAttacks = 1 + s - > valOfBonuses ( Bonus : : ADDITIONAL_RETALIATION ) ;
2011-04-25 12:03:13 +03:00
// new turn effects
2011-02-21 06:13:00 +02:00
s - > battleTurnPassed ( ) ;
2009-03-07 17:55:56 +02:00
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleSetActiveStack : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
gs - > curB - > activeStack = stack ;
CStack * st = gs - > curB - > getStack ( stack ) ;
2011-01-18 19:23:31 +02:00
//remove bonuses that last until when stack gets new turn
2011-07-13 21:39:02 +03:00
st - > getBonusList ( ) . remove_if ( Bonus : : UntilGetsTurn ) ;
2011-01-18 19:23:31 +02:00
2011-12-14 00:23:17 +03:00
if ( vstd : : contains ( st - > state , EBattleStackState : : MOVED ) ) //if stack is moving second time this turn it must had a high morale bonus
st - > state . insert ( EBattleStackState : : HAD_MORALE ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleTriggerEffect : : applyGs ( CGameState * gs )
2011-10-08 16:02:58 +03:00
{
CStack * st = gs - > curB - > getStack ( stackID ) ;
switch ( effect )
{
case Bonus : : HP_REGENERATION :
st - > firstHPleft + = val ;
2011-12-14 00:23:17 +03:00
vstd : : amin ( st - > firstHPleft , ( ui32 ) st - > MaxHealth ( ) ) ;
2011-10-08 16:02:58 +03:00
break ;
case Bonus : : MANA_DRAIN :
{
CGHeroInstance * h = gs - > getHero ( additionalInfo ) ;
h - > mana - = val ;
2011-12-14 00:23:17 +03:00
vstd : : amax ( h - > mana , 0 ) ;
2011-10-08 16:02:58 +03:00
break ;
}
case Bonus : : POISON :
{
Bonus * b = st - > getBonus ( Selector : : source ( Bonus : : SPELL_EFFECT , 71 ) & & Selector : : type ( Bonus : : STACK_HEALTH ) ) ;
if ( b )
b - > val = val ;
break ;
}
case Bonus : : ENCHANTER :
2011-10-08 20:10:43 +03:00
break ;
2011-10-08 16:02:58 +03:00
case Bonus : : FEAR :
2011-12-14 00:23:17 +03:00
st - > state . insert ( EBattleStackState : : FEAR ) ;
2011-10-08 20:10:43 +03:00
break ;
2011-10-08 16:02:58 +03:00
default :
tlog2 < < " Unrecognized trigger effect type " < < type < < " \n " ;
}
}
2009-03-07 19:08:40 +02:00
void BattleResult : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2011-05-25 23:44:18 +03:00
//stack with SUMMONED flag but coming from garrison -> most likely resurrected, needs to be removed
BOOST_FOREACH ( CStack * s , gs - > curB - > stacks )
{
2011-12-14 00:23:17 +03:00
if ( s - > base & & s - > base - > armyObj & & vstd : : contains ( s - > state , EBattleStackState : : SUMMONED ) )
2011-05-25 23:44:18 +03:00
{
assert ( & s - > base - > armyObj - > getStack ( s - > slot ) = = s - > base ) ;
const_cast < CArmedInstance * > ( s - > base - > armyObj ) - > eraseStack ( s - > slot ) ;
}
}
2009-03-07 17:55:56 +02:00
for ( unsigned i = 0 ; i < gs - > curB - > stacks . size ( ) ; i + + )
delete gs - > curB - > stacks [ i ] ;
//remove any "until next battle" bonuses
CGHeroInstance * h ;
2009-10-06 03:32:33 +03:00
h = gs - > curB - > heroes [ 0 ] ;
2009-03-07 17:55:56 +02:00
if ( h )
2011-07-13 21:39:02 +03:00
h - > getBonusList ( ) . remove_if ( Bonus : : OneBattle ) ;
2009-10-06 03:32:33 +03:00
h = gs - > curB - > heroes [ 1 ] ;
2009-03-07 17:55:56 +02:00
if ( h )
2011-07-13 21:39:02 +03:00
h - > getBonusList ( ) . remove_if ( Bonus : : OneBattle ) ;
2009-03-07 17:55:56 +02:00
2011-12-14 00:23:17 +03:00
if ( GameConstants : : STACK_EXP )
2011-02-13 15:11:09 +02:00
{
if ( exp [ 0 ] ) //checking local array is easier than dereferencing this crap twice
gs - > curB - > belligerents [ 0 ] - > giveStackExp ( exp [ 0 ] ) ;
if ( exp [ 1 ] )
gs - > curB - > belligerents [ 1 ] - > giveStackExp ( exp [ 1 ] ) ;
2012-03-06 19:59:55 +03:00
CBonusSystemNode : : treeHasChanged ( ) ;
2011-02-13 15:11:09 +02:00
}
2010-05-02 21:20:26 +03:00
gs - > curB - > belligerents [ 0 ] - > battle = gs - > curB - > belligerents [ 1 ] - > battle = NULL ;
2010-12-26 16:34:11 +02:00
gs - > curB . dellNull ( ) ;
2009-03-07 17:55:56 +02:00
}
2009-03-07 19:08:40 +02:00
void BattleStackMoved : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2011-08-01 20:36:18 +03:00
gs - > curB - > getStack ( stack ) - > position = tilesToMove . back ( ) ;
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleStackAttacked : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CStack * at = gs - > curB - > getStack ( stackAttacked ) ;
2010-05-02 21:20:26 +03:00
at - > count = newAmount ;
2009-03-07 17:55:56 +02:00
at - > firstHPleft = newHP ;
2011-07-08 17:54:20 +03:00
2009-03-07 17:55:56 +02:00
if ( killed ( ) )
2011-07-08 17:54:20 +03:00
{
2011-12-14 00:23:17 +03:00
at - > state - = EBattleStackState : : ALIVE ;
2011-07-08 17:54:20 +03:00
}
2010-05-07 15:29:41 +03:00
//life drain handling
for ( int g = 0 ; g < healedStacks . size ( ) ; + + g )
{
healedStacks [ g ] . applyGs ( gs ) ;
}
2011-07-08 17:54:20 +03:00
if ( willRebirth ( ) )
{
at - > casts - - ;
2011-12-14 00:23:17 +03:00
at - > state . insert ( EBattleStackState : : ALIVE ) ; //hmm?
2011-07-08 17:54:20 +03:00
}
2012-02-18 20:39:47 +03:00
if ( cloneKilled ( ) )
{
BattleStacksRemoved bsr ; //remove body
bsr . stackIDs . insert ( at - > ID ) ;
bsr . applyGs ( gs ) ;
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleAttack : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CStack * attacker = gs - > curB - > getStack ( stackAttacking ) ;
if ( counter ( ) )
attacker - > counterAttacks - - ;
2010-05-20 13:54:24 +03:00
2009-03-07 17:55:56 +02:00
if ( shot ( ) )
2010-05-20 13:54:24 +03:00
{
//don't remove ammo if we have a working ammo cart
bool hasAmmoCart = false ;
BOOST_FOREACH ( const CStack * st , gs - > curB - > stacks )
{
2010-11-20 19:36:02 +02:00
if ( st - > owner = = attacker - > owner & & st - > getCreature ( ) - > idNumber = = 148 & & st - > alive ( ) )
2010-05-20 13:54:24 +03:00
{
hasAmmoCart = true ;
break ;
}
}
if ( ! hasAmmoCart )
{
attacker - > shots - - ;
}
}
2009-03-24 23:28:17 +02:00
BOOST_FOREACH ( BattleStackAttacked stackAttacked , bsa )
2009-03-21 14:49:58 +02:00
stackAttacked . applyGs ( gs ) ;
2009-08-07 14:22:17 +03:00
2011-07-13 21:39:02 +03:00
attacker - > getBonusList ( ) . remove_if ( Bonus : : UntilAttack ) ;
2009-08-07 14:22:17 +03:00
2010-02-20 15:24:38 +02:00
for ( std : : vector < BattleStackAttacked > : : const_iterator it = bsa . begin ( ) ; it ! = bsa . end ( ) ; + + it )
2009-08-07 14:22:17 +03:00
{
CStack * stack = gs - > curB - > getStack ( it - > stackAttacked , false ) ;
2012-02-18 20:39:47 +03:00
if ( stack ) //cloned stack is already gone
stack - > getBonusList ( ) . remove_if ( Bonus : : UntilBeingAttacked ) ;
2009-08-07 14:22:17 +03:00
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void StartAction : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
CStack * st = gs - > curB - > getStack ( ba . stackNumber ) ;
2009-09-10 14:28:34 +03:00
2011-02-12 18:12:48 +02:00
if ( ba . actionType = = BattleAction : : END_TACTIC_PHASE )
{
gs - > curB - > tacticDistance = 0 ;
return ;
}
2012-03-27 23:08:54 +03:00
if ( gs - > curB - > tacticDistance )
{
// moves in tactics phase do not affect creature status
// (tactics stack queue is managed by client)
return ;
}
2010-12-04 21:15:20 +02:00
if ( ba . actionType ! = BattleAction : : HERO_SPELL ) //don't check for stack if it's custom action by hero
2011-02-11 21:12:08 +02:00
{
2009-09-10 14:28:34 +03:00
assert ( st ) ;
2011-02-11 21:12:08 +02:00
}
else
{
gs - > curB - > usedSpellsHistory [ ba . side ] . push_back ( VLC - > spellh - > spells [ ba . additionalInfo ] ) ;
}
2009-09-10 14:28:34 +03:00
2009-03-07 17:55:56 +02:00
switch ( ba . actionType )
{
2010-12-04 21:15:20 +02:00
case BattleAction : : DEFEND :
2011-12-14 00:23:17 +03:00
st - > state . insert ( EBattleStackState : : DEFENDING ) ;
2009-03-07 17:55:56 +02:00
break ;
2010-12-04 21:15:20 +02:00
case BattleAction : : WAIT :
2011-12-14 00:23:17 +03:00
st - > state . insert ( EBattleStackState : : WAITING ) ;
2009-11-21 00:35:18 +02:00
return ;
2011-10-01 22:56:54 +03:00
case BattleAction : : HERO_SPELL : //no change in current stack state
return ;
default : //any active stack action - attack, catapult, heal, spell...
2011-12-14 00:23:17 +03:00
st - > state . insert ( EBattleStackState : : MOVED ) ;
2009-03-07 17:55:56 +02:00
break ;
}
2009-11-21 00:35:18 +02:00
2009-11-28 03:42:08 +02:00
if ( st )
2011-12-14 00:23:17 +03:00
st - > state - = EBattleStackState : : WAITING ; //if stack was waiting it has made move, so it won't be "waiting" anymore (if the action was WAIT, then we have returned)
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleSpellCast : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2010-05-02 21:20:26 +03:00
assert ( gs - > curB ) ;
2011-10-09 14:23:24 +03:00
if ( castedByHero )
2009-03-07 17:55:56 +02:00
{
2011-10-09 14:23:24 +03:00
CGHeroInstance * h = gs - > curB - > heroes [ side ] ;
CGHeroInstance * enemy = gs - > curB - > heroes [ 1 - side ] ;
h - > mana - = spellCost ;
2011-12-14 00:23:17 +03:00
vstd : : amax ( h - > mana , 0 ) ;
2011-10-09 14:23:24 +03:00
if ( enemy & & manaGained )
enemy - > mana + = manaGained ;
if ( side > = 0 & & side < 2 )
2009-08-23 16:41:57 +03:00
{
2011-10-09 14:23:24 +03:00
gs - > curB - > castSpells [ side ] + + ;
2009-08-23 16:41:57 +03:00
}
2009-03-07 17:55:56 +02:00
}
2009-08-06 17:02:21 +03:00
2010-05-02 21:20:26 +03:00
if ( id = = 35 | | id = = 78 ) //dispel and dispel helpful spells
2009-04-21 20:32:43 +03:00
{
2010-03-03 13:18:08 +02:00
bool onlyHelpful = id = = 78 ;
2009-08-04 20:05:49 +03:00
for ( std : : set < ui32 > : : const_iterator it = affectedCres . begin ( ) ; it ! = affectedCres . end ( ) ; + + it )
2009-04-21 20:32:43 +03:00
{
2009-08-04 20:05:49 +03:00
CStack * s = gs - > curB - > getStack ( * it ) ;
if ( s & & ! vstd : : contains ( resisted , s - > ID ) ) //if stack exists and it didn't resist
2009-05-16 17:49:06 +03:00
{
2011-02-21 06:13:00 +02:00
if ( onlyHelpful )
s - > popBonuses ( Selector : : positiveSpellEffects ) ;
else
s - > popBonuses ( Selector : : sourceType ( Bonus : : SPELL_EFFECT ) ) ;
2009-05-16 17:49:06 +03:00
}
2009-04-21 20:32:43 +03:00
}
}
2009-03-07 17:55:56 +02:00
}
2011-01-20 21:57:12 +02:00
void actualizeEffect ( CStack * s , const std : : vector < Bonus > & ef )
2009-05-17 18:24:50 +03:00
{
//actualizing features vector
2010-05-02 21:20:26 +03:00
2011-01-20 21:57:12 +02:00
BOOST_FOREACH ( const Bonus & fromEffect , ef )
2009-05-17 18:24:50 +03:00
{
2011-07-13 21:39:02 +03:00
BOOST_FOREACH ( Bonus * stackBonus , s - > getBonusList ( ) ) //TODO: optimize
2009-05-17 18:24:50 +03:00
{
2011-01-20 21:57:12 +02:00
if ( stackBonus - > source = = Bonus : : SPELL_EFFECT & & stackBonus - > type = = fromEffect . type & & stackBonus - > subtype = = fromEffect . subtype )
2009-05-17 18:24:50 +03:00
{
2011-01-20 21:57:12 +02:00
stackBonus - > turnsRemain = std : : max ( stackBonus - > turnsRemain , fromEffect . turnsRemain ) ;
2009-05-17 18:24:50 +03:00
}
}
}
2011-04-23 12:57:51 +03:00
}
void actualizeEffect ( CStack * s , const Bonus & ef )
{
2011-07-13 21:39:02 +03:00
BOOST_FOREACH ( Bonus * stackBonus , s - > getBonusList ( ) ) //TODO: optimize
2011-04-23 12:57:51 +03:00
{
if ( stackBonus - > source = = Bonus : : SPELL_EFFECT & & stackBonus - > type = = ef . type & & stackBonus - > subtype = = ef . subtype )
{
stackBonus - > turnsRemain = std : : max ( stackBonus - > turnsRemain , ef . turnsRemain ) ;
}
}
2009-05-17 18:24:50 +03:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetStackEffect : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2011-04-25 12:03:13 +03:00
int spellid = effect . begin ( ) - > sid ; //effects' source ID
2011-04-23 12:57:51 +03:00
2009-03-21 14:49:58 +02:00
BOOST_FOREACH ( ui32 id , stacks )
{
CStack * s = gs - > curB - > getStack ( id ) ;
if ( s )
2009-04-17 17:01:22 +03:00
{
2011-04-25 12:03:13 +03:00
if ( spellid = = 47 | | spellid = = 80 | | ! s - > hasBonus ( Selector : : source ( Bonus : : SPELL_EFFECT , spellid ) ) ) //disrupting ray or acid breath or not on the list - just add
2009-05-16 17:49:06 +03:00
{
2011-01-20 21:57:12 +02:00
BOOST_FOREACH ( Bonus & fromEffect , effect )
2009-05-16 17:49:06 +03:00
{
2011-01-20 21:57:12 +02:00
s - > addNewBonus ( new Bonus ( fromEffect ) ) ;
2009-05-16 17:49:06 +03:00
}
2009-05-17 18:24:50 +03:00
}
else //just actualize
{
actualizeEffect ( s , effect ) ;
2009-05-16 17:49:06 +03:00
}
2009-04-17 17:01:22 +03:00
}
2009-03-21 14:49:58 +02:00
else
tlog1 < < " Cannot find stack " < < id < < std : : endl ;
}
2011-04-23 12:57:51 +03:00
typedef std : : pair < ui32 , Bonus > p ;
BOOST_FOREACH ( p para , uniqueBonuses )
{
CStack * s = gs - > curB - > getStack ( para . first ) ;
if ( s )
{
2011-06-24 20:43:02 +03:00
if ( ! s - > hasBonus ( Selector : : source ( Bonus : : SPELL_EFFECT , spellid ) & & Selector : : typeSubtype ( para . second . type , para . second . subtype ) ) )
2011-04-23 12:57:51 +03:00
s - > addNewBonus ( new Bonus ( para . second ) ) ;
else
actualizeEffect ( s , effect ) ;
}
else
tlog1 < < " Cannot find stack " < < para . first < < std : : endl ;
}
2009-03-07 17:55:56 +02:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void StacksInjured : : applyGs ( CGameState * gs )
2009-04-16 03:28:54 +03:00
{
BOOST_FOREACH ( BattleStackAttacked stackAttacked , stacks )
stackAttacked . applyGs ( gs ) ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void StacksHealedOrResurrected : : applyGs ( CGameState * gs )
2009-08-04 20:05:49 +03:00
{
for ( int g = 0 ; g < healedStacks . size ( ) ; + + g )
{
2009-10-17 17:32:42 +03:00
CStack * changedStack = gs - > curB - > getStack ( healedStacks [ g ] . stackID , false ) ;
2009-08-17 14:22:29 +03:00
//checking if we resurrect a stack that is under a living stack
2011-12-22 16:05:19 +03:00
std : : vector < BattleHex > access = gs - > curB - > getAccessibility ( changedStack , true ) ;
2011-12-14 00:23:17 +03:00
bool acc [ GameConstants : : BFIELD_SIZE ] ;
for ( int h = 0 ; h < GameConstants : : BFIELD_SIZE ; + + h )
2009-08-17 14:22:29 +03:00
acc [ h ] = false ;
for ( int h = 0 ; h < access . size ( ) ; + + h )
acc [ access [ h ] ] = true ;
if ( ! changedStack - > alive ( ) & & ! gs - > curB - > isAccessible ( changedStack - > position , acc ,
2010-05-02 21:20:26 +03:00
changedStack - > doubleWide ( ) , changedStack - > attackerOwned ,
changedStack - > hasBonusOfType ( Bonus : : FLYING ) , true ) )
2009-08-17 14:22:29 +03:00
return ; //position is already occupied
//applying changes
2009-10-17 17:32:42 +03:00
bool resurrected = ! changedStack - > alive ( ) ; //indicates if stack is resurrected or just healed
2010-05-07 15:29:41 +03:00
if ( resurrected )
2009-08-05 15:46:08 +03:00
{
2011-12-14 00:23:17 +03:00
changedStack - > state . insert ( EBattleStackState : : ALIVE ) ;
2010-01-29 18:35:05 +02:00
if ( healedStacks [ g ] . lowLevelResurrection )
2011-12-14 00:23:17 +03:00
changedStack - > state . insert ( EBattleStackState : : SUMMONED ) ; //TODO: different counter for rised units
2009-08-05 15:46:08 +03:00
}
2010-11-09 13:27:58 +02:00
//int missingHPfirst = changedStack->MaxHealth() - changedStack->firstHPleft;
2010-05-02 21:20:26 +03:00
int res = std : : min ( healedStacks [ g ] . healedHP / changedStack - > MaxHealth ( ) , changedStack - > baseAmount - changedStack - > count ) ;
changedStack - > count + = res ;
2009-10-17 17:32:42 +03:00
changedStack - > firstHPleft + = healedStacks [ g ] . healedHP - res * changedStack - > MaxHealth ( ) ;
2009-08-05 15:46:08 +03:00
if ( changedStack - > firstHPleft > changedStack - > MaxHealth ( ) )
{
changedStack - > firstHPleft - = changedStack - > MaxHealth ( ) ;
2010-05-02 21:20:26 +03:00
if ( changedStack - > baseAmount > changedStack - > count )
2009-10-17 17:32:42 +03:00
{
2010-05-02 21:20:26 +03:00
changedStack - > count + = 1 ;
2009-10-17 17:32:42 +03:00
}
2009-08-05 15:46:08 +03:00
}
2011-12-14 00:23:17 +03:00
vstd : : amin ( changedStack - > firstHPleft , changedStack - > MaxHealth ( ) ) ;
2009-08-04 20:05:49 +03:00
//removal of negative effects
2009-10-17 17:32:42 +03:00
if ( resurrected )
2009-08-04 20:05:49 +03:00
{
2010-11-19 00:06:56 +02:00
2011-05-25 17:48:49 +03:00
// for (BonusList::iterator it = changedStack->bonuses.begin(); it != changedStack->bonuses.end(); it++)
// {
// if(VLC->spellh->spells[(*it)->sid]->positiveness < 0)
// {
// changedStack->bonuses.erase(it);
// }
// }
2009-08-04 20:05:49 +03:00
//removing all features from negative spells
2011-07-13 21:39:02 +03:00
const BonusList tmpFeatures = changedStack - > getBonusList ( ) ;
2011-05-25 17:48:49 +03:00
//changedStack->bonuses.clear();
2010-05-02 21:20:26 +03:00
2010-11-19 00:06:56 +02:00
BOOST_FOREACH ( Bonus * b , tmpFeatures )
2009-08-04 20:05:49 +03:00
{
2010-11-19 00:06:56 +02:00
const CSpell * s = b - > sourceSpell ( ) ;
2012-02-17 00:19:07 +03:00
if ( s & & s - > isNegative ( ) )
2009-08-04 20:05:49 +03:00
{
2011-05-25 17:48:49 +03:00
changedStack - > removeBonus ( b ) ;
2009-08-04 20:05:49 +03:00
}
}
}
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void ObstaclesRemoved : : applyGs ( CGameState * gs )
2009-08-19 13:59:42 +03:00
{
if ( gs - > curB ) //if there is a battle
{
for ( std : : set < si32 > : : const_iterator it = obstacles . begin ( ) ; it ! = obstacles . end ( ) ; + + it )
{
for ( int i = 0 ; i < gs - > curB - > obstacles . size ( ) ; + + i )
{
if ( gs - > curB - > obstacles [ i ] . uniqueID = = * it ) //remove this obstacle
{
gs - > curB - > obstacles . erase ( gs - > curB - > obstacles . begin ( ) + i ) ;
break ;
}
}
}
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void CatapultAttack : : applyGs ( CGameState * gs )
2009-09-01 16:54:13 +03:00
{
if ( gs - > curB & & gs - > curB - > siege ! = 0 ) //if there is a battle and it's a siege
{
2009-09-24 16:44:55 +03:00
for ( std : : set < std : : pair < std : : pair < ui8 , si16 > , ui8 > > : : const_iterator it = attackedParts . begin ( ) ; it ! = attackedParts . end ( ) ; + + it )
2009-09-07 15:30:10 +03:00
{
2009-09-24 16:44:55 +03:00
gs - > curB - > si . wallState [ it - > first . first ] =
std : : min ( gs - > curB - > si . wallState [ it - > first . first ] + it - > second , 3 ) ;
2009-09-07 15:30:10 +03:00
}
2009-09-01 16:54:13 +03:00
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleStacksRemoved : : applyGs ( CGameState * gs )
2009-09-05 17:10:26 +03:00
{
if ( ! gs - > curB )
return ;
for ( std : : set < ui32 > : : const_iterator it = stackIDs . begin ( ) ; it ! = stackIDs . end ( ) ; + + it ) //for each removed stack
{
for ( int b = 0 ; b < gs - > curB - > stacks . size ( ) ; + + b ) //find it in vector of stacks
{
if ( gs - > curB - > stacks [ b ] - > ID = = * it ) //if found
{
2012-02-18 23:50:06 +03:00
CStack * toRemove = gs - > curB - > stacks [ b ] ;
2009-09-05 17:10:26 +03:00
gs - > curB - > stacks . erase ( gs - > curB - > stacks . begin ( ) + b ) ; //remove
2012-02-18 23:50:06 +03:00
toRemove - > detachFromAll ( ) ;
delete toRemove ;
2009-09-05 17:10:26 +03:00
break ;
}
}
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleStackAdded : : applyGs ( CGameState * gs )
2011-10-01 22:56:54 +03:00
{
2011-12-22 16:05:19 +03:00
if ( ! BattleHex ( pos ) . isValid ( ) )
2011-10-01 22:56:54 +03:00
{
tlog2 < < " No place found for new stack! \n " ;
return ;
}
2012-02-29 04:31:48 +03:00
CStackBasicDescriptor csbd ( creID , amount ) ;
CStack * addedStack = gs - > curB - > generateNewStack ( csbd , attacker , 255 , pos ) ; //TODO: netpacks?
2011-10-01 22:56:54 +03:00
if ( summoned )
2012-02-29 04:31:48 +03:00
addedStack - > state . insert ( EBattleStackState : : SUMMONED ) ;
gs - > curB - > localInitStack ( addedStack ) ;
gs - > curB - > stacks . push_back ( addedStack ) ; //the stack is not "SUMMONED", it is permanent
2011-10-01 22:56:54 +03:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void BattleSetStackProperty : : applyGs ( CGameState * gs )
2011-10-02 16:59:12 +03:00
{
2011-10-08 12:11:36 +03:00
CStack * stack = gs - > curB - > getStack ( stackID ) ;
2011-10-02 16:59:12 +03:00
switch ( which )
{
case CASTS :
{
if ( absolute )
2011-10-08 12:11:36 +03:00
stack - > casts = val ;
2011-10-02 16:59:12 +03:00
else
2011-10-08 12:11:36 +03:00
stack - > casts + = val ;
2011-12-14 00:23:17 +03:00
vstd : : amax ( stack - > casts , 0 ) ;
2011-10-02 16:59:12 +03:00
break ;
}
2011-10-09 10:20:23 +03:00
case ENCHANTER_COUNTER :
{
int side = gs - > curB - > whatSide ( stack - > owner ) ;
if ( absolute )
gs - > curB - > enchanterCounter [ side ] = val ;
else
gs - > curB - > enchanterCounter [ side ] + = val ;
2011-12-14 00:23:17 +03:00
vstd : : amax ( gs - > curB - > enchanterCounter [ side ] , 0 ) ;
2011-10-09 10:20:23 +03:00
break ;
}
2011-10-17 11:24:51 +03:00
case UNBIND :
{
stack - > popBonuses ( Selector : : type ( Bonus : : BIND_EFFECT ) ) ;
break ;
}
2012-02-10 16:13:24 +03:00
case CLONED :
{
stack - > state . insert ( EBattleStackState : : CLONED ) ;
break ;
}
2011-10-02 16:59:12 +03:00
}
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void YourTurn : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
gs - > currentPlayer = player ;
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE void SetSelection : : applyGs ( CGameState * gs )
2009-03-07 17:55:56 +02:00
{
2009-03-09 12:37:49 +02:00
gs - > getPlayer ( player ) - > currentSelection = id ;
2010-04-02 05:07:40 +03:00
}
2011-12-14 00:23:17 +03:00
DLL_LINKAGE Component : : Component ( const CStackBasicDescriptor & stack )
2010-04-02 05:07:40 +03:00
: id ( CREATURE ) , subtype ( stack . type - > idNumber ) , val ( stack . count ) , when ( 0 )
{
2011-09-24 04:15:36 +03:00
}