2017-07-13 10:26:03 +02:00
/*
* NetPacksClient . 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
*
*/
2011-12-14 00:23:17 +03:00
# include "StdInc.h"
2023-02-12 09:23:39 +02:00
# include "ClientNetPackVisitors.h"
2011-12-14 00:23:17 +03:00
2009-05-20 13:08:56 +03:00
# include "Client.h"
# include "CPlayerInterface.h"
# include "CGameInfo.h"
2023-02-01 20:42:06 +02:00
# include "windows/GUIClasses.h"
2023-03-01 12:31:23 +02:00
# include "mapView/mapHandler.h"
2023-02-01 20:42:06 +02:00
# include "adventureMap/CInGameConsole.h"
# include "battle/BattleInterface.h"
# include "gui/CGuiHandler.h"
# include "widgets/MiscWidgets.h"
# include "CMT.h"
# include "CServerHandler.h"
# include "../CCallback.h"
# include "../lib/filesystem/Filesystem.h"
# include "../lib/filesystem/FileInfo.h"
2016-09-10 02:32:40 +02:00
# include "../lib/serializer/Connection.h"
# include "../lib/serializer/BinarySerializer.h"
2010-12-20 23:22:53 +02:00
# include "../lib/CGeneralTextHandler.h"
# include "../lib/CHeroHandler.h"
2009-03-07 17:55:56 +02:00
# include "../lib/VCMI_Lib.h"
2013-04-07 13:48:07 +03:00
# include "../lib/mapping/CMap.h"
2009-10-10 08:47:59 +03:00
# include "../lib/VCMIDirs.h"
2015-02-02 10:25:26 +02:00
# include "../lib/spells/CSpellHandler.h"
2014-06-05 23:51:24 +03:00
# include "../lib/CSoundBase.h"
2014-06-25 17:11:07 +03:00
# include "../lib/StartInfo.h"
2012-09-29 13:59:43 +03:00
# include "../lib/CConfigHandler.h"
2013-04-07 13:48:07 +03:00
# include "../lib/mapping/CCampaignHandler.h"
2010-12-25 21:23:30 +02:00
# include "../lib/CGameState.h"
2017-03-17 17:48:44 +02:00
# include "../lib/CStack.h"
2017-06-24 16:42:05 +02:00
# include "../lib/battle/BattleInfo.h"
2011-12-14 00:23:17 +03:00
# include "../lib/GameConstants.h"
2015-12-02 21:39:53 +02:00
# include "../lib/CPlayerState.h"
2009-03-07 17:55:56 +02:00
2018-02-03 16:44:30 +02:00
// TODO: as Tow suggested these template should all be part of CClient
// This will require rework spectator interface properly though
template < typename T , typename . . . Args , typename . . . Args2 >
2023-02-12 09:23:39 +02:00
bool callOnlyThatInterface ( CClient & cl , PlayerColor player , void ( T : : * ptr ) ( Args . . . ) , Args2 & & . . . args )
2018-02-03 16:44:30 +02:00
{
2023-02-12 09:23:39 +02:00
if ( vstd : : contains ( cl . playerint , player ) )
2018-02-03 16:44:30 +02:00
{
2023-02-12 09:23:39 +02:00
( ( * cl . playerint [ player ] ) . * ptr ) ( std : : forward < Args2 > ( args ) . . . ) ;
2018-02-03 16:44:30 +02:00
return true ;
}
return false ;
}
template < typename T , typename . . . Args , typename . . . Args2 >
2023-02-12 09:23:39 +02:00
bool callInterfaceIfPresent ( CClient & cl , PlayerColor player , void ( T : : * ptr ) ( Args . . . ) , Args2 & & . . . args )
2018-02-03 16:44:30 +02:00
{
bool called = callOnlyThatInterface ( cl , player , ptr , std : : forward < Args2 > ( args ) . . . ) ;
return called ;
}
template < typename T , typename . . . Args , typename . . . Args2 >
2023-02-12 09:23:39 +02:00
void callOnlyThatBattleInterface ( CClient & cl , PlayerColor player , void ( T : : * ptr ) ( Args . . . ) , Args2 & & . . . args )
2018-02-03 16:44:30 +02:00
{
2023-02-12 09:23:39 +02:00
if ( vstd : : contains ( cl . battleints , player ) )
( ( * cl . battleints [ player ] ) . * ptr ) ( std : : forward < Args2 > ( args ) . . . ) ;
2018-02-03 16:44:30 +02:00
2023-02-12 09:23:39 +02:00
if ( cl . additionalBattleInts . count ( player ) )
2018-02-03 16:44:30 +02:00
{
2023-02-12 09:23:39 +02:00
for ( auto bInt : cl . additionalBattleInts [ player ] )
2018-02-03 16:44:30 +02:00
( ( * bInt ) . * ptr ) ( std : : forward < Args2 > ( args ) . . . ) ;
}
}
template < typename T , typename . . . Args , typename . . . Args2 >
2023-02-12 09:23:39 +02:00
void callBattleInterfaceIfPresent ( CClient & cl , PlayerColor player , void ( T : : * ptr ) ( Args . . . ) , Args2 & & . . . args )
2018-02-03 16:44:30 +02:00
{
callOnlyThatInterface ( cl , player , ptr , std : : forward < Args2 > ( args ) . . . ) ;
}
//calls all normal interfaces and privileged ones, playerints may be updated when iterating over it, so we need a copy
template < typename T , typename . . . Args , typename . . . Args2 >
2023-02-12 09:23:39 +02:00
void callAllInterfaces ( CClient & cl , void ( T : : * ptr ) ( Args . . . ) , Args2 & & . . . args )
2018-02-03 16:44:30 +02:00
{
2023-02-12 09:23:39 +02:00
for ( auto pInt : cl . playerint )
2018-02-03 16:44:30 +02:00
( ( * pInt . second ) . * ptr ) ( std : : forward < Args2 > ( args ) . . . ) ;
}
//calls all normal interfaces and privileged ones, playerints may be updated when iterating over it, so we need a copy
template < typename T , typename . . . Args , typename . . . Args2 >
2023-02-12 09:23:39 +02:00
void callBattleInterfaceIfPresentForBothSides ( CClient & cl , void ( T : : * ptr ) ( Args . . . ) , Args2 & & . . . args )
2018-02-03 16:44:30 +02:00
{
2023-02-12 09:23:39 +02:00
callOnlyThatBattleInterface ( cl , cl . gameState ( ) - > curB - > sides [ 0 ] . color , ptr , std : : forward < Args2 > ( args ) . . . ) ;
callOnlyThatBattleInterface ( cl , cl . gameState ( ) - > curB - > sides [ 1 ] . color , ptr , std : : forward < Args2 > ( args ) . . . ) ;
2018-02-03 16:44:30 +02:00
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) & & ! settings [ " session " ] [ " spectate-skip-battle " ] . Bool ( ) & & LOCPLINT - > battleInt )
{
callOnlyThatBattleInterface ( cl , PlayerColor : : SPECTATOR , ptr , std : : forward < Args2 > ( args ) . . . ) ;
}
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetResources ( SetResources & pack )
2009-03-07 17:55:56 +02:00
{
2016-11-26 14:14:43 +02:00
//todo: inform on actual resource set transfered
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . player , & IGameEventsReceiver : : receivedResource ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetPrimSkill ( SetPrimSkill & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . id ) ;
2009-03-19 16:17:19 +02:00
if ( ! h )
{
2023-02-12 09:23:39 +02:00
logNetwork - > error ( " Cannot find hero with pack.id %d " , pack . id . getNum ( ) ) ;
2009-03-19 16:17:19 +02:00
return ;
}
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroPrimarySkillChanged , h , pack . which , pack . val ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetSecSkill ( SetSecSkill & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . id ) ;
2010-07-20 17:08:13 +03:00
if ( ! h )
{
2023-02-12 09:23:39 +02:00
logNetwork - > error ( " Cannot find hero with pack.id %d " , pack . id . getNum ( ) ) ;
2010-07-20 17:08:13 +03:00
return ;
}
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroSecondarySkillChanged , h , pack . which , pack . val ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitHeroVisitCastle ( HeroVisitCastle & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . hid ) ;
if ( pack . start ( ) )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroVisitsTown , h , gs . getTown ( pack . tid ) ) ;
2009-03-07 17:55:56 +02:00
}
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetMana ( SetMana & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . hid ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroManaPointsChanged , h ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetMovePoints ( SetMovePoints & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . hid ) ;
cl . invalidatePaths ( ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroMovePointsChanged , h ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitFoWChange ( FoWChange & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
for ( auto & i : cl . playerint )
2014-06-21 16:41:05 +03:00
{
2023-02-12 09:23:39 +02:00
if ( cl . getPlayerRelations ( i . first , pack . player ) = = PlayerRelations : : SAME_PLAYER & & pack . waitForDialogs & & LOCPLINT = = i . second . get ( ) )
2014-06-21 16:41:05 +03:00
{
LOCPLINT - > waitWhileDialog ( ) ;
}
2023-02-12 09:23:39 +02:00
if ( cl . getPlayerRelations ( i . first , pack . player ) ! = PlayerRelations : : ENEMIES )
2012-02-21 00:01:54 +03:00
{
2023-02-12 09:23:39 +02:00
if ( pack . mode )
i . second - > tileRevealed ( pack . tiles ) ;
2012-02-21 00:01:54 +03:00
else
2023-02-12 09:23:39 +02:00
i . second - > tileHidden ( pack . tiles ) ;
2012-02-21 00:01:54 +03:00
}
2014-06-21 16:41:05 +03:00
}
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
static void dispatchGarrisonChange ( CClient & cl , ObjectInstanceID army1 , ObjectInstanceID army2 )
2010-11-27 22:17:28 +02:00
{
2023-02-12 09:23:39 +02:00
auto obj1 = cl . getObj ( army1 ) ;
2018-03-10 23:19:36 +02:00
if ( ! obj1 )
{
2023-02-12 09:23:39 +02:00
logNetwork - > error ( " Cannot find army with pack.id %d " , army1 . getNum ( ) ) ;
2018-03-10 23:19:36 +02:00
return ;
}
callInterfaceIfPresent ( cl , obj1 - > tempOwner , & IGameEventsReceiver : : garrisonsChanged , army1 , army2 ) ;
if ( army2 ! = ObjectInstanceID ( ) & & army2 ! = army1 )
{
2023-02-12 09:23:39 +02:00
auto obj2 = cl . getObj ( army2 ) ;
2018-03-10 23:19:36 +02:00
if ( ! obj2 )
{
2023-02-12 09:23:39 +02:00
logNetwork - > error ( " Cannot find army with pack.id %d " , army2 . getNum ( ) ) ;
2018-03-10 23:19:36 +02:00
return ;
}
if ( obj1 - > tempOwner ! = obj2 - > tempOwner )
callInterfaceIfPresent ( cl , obj2 - > tempOwner , & IGameEventsReceiver : : garrisonsChanged , army1 , army2 ) ;
}
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitChangeStackCount ( ChangeStackCount & pack )
2018-03-10 23:19:36 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . army , ObjectInstanceID ( ) ) ;
2010-11-27 22:17:28 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetStackType ( SetStackType & pack )
2010-11-27 22:17:28 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . army , ObjectInstanceID ( ) ) ;
2010-11-27 22:17:28 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitEraseStack ( EraseStack & pack )
2010-11-27 22:17:28 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . army , ObjectInstanceID ( ) ) ;
2010-11-27 22:17:28 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSwapStacks ( SwapStacks & pack )
2010-11-27 22:17:28 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . srcArmy , pack . dstArmy ) ;
2010-11-27 22:17:28 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitInsertNewStack ( InsertNewStack & pack )
2010-11-27 22:17:28 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . army , ObjectInstanceID ( ) ) ;
2010-11-27 22:17:28 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitRebalanceStacks ( RebalanceStacks & pack )
2010-11-27 22:17:28 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . srcArmy , pack . dstArmy ) ;
2010-11-27 22:17:28 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBulkRebalanceStacks ( BulkRebalanceStacks & pack )
2021-11-28 14:57:38 +02:00
{
2023-02-12 09:23:39 +02:00
if ( ! pack . moves . empty ( ) )
2021-11-28 14:57:38 +02:00
{
2023-02-12 09:23:39 +02:00
auto destArmy = pack . moves [ 0 ] . srcArmy = = pack . moves [ 0 ] . dstArmy
2021-11-28 14:57:38 +02:00
? ObjectInstanceID ( )
2023-02-12 09:23:39 +02:00
: pack . moves [ 0 ] . dstArmy ;
dispatchGarrisonChange ( cl , pack . moves [ 0 ] . srcArmy , destArmy ) ;
2021-11-28 14:57:38 +02:00
}
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBulkSmartRebalanceStacks ( BulkSmartRebalanceStacks & pack )
2021-11-28 14:57:38 +02:00
{
2023-02-12 09:23:39 +02:00
if ( ! pack . moves . empty ( ) )
2021-11-28 14:57:38 +02:00
{
2023-02-12 09:23:39 +02:00
assert ( pack . moves [ 0 ] . srcArmy = = pack . moves [ 0 ] . dstArmy ) ;
dispatchGarrisonChange ( cl , pack . moves [ 0 ] . srcArmy , ObjectInstanceID ( ) ) ;
2021-11-28 14:57:38 +02:00
}
2023-02-12 09:23:39 +02:00
else if ( ! pack . changes . empty ( ) )
2021-11-28 14:57:38 +02:00
{
2023-02-12 09:23:39 +02:00
dispatchGarrisonChange ( cl , pack . changes [ 0 ] . army , ObjectInstanceID ( ) ) ;
2021-11-28 14:57:38 +02:00
}
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitPutArtifact ( PutArtifact & pack )
2010-12-26 16:34:11 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . al . owningPlayer ( ) , & IGameEventsReceiver : : artifactPut , pack . al ) ;
2023-04-08 00:54:19 +02:00
if ( pack . askAssemble )
callInterfaceIfPresent ( cl , pack . al . owningPlayer ( ) , & IGameEventsReceiver : : askToAssembleArtifact , pack . al ) ;
2010-12-26 16:34:11 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitEraseArtifact ( EraseArtifact & pack )
2010-12-26 16:34:11 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . al . owningPlayer ( ) , & IGameEventsReceiver : : artifactRemoved , pack . al ) ;
2010-12-26 16:34:11 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitMoveArtifact ( MoveArtifact & pack )
2010-12-26 16:34:11 +02:00
{
2023-02-12 09:23:39 +02:00
auto moveArtifact = [ this , & pack ] ( PlayerColor player ) - > void
2022-11-07 00:36:13 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , player , & IGameEventsReceiver : : artifactMoved , pack . src , pack . dst ) ;
if ( pack . askAssemble )
2023-02-13 21:10:53 +02:00
callInterfaceIfPresent ( cl , player , & IGameEventsReceiver : : askToAssembleArtifact , pack . dst ) ;
2023-01-02 16:19:45 +02:00
} ;
2023-02-12 09:23:39 +02:00
moveArtifact ( pack . src . owningPlayer ( ) ) ;
if ( pack . src . owningPlayer ( ) ! = pack . dst . owningPlayer ( ) )
moveArtifact ( pack . dst . owningPlayer ( ) ) ;
2010-12-26 16:34:11 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBulkMoveArtifacts ( BulkMoveArtifacts & pack )
2022-11-06 23:54:50 +02:00
{
2023-02-12 09:23:39 +02:00
auto applyMove = [ this , & pack ] ( std : : vector < BulkMoveArtifacts : : LinkedSlots > & artsPack ) - > void
2022-11-06 23:54:50 +02:00
{
2022-11-10 20:48:19 +02:00
for ( auto & slotToMove : artsPack )
2022-11-06 23:54:50 +02:00
{
2023-02-12 09:23:39 +02:00
auto srcLoc = ArtifactLocation ( pack . srcArtHolder , slotToMove . srcPos ) ;
auto dstLoc = ArtifactLocation ( pack . dstArtHolder , slotToMove . dstPos ) ;
2023-02-13 21:10:53 +02:00
MoveArtifact ma ( & srcLoc , & dstLoc , false ) ;
visitMoveArtifact ( ma ) ;
2022-11-06 23:54:50 +02:00
}
2022-11-10 20:48:19 +02:00
} ;
2023-02-13 21:10:53 +02:00
// Begin a session of bulk movement of arts. It is not necessary but useful for the client optimization.
callInterfaceIfPresent ( cl , cl . getCurrentPlayer ( ) , & IGameEventsReceiver : : bulkArtMovementStart ,
pack . artsPack0 . size ( ) + pack . artsPack1 . size ( ) ) ;
2023-02-12 09:23:39 +02:00
applyMove ( pack . artsPack0 ) ;
if ( pack . swap )
applyMove ( pack . artsPack1 ) ;
2022-11-06 23:54:50 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitAssembledArtifact ( AssembledArtifact & pack )
2011-01-22 05:43:20 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . al . owningPlayer ( ) , & IGameEventsReceiver : : artifactAssembled , pack . al ) ;
2011-01-22 05:43:20 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitDisassembledArtifact ( DisassembledArtifact & pack )
2011-01-22 05:43:20 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . al . owningPlayer ( ) , & IGameEventsReceiver : : artifactDisassembled , pack . al ) ;
2011-01-22 05:43:20 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitHeroVisit ( HeroVisit & pack )
2011-05-10 01:20:47 +03:00
{
2023-02-12 09:23:39 +02:00
auto hero = cl . getHero ( pack . heroId ) ;
auto obj = cl . getObj ( pack . objId , false ) ;
callInterfaceIfPresent ( cl , pack . player , & IGameEventsReceiver : : heroVisit , hero , obj , pack . starting ) ;
2011-05-10 01:20:47 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitNewTurn ( NewTurn & pack )
2011-08-25 18:24:37 +03:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
2011-08-25 18:24:37 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitGiveBonus ( GiveBonus & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
switch ( pack . who )
2010-02-10 04:56:00 +02:00
{
2023-03-28 13:46:53 +02:00
case GiveBonus : : ETarget : : HERO :
2010-02-10 04:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = gs . getHero ( ObjectInstanceID ( pack . id ) ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroBonusChanged , h , * h - > getBonusList ( ) . back ( ) , true ) ;
2010-02-10 04:56:00 +02:00
}
break ;
2023-03-28 13:46:53 +02:00
case GiveBonus : : ETarget : : PLAYER :
2010-02-10 04:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
const PlayerState * p = gs . getPlayerState ( PlayerColor ( pack . id ) ) ;
callInterfaceIfPresent ( cl , PlayerColor ( pack . id ) , & IGameEventsReceiver : : playerBonusChanged , * p - > getBonusList ( ) . back ( ) , true ) ;
2010-02-10 04:56:00 +02:00
}
break ;
}
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitChangeObjPos ( ChangeObjPos & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGObjectInstance * obj = gs . getObjInstance ( pack . objid ) ;
2023-02-16 21:35:15 +02:00
if ( CGI - > mh )
CGI - > mh - > onObjectFadeOut ( obj ) ;
2023-02-18 17:37:09 +02:00
CGI - > mh - > waitForOngoingAnimations ( ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitChangeObjPos ( ChangeObjPos & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGObjectInstance * obj = gs . getObjInstance ( pack . objid ) ;
2023-02-16 21:35:15 +02:00
if ( CGI - > mh )
CGI - > mh - > onObjectFadeIn ( obj ) ;
2010-03-11 01:16:30 +02:00
2023-02-18 17:37:09 +02:00
CGI - > mh - > waitForOngoingAnimations ( ) ;
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitPlayerEndsGame ( PlayerEndsGame & pack )
2010-01-29 22:52:45 +02:00
{
2023-02-12 09:23:39 +02:00
callAllInterfaces ( cl , & IGameEventsReceiver : : gameOver , pack . player , pack . victoryLossCheckResult ) ;
2017-06-04 10:59:26 +02:00
2023-02-12 09:23:39 +02:00
// In auto testing pack.mode we always close client if red pack.player won or lose
if ( ! settings [ " session " ] [ " testmap " ] . isNull ( ) & & pack . player = = PlayerColor ( 0 ) )
2017-06-04 10:59:26 +02:00
handleQuit ( settings [ " session " ] [ " spectate " ] . Bool ( ) ) ; // if spectator is active ask to close client or not
2010-01-29 22:52:45 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitPlayerReinitInterface ( PlayerReinitInterface & pack )
2022-09-30 21:08:37 +02:00
{
2023-02-12 09:23:39 +02:00
auto initInterfaces = [ this ] ( )
2022-10-12 22:18:15 +02:00
{
2023-02-12 09:23:39 +02:00
cl . initPlayerInterfaces ( ) ;
auto currentPlayer = cl . gameState ( ) - > currentPlayer ;
2022-10-12 22:18:15 +02:00
callAllInterfaces ( cl , & IGameEventsReceiver : : playerStartsTurn , currentPlayer ) ;
callOnlyThatInterface ( cl , currentPlayer , & CGameInterface : : yourTurn ) ;
} ;
2023-02-12 09:23:39 +02:00
for ( auto player : pack . players )
2022-10-01 16:28:45 +02:00
{
2022-10-04 23:54:31 +02:00
auto & plSettings = CSH - > si - > getIthPlayersSettings ( player ) ;
2023-02-12 09:23:39 +02:00
if ( pack . playerConnectionId = = PlayerSettings : : PLAYER_AI )
2022-10-04 23:54:31 +02:00
{
plSettings . connectedPlayerIDs . clear ( ) ;
2023-02-12 09:23:39 +02:00
cl . initPlayerEnvironments ( ) ;
2022-10-12 22:18:15 +02:00
initInterfaces ( ) ;
2022-10-04 23:54:31 +02:00
}
2023-02-12 09:23:39 +02:00
else if ( pack . playerConnectionId = = CSH - > c - > connectionID )
2022-10-04 23:54:31 +02:00
{
2023-02-12 09:23:39 +02:00
plSettings . connectedPlayerIDs . insert ( pack . playerConnectionId ) ;
cl . playerint . clear ( ) ;
2022-10-12 22:18:15 +02:00
initInterfaces ( ) ;
2022-10-04 23:54:31 +02:00
}
2022-10-01 16:28:45 +02:00
}
2022-09-30 21:08:37 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitRemoveBonus ( RemoveBonus & pack )
2010-02-10 04:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
switch ( pack . who )
2010-02-10 04:56:00 +02:00
{
2023-03-28 13:46:53 +02:00
case GiveBonus : : ETarget : : HERO :
2010-02-10 04:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = gs . getHero ( ObjectInstanceID ( pack . id ) ) ;
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroBonusChanged , h , pack . bonus , false ) ;
2010-02-10 04:56:00 +02:00
}
break ;
2023-03-28 13:46:53 +02:00
case GiveBonus : : ETarget : : PLAYER :
2010-02-10 04:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
//const PlayerState *p = gs.getPlayerState(pack.id);
callInterfaceIfPresent ( cl , PlayerColor ( pack . id ) , & IGameEventsReceiver : : playerBonusChanged , pack . bonus , false ) ;
2010-02-10 04:56:00 +02:00
}
break ;
}
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitRemoveObject ( RemoveObject & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGObjectInstance * o = cl . getObj ( pack . id ) ;
2012-07-19 12:10:55 +03:00
2017-03-12 09:54:24 +02:00
if ( CGI - > mh )
2023-02-16 21:35:15 +02:00
CGI - > mh - > onObjectFadeOut ( o ) ;
2009-08-04 02:53:18 +03:00
//notify interfaces about removal
2023-02-12 09:23:39 +02:00
for ( auto i = cl . playerint . begin ( ) ; i ! = cl . playerint . end ( ) ; i + + )
2009-03-07 17:55:56 +02:00
{
2018-11-02 17:35:25 +02:00
//below line contains little cheat for AI so it will be aware of deletion of enemy heroes that moved or got re-covered by FoW
2023-02-12 09:23:39 +02:00
//TODO: loose requirements as next AI related crashes appear, for example another pack.player collects object that got re-covered by FoW, unsure if AI code workarounds this
if ( gs . isVisible ( o , i - > first ) | | ( ! cl . getPlayerState ( i - > first ) - > human & & o - > ID = = Obj : : HERO & & o - > tempOwner ! = i - > first ) )
2009-08-04 02:53:18 +03:00
i - > second - > objectRemoved ( o ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-18 17:37:09 +02:00
CGI - > mh - > waitForOngoingAnimations ( ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitRemoveObject ( RemoveObject & pack )
2009-03-07 19:08:40 +02:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
2023-02-12 13:02:06 +02:00
for ( auto i = cl . playerint . begin ( ) ; i ! = cl . playerint . end ( ) ; i + + )
i - > second - > objectRemovedAfter ( ) ;
2009-03-07 19:08:40 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitTryMoveHero ( TryMoveHero & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGHeroInstance * h = gs . getHero ( pack . id ) ;
2009-12-28 06:08:24 +02:00
2023-02-26 18:17:53 +02:00
if ( CGI - > mh )
2009-12-28 06:08:24 +02:00
{
2023-02-26 18:17:53 +02:00
switch ( pack . result )
2017-06-03 07:25:10 +02:00
{
2023-02-26 18:17:53 +02:00
case TryMoveHero : : EMBARK :
CGI - > mh - > onBeforeHeroEmbark ( h , pack . start , pack . end ) ;
break ;
case TryMoveHero : : TELEPORTATION :
CGI - > mh - > onBeforeHeroTeleported ( h , pack . start , pack . end ) ;
break ;
case TryMoveHero : : DISEMBARK :
CGI - > mh - > onBeforeHeroDisembark ( h , pack . start , pack . end ) ;
break ;
2017-06-03 07:25:10 +02:00
}
2023-02-19 14:17:18 +02:00
CGI - > mh - > waitForOngoingAnimations ( ) ;
}
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitTryMoveHero ( TryMoveHero & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . id ) ;
cl . invalidatePaths ( ) ;
2009-03-07 17:55:56 +02:00
2017-03-12 09:54:24 +02:00
if ( CGI - > mh )
2011-06-21 19:00:19 +03:00
{
2023-02-16 21:35:15 +02:00
switch ( pack . result )
{
case TryMoveHero : : SUCCESS :
CGI - > mh - > onHeroMoved ( h , pack . start , pack . end ) ;
break ;
case TryMoveHero : : EMBARK :
2023-02-26 18:17:53 +02:00
CGI - > mh - > onAfterHeroEmbark ( h , pack . start , pack . end ) ;
break ;
case TryMoveHero : : TELEPORTATION :
CGI - > mh - > onAfterHeroTeleported ( h , pack . start , pack . end ) ;
2023-02-16 21:35:15 +02:00
break ;
case TryMoveHero : : DISEMBARK :
2023-02-26 18:17:53 +02:00
CGI - > mh - > onAfterHeroDisembark ( h , pack . start , pack . end ) ;
2023-02-16 21:35:15 +02:00
break ;
}
2017-03-12 09:54:24 +02:00
}
2009-07-19 06:10:24 +03:00
2013-03-03 20:06:03 +03:00
PlayerColor player = h - > tempOwner ;
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
for ( auto & i : cl . playerint )
if ( cl . getPlayerRelations ( i . first , player ) ! = PlayerRelations : : ENEMIES )
i . second - > tileRevealed ( pack . fowRevealed ) ;
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
for ( auto i = cl . playerint . begin ( ) ; i ! = cl . playerint . end ( ) ; i + + )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
if ( i - > first ! = PlayerColor : : SPECTATOR & & gs . checkForStandardLoss ( i - > first ) ) // Do not notify vanquished pack.player's interface
2022-01-25 13:19:48 +02:00
continue ;
2023-02-16 21:35:15 +02:00
if ( gs . isVisible ( h - > convertToVisitablePos ( pack . start ) , i - > first )
| | gs . isVisible ( h - > convertToVisitablePos ( pack . end ) , i - > first ) )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
// pack.src and pack.dst of enemy hero move may be not visible => 'verbose' should be false
const bool verbose = cl . getPlayerRelations ( i - > first , player ) ! = PlayerRelations : : ENEMIES ;
i - > second - > heroMoved ( pack , verbose ) ;
2009-03-07 17:55:56 +02:00
}
}
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitNewStructures ( NewStructures & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGTownInstance * town = gs . getTown ( pack . tid ) ;
for ( const auto & id : pack . bid )
2013-11-17 20:57:04 +03:00
{
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , town - > tempOwner , & IGameEventsReceiver : : buildChanged , town , id , 1 ) ;
2009-03-07 17:55:56 +02:00
}
2023-03-22 14:41:36 +02:00
// invalidate section of map view with our object and force an update
CGI - > mh - > onObjectInstantRemove ( town ) ;
CGI - > mh - > onObjectInstantAdd ( town ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitRazeStructures ( RazeStructures & pack )
2009-09-22 17:27:46 +03:00
{
2023-02-12 09:23:39 +02:00
CGTownInstance * town = gs . getTown ( pack . tid ) ;
for ( const auto & id : pack . bid )
2013-11-17 20:57:04 +03:00
{
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , town - > tempOwner , & IGameEventsReceiver : : buildChanged , town , id , 2 ) ;
2009-09-22 17:27:46 +03:00
}
2023-03-22 14:41:36 +02:00
// invalidate section of map view with our object and force an update
CGI - > mh - > onObjectInstantRemove ( town ) ;
CGI - > mh - > onObjectInstantAdd ( town ) ;
2009-09-22 17:27:46 +03:00
}
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetAvailableCreatures ( SetAvailableCreatures & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGDwelling * dw = static_cast < const CGDwelling * > ( cl . getObj ( pack . tid ) ) ;
2010-05-15 11:33:32 +03:00
2013-03-03 20:06:03 +03:00
PlayerColor p ;
2012-09-23 21:01:04 +03:00
if ( dw - > ID = = Obj : : WAR_MACHINE_FACTORY ) //War Machines Factory is not flaggable, it's "owned" by visitor
2023-02-12 09:23:39 +02:00
p = cl . getTile ( dw - > visitablePos ( ) ) - > visitableObjects . back ( ) - > tempOwner ;
2010-05-15 11:33:32 +03:00
else
p = dw - > tempOwner ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , p , & IGameEventsReceiver : : availableCreaturesChanged , dw ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetHeroesInTown ( SetHeroesInTown & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGTownInstance * t = gs . getTown ( pack . tid ) ;
CGHeroInstance * hGarr = gs . getHero ( pack . garrison ) ;
CGHeroInstance * hVisit = gs . getHero ( pack . visiting ) ;
2013-02-23 15:22:23 +03:00
2016-09-11 12:56:00 +02:00
//inform all players that see this object
2023-02-12 09:23:39 +02:00
for ( auto i = cl . playerint . cbegin ( ) ; i ! = cl . playerint . cend ( ) ; + + i )
2016-09-11 12:56:00 +02:00
{
if ( i - > first > = PlayerColor : : PLAYER_LIMIT )
continue ;
2013-02-23 15:22:23 +03:00
2023-02-12 09:23:39 +02:00
if ( gs . isVisible ( t , i - > first ) | |
( hGarr & & gs . isVisible ( hGarr , i - > first ) ) | |
( hVisit & & gs . isVisible ( hVisit , i - > first ) ) )
2016-09-11 12:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
cl . playerint [ i - > first ] - > heroInGarrisonChange ( t ) ;
2016-09-11 12:56:00 +02:00
}
}
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitHeroRecruited ( HeroRecruited & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGHeroInstance * h = gs . map - > heroesOnMap . back ( ) ;
if ( h - > subID ! = pack . hid )
2009-03-07 17:55:56 +02:00
{
2017-08-10 18:39:27 +02:00
logNetwork - > error ( " Something wrong with hero recruited! " ) ;
2009-03-07 17:55:56 +02:00
}
2018-02-03 16:44:30 +02:00
if ( callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroCreated , h ) )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
if ( const CGTownInstance * t = gs . getTown ( pack . tid ) )
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroInGarrisonChange , t ) ;
2016-10-02 16:27:01 +02:00
}
2023-02-22 22:06:27 +02:00
if ( CGI - > mh )
2023-02-16 21:35:15 +02:00
CGI - > mh - > onObjectInstantAdd ( h ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitGiveHero ( GiveHero & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
CGHeroInstance * h = gs . getHero ( pack . id ) ;
2017-03-12 09:54:24 +02:00
if ( CGI - > mh )
2023-02-16 21:35:15 +02:00
CGI - > mh - > onObjectInstantAdd ( h ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , h - > tempOwner , & IGameEventsReceiver : : heroCreated , h ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitGiveHero ( GiveHero & pack )
2009-03-07 17:55:56 +02:00
{
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitInfoWindow ( InfoWindow & pack )
2009-03-07 17:55:56 +02:00
{
2009-07-09 22:15:22 +03:00
std : : string str ;
2023-02-12 09:23:39 +02:00
pack . text . toString ( str ) ;
2013-11-17 20:57:04 +03:00
2023-03-06 01:30:21 +02:00
if ( ! callInterfaceIfPresent ( cl , pack . player , & CGameInterface : : showInfoDialog , pack . type , str , pack . components , ( soundBase : : soundID ) pack . soundID ) )
2017-08-10 18:39:27 +02:00
logNetwork - > warn ( " We received InfoWindow for not our player... " ) ;
2013-11-17 20:57:04 +03:00
}
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetObjectProperty ( SetObjectProperty & pack )
2009-07-30 15:49:45 +03:00
{
//inform all players that see this object
2023-02-12 09:23:39 +02:00
for ( auto it = cl . playerint . cbegin ( ) ; it ! = cl . playerint . cend ( ) ; + + it )
2009-07-30 15:49:45 +03:00
{
2023-02-12 09:23:39 +02:00
if ( gs . isVisible ( gs . getObjInstance ( pack . id ) , it - > first ) )
callInterfaceIfPresent ( cl , it - > first , & IGameEventsReceiver : : objectPropertyChanged , & pack ) ;
2009-07-30 15:49:45 +03:00
}
2023-03-15 00:30:58 +02:00
if ( pack . what = = ObjProperty : : OWNER )
{
2023-03-22 14:41:36 +02:00
// invalidate section of map view with our object and force an update with new flag color
2023-03-15 00:30:58 +02:00
CGI - > mh - > onObjectInstantRemove ( gs . getObjInstance ( pack . id ) ) ;
CGI - > mh - > onObjectInstantAdd ( gs . getObjInstance ( pack . id ) ) ;
}
2009-07-30 15:49:45 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitHeroLevelUp ( HeroLevelUp & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * hero = cl . getHero ( pack . heroId ) ;
2018-03-10 21:19:55 +02:00
assert ( hero ) ;
2023-02-12 09:23:39 +02:00
callOnlyThatInterface ( cl , pack . player , & CGameInterface : : heroGotLevel , hero , pack . primskill , pack . skills , pack . queryID ) ;
2009-03-07 17:55:56 +02:00
}
2012-07-15 18:34:00 +03:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitCommanderLevelUp ( CommanderLevelUp & pack )
2012-05-16 20:29:05 +03:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * hero = cl . getHero ( pack . heroId ) ;
2018-03-10 21:19:55 +02:00
assert ( hero ) ;
2013-04-20 14:34:01 +03:00
const CCommanderInstance * commander = hero - > commander ;
2018-02-03 16:44:30 +02:00
assert ( commander ) ;
assert ( commander - > armyObj ) ; //is it possible for Commander to exist beyond armed instance?
2023-02-12 09:23:39 +02:00
callOnlyThatInterface ( cl , pack . player , & CGameInterface : : commanderGotLevel , commander , pack . skills , pack . queryID ) ;
2012-05-16 20:29:05 +03:00
}
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBlockingDialog ( BlockingDialog & pack )
2009-03-07 17:55:56 +02:00
{
2009-07-09 22:15:22 +03:00
std : : string str ;
2023-02-12 09:23:39 +02:00
pack . text . toString ( str ) ;
2013-11-17 20:57:04 +03:00
2023-02-12 09:23:39 +02:00
if ( ! callOnlyThatInterface ( cl , pack . player , & CGameInterface : : showBlockingDialog , str , pack . components , pack . queryID , ( soundBase : : soundID ) pack . soundID , pack . selection ( ) , pack . cancel ( ) ) )
2017-08-10 18:39:27 +02:00
logNetwork - > warn ( " We received YesNoDialog for not our player... " ) ;
2013-11-17 20:57:04 +03:00
}
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitGarrisonDialog ( GarrisonDialog & pack )
2009-04-12 03:58:41 +03:00
{
2023-02-12 09:23:39 +02:00
const CGHeroInstance * h = cl . getHero ( pack . hid ) ;
const CArmedInstance * obj = static_cast < const CArmedInstance * > ( cl . getObj ( pack . objid ) ) ;
2009-04-12 03:58:41 +03:00
2023-02-12 09:23:39 +02:00
callOnlyThatInterface ( cl , h - > getOwner ( ) , & CGameInterface : : showGarrisonDialog , obj , h , pack . removableUnits , pack . queryID ) ;
2013-11-17 20:57:04 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitExchangeDialog ( ExchangeDialog & pack )
2013-05-27 13:53:28 +03:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . player , & IGameEventsReceiver : : heroExchangeStarted , pack . hero1 , pack . hero2 , pack . queryID ) ;
2013-05-27 13:53:28 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitTeleportDialog ( TeleportDialog & pack )
2015-03-08 15:37:33 +02:00
{
2023-02-12 09:23:39 +02:00
callOnlyThatInterface ( cl , pack . player , & CGameInterface : : showTeleportDialog , pack . channel , pack . exits , pack . impassable , pack . queryID ) ;
2015-03-08 15:37:33 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitMapObjectSelectDialog ( MapObjectSelectDialog & pack )
2017-06-06 06:53:51 +02:00
{
2023-02-12 09:23:39 +02:00
callOnlyThatInterface ( cl , pack . player , & CGameInterface : : showMapObjectSelectDialog , pack . queryID , pack . icon , pack . title , pack . description , pack . objects ) ;
2017-06-06 06:53:51 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitBattleStart ( BattleStart & pack )
2013-09-14 22:09:35 +03:00
{
2018-02-03 16:44:30 +02:00
// Cannot use the usual code because curB is not set yet
2023-02-12 09:23:39 +02:00
callOnlyThatBattleInterface ( cl , pack . info - > sides [ 0 ] . color , & IBattleEventsReceiver : : battleStartBefore , pack . info - > sides [ 0 ] . armyObject , pack . info - > sides [ 1 ] . armyObject ,
pack . info - > tile , pack . info - > sides [ 0 ] . hero , pack . info - > sides [ 1 ] . hero ) ;
callOnlyThatBattleInterface ( cl , pack . info - > sides [ 1 ] . color , & IBattleEventsReceiver : : battleStartBefore , pack . info - > sides [ 0 ] . armyObject , pack . info - > sides [ 1 ] . armyObject ,
pack . info - > tile , pack . info - > sides [ 0 ] . hero , pack . info - > sides [ 1 ] . hero ) ;
callOnlyThatBattleInterface ( cl , PlayerColor : : SPECTATOR , & IBattleEventsReceiver : : battleStartBefore , pack . info - > sides [ 0 ] . armyObject , pack . info - > sides [ 1 ] . armyObject ,
pack . info - > tile , pack . info - > sides [ 0 ] . hero , pack . info - > sides [ 1 ] . hero ) ;
2013-09-14 22:09:35 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleStart ( BattleStart & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
cl . battleStarted ( pack . info ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitBattleNextRound ( BattleNextRound & pack )
2010-05-07 15:29:41 +03:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleNewRoundFirst , pack . round ) ;
2010-05-07 15:29:41 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleNextRound ( BattleNextRound & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleNewRound , pack . round ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleSetActiveStack ( BattleSetActiveStack & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
if ( ! pack . askPlayerInterface )
2012-08-27 15:34:43 +03:00
return ;
2023-02-12 09:23:39 +02:00
const CStack * activated = gs . curB - > battleGetStackByID ( pack . stack ) ;
PlayerColor playerToCall ; //pack.player that will move activated stack
2016-10-28 23:37:20 +02:00
if ( activated - > hasBonusOfType ( Bonus : : HYPNOTIZED ) )
2009-08-18 14:49:34 +03:00
{
2023-02-12 09:23:39 +02:00
playerToCall = ( gs . curB - > sides [ 0 ] . color = = activated - > owner
? gs . curB - > sides [ 1 ] . color
: gs . curB - > sides [ 0 ] . color ) ;
2009-08-18 14:49:34 +03:00
}
else
{
playerToCall = activated - > owner ;
}
2017-11-16 13:15:43 +02:00
2023-02-12 09:23:39 +02:00
cl . startPlayerBattleAction ( playerToCall ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleLogMessage ( BattleLogMessage & pack )
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleLogMessage , pack . lines ) ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleTriggerEffect ( BattleTriggerEffect & pack )
2011-10-08 16:02:58 +03:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleTriggerEffect , pack ) ;
2011-10-08 16:02:58 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitBattleUpdateGateState ( BattleUpdateGateState & pack )
2016-02-10 06:10:32 +02:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleGateStateChanged , pack . state ) ;
2016-02-10 06:10:32 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitBattleResult ( BattleResult & pack )
2009-03-07 17:55:56 +02:00
{
2023-04-06 17:59:22 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleEnd , & pack , pack . queryID ) ;
2023-02-12 09:23:39 +02:00
cl . battleFinished ( ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitBattleStackMoved ( BattleStackMoved & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
const CStack * movedStack = gs . curB - > battleGetStackByID ( pack . stack ) ;
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleStackMoved , movedStack , pack . tilesToMove , pack . distance , pack . teleporting ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitBattleAttack ( BattleAttack & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleAttack , & pack ) ;
2023-03-25 16:00:25 +02:00
// battleStacksAttacked should be excuted before BattleAttack.applyGs() to play animation before damaging unit
// so this has to be here instead of ApplyClientNetPackVisitor::visitBattleAttack()
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleStacksAttacked , pack . bsa , pack . shot ( ) ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleAttack ( BattleAttack & pack )
2009-03-07 17:55:56 +02:00
{
}
2023-02-12 09:23:39 +02:00
void ApplyFirstClientNetPackVisitor : : visitStartAction ( StartAction & pack )
2009-03-07 17:55:56 +02:00
{
2023-04-16 19:42:56 +02:00
cl . curbaction = std : : make_optional ( pack . ba ) ;
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : actionStarted , pack . ba ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleSpellCast ( BattleSpellCast & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleSpellCast , & pack ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetStackEffect ( SetStackEffect & pack )
2009-03-07 17:55:56 +02:00
{
2009-03-21 18:03:07 +02:00
//informing about effects
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleStacksEffectsSet , pack ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitStacksInjured ( StacksInjured & pack )
2009-04-16 03:28:54 +03:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleStacksAttacked , pack . stacks , false ) ;
2009-04-16 03:28:54 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleResultsApplied ( BattleResultsApplied & pack )
2009-08-04 02:53:18 +03:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . player1 , & IGameEventsReceiver : : battleResultsApplied ) ;
callInterfaceIfPresent ( cl , pack . player2 , & IGameEventsReceiver : : battleResultsApplied ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , PlayerColor : : SPECTATOR , & IGameEventsReceiver : : battleResultsApplied ) ;
2009-08-04 02:53:18 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleUnitsChanged ( BattleUnitsChanged & pack )
2009-08-05 15:46:08 +03:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleUnitsChanged , pack . changedStacks ) ;
2009-08-05 15:46:08 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitBattleObstaclesChanged ( BattleObstaclesChanged & pack )
2009-08-19 13:59:42 +03:00
{
//inform interfaces about removed obstacles
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleObstaclesChanged , pack . changes ) ;
2009-08-19 13:59:42 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitCatapultAttack ( CatapultAttack & pack )
2009-09-01 16:54:13 +03:00
{
//inform interfaces about catapult attack
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : battleCatapultAttacked , pack ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitEndAction ( EndAction & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
callBattleInterfaceIfPresentForBothSides ( cl , & IBattleEventsReceiver : : actionFinished , * cl . curbaction ) ;
cl . curbaction . reset ( ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitPackageApplied ( PackageApplied & pack )
2009-04-16 03:28:54 +03:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . player , & IGameEventsReceiver : : requestRealized , & pack ) ;
if ( ! CClient : : waitingRequest . tryRemovingElement ( pack . requestID ) )
2018-01-05 19:21:07 +02:00
logNetwork - > warn ( " Surprising server message! PackageApplied for unknown requestID! " ) ;
2009-04-16 03:28:54 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSystemMessage ( SystemMessage & pack )
2009-03-07 17:55:56 +02:00
{
2009-04-04 22:26:41 +03:00
std : : ostringstream str ;
2023-02-12 09:23:39 +02:00
str < < " System message: " < < pack . text ;
2009-04-04 22:26:41 +03:00
2017-08-11 13:38:10 +02:00
logNetwork - > error ( str . str ( ) ) ; // usually used to receive error messages from server
2016-09-26 15:05:27 +02:00
if ( LOCPLINT & & ! settings [ " session " ] [ " hideSystemMessages " ] . Bool ( ) )
2009-04-04 22:26:41 +03:00
LOCPLINT - > cingconsole - > print ( str . str ( ) ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitPlayerBlocked ( PlayerBlocked & pack )
2009-08-04 02:53:18 +03:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . player , & IGameEventsReceiver : : playerBlocked , pack . reason , pack . startOrEnd = = PlayerBlocked : : BLOCKADE_STARTED ) ;
2009-08-04 02:53:18 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitYourTurn ( YourTurn & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
logNetwork - > debug ( " Server gives turn to %s " , pack . player . getStr ( ) ) ;
2018-01-05 19:21:07 +02:00
2023-02-12 09:23:39 +02:00
callAllInterfaces ( cl , & IGameEventsReceiver : : playerStartsTurn , pack . player ) ;
callOnlyThatInterface ( cl , pack . player , & CGameInterface : : yourTurn ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSaveGameClient ( SaveGameClient & pack )
2009-03-28 20:46:20 +02:00
{
2023-02-12 09:23:39 +02:00
const auto stem = FileInfo : : GetPathStem ( pack . fname ) ;
2022-10-06 13:54:46 +02:00
if ( ! CResourceHandler : : get ( " local " ) - > createResource ( stem . to_string ( ) + " .vcgm1 " ) )
{
logNetwork - > error ( " Failed to create resource %s " , stem . to_string ( ) + " .vcgm1 " ) ;
return ;
}
2012-08-07 14:28:52 +03:00
2012-06-09 22:58:17 +03:00
try
{
2016-01-26 15:51:38 +02:00
CSaveFile save ( * CResourceHandler : : get ( ) - > getResourceName ( ResourceID ( stem . to_string ( ) , EResType : : CLIENT_SAVEGAME ) ) ) ;
2023-02-12 09:23:39 +02:00
save < < cl ;
2012-06-09 22:58:17 +03:00
}
catch ( std : : exception & e )
{
2017-08-11 13:38:10 +02:00
logNetwork - > error ( " Failed to save game:%s " , e . what ( ) ) ;
2012-06-09 22:58:17 +03:00
}
2009-03-28 20:46:20 +02:00
}
2009-03-07 17:55:56 +02:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitPlayerMessageClient ( PlayerMessageClient & pack )
2009-03-07 17:55:56 +02:00
{
2023-02-12 09:23:39 +02:00
logNetwork - > debug ( " pack.player %s sends a message: %s " , pack . player . getStr ( ) , pack . text ) ;
2009-04-04 22:26:41 +03:00
2015-11-08 21:16:58 +02:00
std : : ostringstream str ;
2023-02-12 09:23:39 +02:00
if ( pack . player . isSpectator ( ) )
str < < " Spectator: " < < pack . text ;
2017-06-03 07:25:10 +02:00
else
2023-02-12 09:23:39 +02:00
str < < cl . getPlayerState ( pack . player ) - > nodeName ( ) < < " : " < < pack . text ;
2009-04-04 22:26:41 +03:00
if ( LOCPLINT )
LOCPLINT - > cingconsole - > print ( str . str ( ) ) ;
2009-03-07 17:55:56 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitAdvmapSpellCast ( AdvmapSpellCast & pack )
2010-05-16 16:42:19 +03:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
auto caster = cl . getHero ( pack . casterID ) ;
2018-03-10 21:19:55 +02:00
if ( caster )
//consider notifying other interfaces that see hero?
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , caster - > getOwner ( ) , & IGameEventsReceiver : : advmapSpellCast , caster , pack . spellID ) ;
2018-03-10 21:19:55 +02:00
else
logNetwork - > error ( " Invalid hero instance " ) ;
2010-05-16 16:42:19 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitShowWorldViewEx ( ShowWorldViewEx & pack )
2015-02-26 16:15:17 +02:00
{
2023-02-21 14:38:08 +02:00
callOnlyThatInterface ( cl , pack . player , & CGameInterface : : showWorldViewEx , pack . objectPositions , pack . showTerrain ) ;
2015-02-26 16:15:17 +02:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitOpenWindow ( OpenWindow & pack )
2009-06-16 14:18:14 +03:00
{
2023-02-12 09:23:39 +02:00
switch ( pack . window )
2009-07-06 22:41:27 +03:00
{
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : RECRUITMENT_FIRST :
case EOpenWindowMode : : RECRUITMENT_ALL :
2009-07-06 22:41:27 +03:00
{
2023-02-12 09:23:39 +02:00
const CGDwelling * dw = dynamic_cast < const CGDwelling * > ( cl . getObj ( ObjectInstanceID ( pack . id1 ) ) ) ;
const CArmedInstance * dst = dynamic_cast < const CArmedInstance * > ( cl . getObj ( ObjectInstanceID ( pack . id2 ) ) ) ;
2023-03-08 00:32:21 +02:00
callInterfaceIfPresent ( cl , dst - > tempOwner , & IGameEventsReceiver : : showRecruitmentDialog , dw , dst , pack . window = = EOpenWindowMode : : RECRUITMENT_FIRST ? 0 : - 1 ) ;
2009-07-06 22:41:27 +03:00
}
2009-07-26 06:33:13 +03:00
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : SHIPYARD_WINDOW :
2009-07-26 06:33:13 +03:00
{
2023-02-12 09:23:39 +02:00
const IShipyard * sy = IShipyard : : castFrom ( cl . getObj ( ObjectInstanceID ( pack . id1 ) ) ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , sy - > o - > tempOwner , & IGameEventsReceiver : : showShipyardDialog , sy ) ;
2009-07-26 06:33:13 +03:00
}
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : THIEVES_GUILD :
2010-02-07 17:06:14 +02:00
{
//displays Thieves' Guild window (when hero enters Den of Thieves)
2023-02-12 09:23:39 +02:00
const CGObjectInstance * obj = cl . getObj ( ObjectInstanceID ( pack . id2 ) ) ;
callInterfaceIfPresent ( cl , PlayerColor ( pack . id1 ) , & IGameEventsReceiver : : showThievesGuildWindow , obj ) ;
2010-02-07 17:06:14 +02:00
}
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : UNIVERSITY_WINDOW :
2010-07-20 17:08:13 +03:00
{
//displays University window (when hero enters University on adventure map)
2023-02-12 09:23:39 +02:00
const IMarket * market = IMarket : : castFrom ( cl . getObj ( ObjectInstanceID ( pack . id1 ) ) ) ;
const CGHeroInstance * hero = cl . getHero ( ObjectInstanceID ( pack . id2 ) ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , hero - > tempOwner , & IGameEventsReceiver : : showUniversityWindow , market , hero ) ;
2010-07-20 17:08:13 +03:00
}
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : MARKET_WINDOW :
2010-05-18 10:01:54 +03:00
{
//displays Thieves' Guild window (when hero enters Den of Thieves)
2023-02-12 09:23:39 +02:00
const CGObjectInstance * obj = cl . getObj ( ObjectInstanceID ( pack . id1 ) ) ;
const CGHeroInstance * hero = cl . getHero ( ObjectInstanceID ( pack . id2 ) ) ;
2010-05-18 10:01:54 +03:00
const IMarket * market = IMarket : : castFrom ( obj ) ;
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , cl . getTile ( obj - > visitablePos ( ) ) - > visitableObjects . back ( ) - > tempOwner , & IGameEventsReceiver : : showMarketWindow , market , hero ) ;
2010-05-18 10:01:54 +03:00
}
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : HILL_FORT_WINDOW :
2010-07-22 03:32:45 +03:00
{
//displays Hill fort window
2023-02-12 09:23:39 +02:00
const CGObjectInstance * obj = cl . getObj ( ObjectInstanceID ( pack . id1 ) ) ;
const CGHeroInstance * hero = cl . getHero ( ObjectInstanceID ( pack . id2 ) ) ;
callInterfaceIfPresent ( cl , cl . getTile ( obj - > visitablePos ( ) ) - > visitableObjects . back ( ) - > tempOwner , & IGameEventsReceiver : : showHillFortWindow , obj , hero ) ;
2010-07-22 03:32:45 +03:00
}
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : PUZZLE_MAP :
2010-02-10 04:56:00 +02:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , PlayerColor ( pack . id1 ) , & IGameEventsReceiver : : showPuzzleMap ) ;
2010-02-10 04:56:00 +02:00
}
2010-07-20 17:08:13 +03:00
break ;
2023-03-08 00:32:21 +02:00
case EOpenWindowMode : : TAVERN_WINDOW :
2023-02-12 09:23:39 +02:00
const CGObjectInstance * obj1 = cl . getObj ( ObjectInstanceID ( pack . id1 ) ) ,
* obj2 = cl . getObj ( ObjectInstanceID ( pack . id2 ) ) ;
2018-02-03 16:44:30 +02:00
callInterfaceIfPresent ( cl , obj1 - > tempOwner , & IGameEventsReceiver : : showTavernWindow , obj2 ) ;
2010-02-10 04:56:00 +02:00
break ;
2009-07-06 22:41:27 +03:00
}
2009-06-16 14:18:14 +03:00
}
2009-07-26 06:33:13 +03:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitCenterView ( CenterView & pack )
2009-08-11 10:50:29 +03:00
{
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , pack . player , & IGameEventsReceiver : : centerView , pack . pos , pack . focusTime ) ;
2009-08-11 10:50:29 +03:00
}
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitNewObject ( NewObject & pack )
2009-07-26 06:33:13 +03:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
2010-06-24 15:10:45 +03:00
2023-02-12 09:23:39 +02:00
const CGObjectInstance * obj = cl . getObj ( pack . id ) ;
2017-03-12 09:54:24 +02:00
if ( CGI - > mh )
2023-02-16 21:35:15 +02:00
CGI - > mh - > onObjectFadeIn ( obj ) ;
2011-08-25 23:02:38 +03:00
2023-02-12 09:23:39 +02:00
for ( auto i = cl . playerint . begin ( ) ; i ! = cl . playerint . end ( ) ; i + + )
2009-07-26 06:33:13 +03:00
{
2023-02-12 09:23:39 +02:00
if ( gs . isVisible ( obj , i - > first ) )
2009-07-26 06:33:13 +03:00
i - > second - > newObject ( obj ) ;
}
2023-02-18 17:37:09 +02:00
CGI - > mh - > waitForOngoingAnimations ( ) ;
2009-07-26 06:33:13 +03:00
}
2009-10-03 14:16:42 +03:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitSetAvailableArtifacts ( SetAvailableArtifacts & pack )
2010-06-27 19:03:01 +03:00
{
2023-02-12 09:23:39 +02:00
if ( pack . id < 0 ) //artifact merchants globally
2010-06-27 19:03:01 +03:00
{
2018-02-03 16:44:30 +02:00
callAllInterfaces ( cl , & IGameEventsReceiver : : availableArtifactsChanged , nullptr ) ;
2010-06-27 19:03:01 +03:00
}
else
{
2023-02-12 09:23:39 +02:00
const CGBlackMarket * bm = dynamic_cast < const CGBlackMarket * > ( cl . getObj ( ObjectInstanceID ( pack . id ) ) ) ;
2010-06-27 19:03:01 +03:00
assert ( bm ) ;
2023-02-12 09:23:39 +02:00
callInterfaceIfPresent ( cl , cl . getTile ( bm - > visitablePos ( ) ) - > visitableObjects . back ( ) - > tempOwner , & IGameEventsReceiver : : availableArtifactsChanged , bm ) ;
2010-06-27 19:03:01 +03:00
}
}
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
2023-02-12 09:23:39 +02:00
void ApplyClientNetPackVisitor : : visitEntitiesChanged ( EntitiesChanged & pack )
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
{
2023-02-12 09:23:39 +02:00
cl . invalidatePaths ( ) ;
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
}