2017-07-13 10:26:03 +02:00
/*
* Client . 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
*
*/
2023-04-04 21:54:30 +02:00
# include "Global.h"
2011-12-14 00:23:17 +03:00
# include "StdInc.h"
2014-07-15 10:14:49 +03:00
# include "Client.h"
2009-05-20 13:08:56 +03:00
# include "CGameInfo.h"
# include "CPlayerInterface.h"
2023-03-15 21:34:29 +02:00
# include "CServerHandler.h"
2023-02-12 09:23:39 +02:00
# include "ClientNetPackVisitors.h"
2023-05-08 14:18:34 +02:00
# include "adventureMap/AdventureMapInterface.h"
2022-12-09 13:38:46 +02:00
# include "battle/BattleInterface.h"
2023-03-15 21:34:29 +02:00
# include "gui/CGuiHandler.h"
2023-05-16 14:10:26 +02:00
# include "gui/WindowHandler.h"
2023-03-15 21:34:29 +02:00
# include "mapView/mapHandler.h"
# include "../CCallback.h"
# include "../lib/CConfigHandler.h"
2023-06-23 17:02:48 +02:00
# include "../lib/gameState/CGameState.h"
2011-12-14 00:23:17 +03:00
# include "../lib/CThreadHelper.h"
2023-03-15 21:34:29 +02:00
# include "../lib/VCMIDirs.h"
# include "../lib/battle/BattleInfo.h"
# include "../lib/serializer/BinaryDeserializer.h"
# include "../lib/mapping/CMapService.h"
2023-06-21 12:46:09 +02:00
# include "../lib/pathfinder/CGPathNode.h"
2023-03-15 21:34:29 +02:00
# include "../lib/filesystem/Filesystem.h"
2014-02-24 22:57:33 +03:00
# include "../lib/registerTypes/RegisterTypes.h"
2023-03-15 21:34:29 +02:00
# include "../lib/serializer/Connection.h"
2023-04-04 21:54:30 +02:00
# include <memory>
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
# include <vcmi/events/EventBus.h>
2011-05-10 01:20:47 +03:00
2023-03-13 23:26:44 +02:00
# if SCRIPTING_ENABLED
# include "../lib/ScriptHandler.h"
# endif
2017-06-04 14:59:11 +02:00
# ifdef VCMI_ANDROID
2017-05-25 19:57:20 +02:00
# include "lib/CAndroidVMHelper.h"
2008-07-28 15:44:08 +03:00
2023-02-26 11:18:24 +02:00
# ifndef SINGLE_PROCESS_APP
2017-05-25 19:57:20 +02:00
std : : atomic_bool androidTestServerReadyFlag ;
# endif
2023-02-26 11:18:24 +02:00
# endif
2017-05-25 19:57:20 +02:00
2017-07-12 16:02:25 +02:00
ThreadSafeVector < int > CClient : : waitingRequest ;
2018-01-05 19:21:07 +02:00
template < typename T > class CApplyOnCL ;
2010-09-03 21:42:54 +03:00
2009-03-07 00:25:19 +02:00
class CBaseForCLApply
{
public :
2018-01-05 19:21:07 +02:00
virtual void applyOnClAfter ( CClient * cl , void * pack ) const = 0 ;
virtual void applyOnClBefore ( CClient * cl , void * pack ) const = 0 ;
2010-01-02 03:48:44 +02:00
virtual ~ CBaseForCLApply ( ) { }
2010-09-03 21:42:54 +03:00
2018-01-05 19:21:07 +02:00
template < typename U > static CBaseForCLApply * getApplier ( const U * t = nullptr )
2010-09-03 21:42:54 +03:00
{
2017-07-16 11:58:05 +02:00
return new CApplyOnCL < U > ( ) ;
2010-09-03 21:42:54 +03:00
}
2009-03-07 00:25:19 +02:00
} ;
2010-09-03 21:42:54 +03:00
2018-01-05 19:21:07 +02:00
template < typename T > class CApplyOnCL : public CBaseForCLApply
2009-03-07 00:25:19 +02:00
{
public :
2018-01-05 19:21:07 +02:00
void applyOnClAfter ( CClient * cl , void * pack ) const override
2009-03-07 00:25:19 +02:00
{
2018-01-05 19:21:07 +02:00
T * ptr = static_cast < T * > ( pack ) ;
2023-02-12 09:23:39 +02:00
ApplyClientNetPackVisitor visitor ( * cl , * cl - > gameState ( ) ) ;
ptr - > visit ( visitor ) ;
2009-03-07 00:25:19 +02:00
}
2018-01-05 19:21:07 +02:00
void applyOnClBefore ( CClient * cl , void * pack ) const override
2009-03-07 00:25:19 +02:00
{
2018-01-05 19:21:07 +02:00
T * ptr = static_cast < T * > ( pack ) ;
2023-02-12 09:23:39 +02:00
ApplyFirstClientNetPackVisitor visitor ( * cl , * cl - > gameState ( ) ) ;
ptr - > visit ( visitor ) ;
2009-03-07 00:25:19 +02:00
}
} ;
2018-01-05 19:21:07 +02:00
template < > class CApplyOnCL < CPack > : public CBaseForCLApply
2014-02-19 04:04:27 +03:00
{
public :
2018-01-05 19:21:07 +02:00
void applyOnClAfter ( CClient * cl , void * pack ) const override
2014-02-19 04:04:27 +03:00
{
2017-08-10 18:39:27 +02:00
logGlobal - > error ( " Cannot apply on CL plain CPack! " ) ;
2014-02-19 04:04:27 +03:00
assert ( 0 ) ;
}
2018-01-05 19:21:07 +02:00
void applyOnClBefore ( CClient * cl , void * pack ) const override
2014-02-19 04:04:27 +03:00
{
2017-08-10 18:39:27 +02:00
logGlobal - > error ( " Cannot apply on CL plain CPack! " ) ;
2014-02-19 04:04:27 +03:00
assert ( 0 ) ;
}
} ;
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
CPlayerEnvironment : : CPlayerEnvironment ( PlayerColor player_ , CClient * cl_ , std : : shared_ptr < CCallback > mainCallback_ )
: player ( player_ ) ,
cl ( cl_ ) ,
mainCallback ( mainCallback_ )
{
}
const Services * CPlayerEnvironment : : services ( ) const
{
return VLC ;
}
vstd : : CLoggerBase * CPlayerEnvironment : : logger ( ) const
{
return logGlobal ;
}
events : : EventBus * CPlayerEnvironment : : eventBus ( ) const
{
return cl - > eventBus ( ) ; //always get actual value
}
const CPlayerEnvironment : : BattleCb * CPlayerEnvironment : : battle ( ) const
{
return mainCallback . get ( ) ;
}
const CPlayerEnvironment : : GameCb * CPlayerEnvironment : : game ( ) const
{
return mainCallback . get ( ) ;
}
2014-02-19 04:04:27 +03:00
2018-01-05 19:21:07 +02:00
CClient : : CClient ( )
2008-07-25 20:28:28 +03:00
{
2017-07-12 16:02:25 +02:00
waitingRequest . clear ( ) ;
2018-01-05 19:21:07 +02:00
applier = std : : make_shared < CApplier < CBaseForCLApply > > ( ) ;
2014-02-24 22:57:33 +03:00
registerTypesClientPacks1 ( * applier ) ;
registerTypesClientPacks2 ( * applier ) ;
2009-02-01 16:11:41 +02:00
IObjectInterface : : cb = this ;
2013-05-09 14:09:23 +03:00
gs = nullptr ;
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
}
CClient : : ~ CClient ( )
{
IObjectInterface : : cb = nullptr ;
}
const Services * CClient : : services ( ) const
{
return VLC ; //todo: this should be CGI
}
const CClient : : BattleCb * CClient : : battle ( ) const
{
return this ;
}
const CClient : : GameCb * CClient : : game ( ) const
{
return this ;
}
vstd : : CLoggerBase * CClient : : logger ( ) const
{
return logGlobal ;
}
events : : EventBus * CClient : : eventBus ( ) const
{
return clientEventBus . get ( ) ;
2009-01-30 23:28:02 +02:00
}
2022-09-30 16:28:17 +02:00
void CClient : : newGame ( CGameState * initializedGameState )
2009-01-30 23:28:02 +02:00
{
2018-01-05 19:21:07 +02:00
CSH - > th - > update ( ) ;
CMapService mapService ;
2022-09-30 16:28:17 +02:00
gs = initializedGameState ? initializedGameState : new CGameState ( ) ;
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
gs - > preInit ( VLC ) ;
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " \t Creating gamestate: %i " , CSH - > th - > getDiff ( ) ) ;
2022-09-30 16:28:17 +02:00
if ( ! initializedGameState )
2022-09-28 21:15:05 +02:00
gs - > init ( & mapService , CSH - > si . get ( ) , settings [ " general " ] [ " saveRandomMaps " ] . Bool ( ) ) ;
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " Initializing GameState (together): %d ms " , CSH - > th - > getDiff ( ) ) ;
2010-09-03 21:42:54 +03:00
2018-01-05 19:21:07 +02:00
initMapHandler ( ) ;
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
reinitScripting ( ) ;
initPlayerEnvironments ( ) ;
2018-01-05 19:21:07 +02:00
initPlayerInterfaces ( ) ;
2008-07-25 20:28:28 +03:00
}
2010-09-03 21:42:54 +03:00
2022-09-30 16:28:17 +02:00
void CClient : : loadGame ( CGameState * initializedGameState )
2008-07-25 20:28:28 +03:00
{
2018-01-05 19:21:07 +02:00
logNetwork - > info ( " Loading procedure started! " ) ;
2023-03-13 11:10:44 +02:00
logNetwork - > info ( " Game state was transferred over network, loading. " ) ;
gs = initializedGameState ;
gs - > preInit ( VLC ) ;
gs - > updateOnLoad ( CSH - > si . get ( ) ) ;
logNetwork - > info ( " Game loaded, initialize interfaces. " ) ;
initMapHandler ( ) ;
reinitScripting ( ) ;
initPlayerEnvironments ( ) ;
2022-10-02 23:48:03 +02:00
2023-03-17 16:00:47 +02:00
// Loading of client state - disabled for now
// Since client no longer writes or loads its own state and instead receives it from server
// client state serializer will serialize its own copies of all pointers, e.g. heroes/towns/objects
// and on deserialize will create its own copies (instead of using copies from state received from server)
// Potential solutions:
// 1) Use server gamestate to deserialize pointers, so any pointer to same object will point to server instance and not our copy
// 2) Remove all serialization of pointers with instance ID's and restore them on load (including AI deserializer code)
// 3) Completely remove client savegame and send all information, like hero paths and sleeping status to server (either in form of hero properties or as some generic "client options" message
# ifdef BROKEN_CLIENT_STATE_SERIALIZATION_HAS_BEEN_FIXED
2023-03-13 11:10:44 +02:00
// try to deserialize client data including sleepingHeroes
2023-03-12 22:54:51 +02:00
try
2008-08-30 00:41:32 +03:00
{
2023-03-12 22:54:51 +02:00
boost : : filesystem : : path clientSaveName = * CResourceHandler : : get ( " local " ) - > getResourceName ( ResourceID ( CSH - > si - > mapname , EResType : : CLIENT_SAVEGAME ) ) ;
if ( clientSaveName . empty ( ) )
throw std : : runtime_error ( " Cannot open client part of " + CSH - > si - > mapname ) ;
2023-03-13 13:27:13 +02:00
std : : unique_ptr < CLoadFile > loader ( new CLoadFile ( clientSaveName ) ) ;
2023-03-13 11:10:44 +02:00
serialize ( loader - > serializer , loader - > serializer . fileVersion ) ;
2023-03-12 22:54:51 +02:00
2023-03-13 11:10:44 +02:00
logNetwork - > info ( " Client data loaded. " ) ;
2022-09-29 19:33:44 +02:00
}
2023-03-12 22:54:51 +02:00
catch ( std : : exception & e )
2022-09-29 19:33:44 +02:00
{
2023-03-13 11:10:44 +02:00
logGlobal - > info ( " Cannot load client data for game %s. Error: %s " , CSH - > si - > mapname , e . what ( ) ) ;
2012-02-20 00:03:43 +03:00
}
2023-03-17 16:00:47 +02:00
# endif
2023-03-12 22:54:51 +02:00
2018-01-05 19:21:07 +02:00
initPlayerInterfaces ( ) ;
}
void CClient : : serialize ( BinarySerializer & h , const int version )
{
assert ( h . saving ) ;
2020-10-01 10:38:06 +02:00
ui8 players = static_cast < ui8 > ( playerint . size ( ) ) ;
2018-01-05 19:21:07 +02:00
h & players ;
for ( auto i = playerint . begin ( ) ; i ! = playerint . end ( ) ; i + + )
2015-02-14 21:42:47 +02:00
{
2018-01-05 19:21:07 +02:00
logGlobal - > trace ( " Saving player %s interface " , i - > first ) ;
assert ( i - > first = = i - > second - > playerID ) ;
h & i - > first ;
h & i - > second - > dllName ;
h & i - > second - > human ;
i - > second - > saveGame ( h , version ) ;
2015-02-14 21:42:47 +02: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
2022-09-21 18:31:14 +02:00
# if SCRIPTING_ENABLED
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
if ( version > = 800 )
{
JsonNode scriptsState ;
clientScripts - > serializeState ( h . saving , scriptsState ) ;
h & scriptsState ;
}
2022-09-21 18:31:14 +02:00
# endif
2008-08-04 18:56:36 +03:00
}
2009-12-28 06:08:24 +02:00
2018-01-05 19:21:07 +02:00
void CClient : : serialize ( BinaryDeserializer & h , const int version )
2008-07-25 20:28:28 +03:00
{
2018-01-05 19:21:07 +02:00
assert ( ! h . saving ) ;
ui8 players = 0 ;
h & players ;
for ( int i = 0 ; i < players ; i + + )
{
std : : string dllname ;
PlayerColor pid ;
bool isHuman = false ;
2022-03-20 12:18:30 +02:00
auto prevInt = LOCPLINT ;
2018-01-05 19:21:07 +02:00
h & pid ;
h & dllname ;
h & isHuman ;
assert ( dllname . length ( ) = = 0 | | ! isHuman ) ;
if ( pid = = PlayerColor : : NEUTRAL )
2009-03-07 17:54:12 +02:00
{
2018-01-05 19:21:07 +02:00
logGlobal - > trace ( " Neutral battle interfaces are not serialized. " ) ;
continue ;
}
logGlobal - > trace ( " Loading player %s interface " , pid ) ;
std : : shared_ptr < CGameInterface > nInt ;
if ( dllname . length ( ) )
nInt = CDynLibHandler : : getNewAI ( dllname ) ;
else
nInt = std : : make_shared < CPlayerInterface > ( pid ) ;
2016-01-16 17:36:16 +02:00
2018-01-05 19:21:07 +02:00
nInt - > dllName = dllname ;
nInt - > human = isHuman ;
nInt - > playerID = pid ;
2009-11-01 03:15:16 +02:00
2023-03-13 12:04:06 +02:00
bool shouldResetInterface = true ;
2018-01-05 19:21:07 +02:00
// Client no longer handle this player at all
if ( ! vstd : : contains ( CSH - > getAllClientPlayers ( CSH - > c - > connectionID ) , pid ) )
{
logGlobal - > trace ( " Player %s is not belong to this client. Destroying interface " , pid ) ;
2009-03-07 17:54:12 +02:00
}
2018-01-05 19:21:07 +02:00
else if ( isHuman & & ! vstd : : contains ( CSH - > getHumanColors ( ) , pid ) )
2010-01-29 22:52:45 +02:00
{
2018-01-05 19:21:07 +02:00
logGlobal - > trace ( " Player %s is no longer controlled by human. Destroying interface " , pid ) ;
}
else if ( ! isHuman & & vstd : : contains ( CSH - > getHumanColors ( ) , pid ) )
{
logGlobal - > trace ( " Player %s is no longer controlled by AI. Destroying interface " , pid ) ;
}
else
{
installNewPlayerInterface ( nInt , pid ) ;
2023-03-13 12:04:06 +02:00
shouldResetInterface = false ;
}
// loadGame needs to be called after initGameInterface to load paths correctly
// initGameInterface is called in installNewPlayerInterface
nInt - > loadGame ( h , version ) ;
if ( shouldResetInterface )
{
nInt . reset ( ) ;
LOCPLINT = prevInt ;
2010-01-29 22:52:45 +02: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
2022-09-21 18:31:14 +02:00
# if SCRIPTING_ENABLED
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
{
JsonNode scriptsState ;
2022-06-20 16:39:50 +02:00
h & scriptsState ;
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
clientScripts - > serializeState ( h . saving , scriptsState ) ;
}
2022-09-21 18:31:14 +02:00
# endif
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
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " Loaded client part of save %d ms " , CSH - > th - > getDiff ( ) ) ;
2008-08-04 12:05:52 +03:00
}
2008-11-16 03:06:15 +02:00
void CClient : : save ( const std : : string & fname )
{
2009-02-11 19:03:30 +02:00
if ( gs - > curB )
{
2017-08-10 18:39:27 +02:00
logNetwork - > error ( " Game cannot be saved during battle! " ) ;
2009-02-11 19:03:30 +02:00
return ;
}
2011-06-11 07:54:41 +03:00
SaveGame save_game ( fname ) ;
2018-01-05 19:21:07 +02:00
sendRequest ( & save_game , PlayerColor : : NEUTRAL ) ;
2008-11-16 03:06:15 +02:00
}
2008-12-27 03:01:59 +02:00
2018-01-05 19:21:07 +02:00
void CClient : : endGame ( )
2009-01-11 00:08:18 +02:00
{
2022-09-21 18:31:14 +02:00
# if SCRIPTING_ENABLED
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
clientScripts . reset ( ) ;
2022-09-21 18:31:14 +02:00
# endif
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
2012-02-22 16:41:27 +03:00
//suggest interfaces to finish their stuff (AI should interrupt any bg working threads)
2018-01-05 19:21:07 +02:00
for ( auto & i : playerint )
2012-02-22 16:41:27 +03:00
i . second - > finish ( ) ;
2013-06-26 14:18:27 +03:00
GH . curInt = nullptr ;
2022-12-21 17:02:53 +02:00
{
boost : : unique_lock < boost : : recursive_mutex > un ( * CPlayerInterface : : pim ) ;
logNetwork - > info ( " Ending current game! " ) ;
removeGUI ( ) ;
vstd : : clear_pointer ( const_cast < CGameInfo * > ( CGI ) - > mh ) ;
vstd : : clear_pointer ( gs ) ;
logNetwork - > info ( " Deleted mapHandler and gameState. " ) ;
}
2023-04-04 21:54:30 +02:00
//threads cleanup has to be after gs cleanup and before battleints cleanup to stop tacticThread
cleanThreads ( ) ;
2023-04-20 18:56:35 +02:00
CPlayerInterface : : battleInt . reset ( ) ;
2022-12-21 17:02:53 +02:00
playerint . clear ( ) ;
2013-12-06 22:44:11 +03:00
battleints . clear ( ) ;
2013-06-22 17:47:20 +03:00
battleCallbacks . clear ( ) ;
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
playerEnvironments . clear ( ) ;
2017-08-10 18:39:27 +02:00
logNetwork - > info ( " Deleted playerInts. " ) ;
logNetwork - > info ( " Client stopped. " ) ;
2009-11-01 03:15:16 +02:00
}
2018-01-05 19:21:07 +02:00
void CClient : : initMapHandler ( )
2014-10-21 15:11:54 +03:00
{
2018-01-05 19:21:07 +02:00
// TODO: CMapHandler initialization can probably go somewhere else
// It's can't be before initialization of interfaces
// During loading CPlayerInterface from serialized state it's depend on MH
if ( ! settings [ " session " ] [ " headless " ] . Bool ( ) )
2014-10-21 15:11:54 +03:00
{
2023-02-16 21:35:15 +02:00
const_cast < CGameInfo * > ( CGI ) - > mh = new CMapHandler ( gs - > map ) ;
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " Creating mapHandler: %d ms " , CSH - > th - > getDiff ( ) ) ;
2016-03-12 03:41:27 +02:00
}
2019-01-15 05:00:00 +02:00
pathCache . clear ( ) ;
2009-01-11 00:08:18 +02: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
void CClient : : initPlayerEnvironments ( )
{
playerEnvironments . clear ( ) ;
auto allPlayers = CSH - > getAllClientPlayers ( CSH - > c - > connectionID ) ;
2023-04-13 00:01:13 +02:00
bool hasHumanPlayer = false ;
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
for ( auto & color : allPlayers )
{
logNetwork - > info ( " Preparing environment for player %s " , color . getStr ( ) ) ;
playerEnvironments [ color ] = std : : make_shared < CPlayerEnvironment > ( color , this , std : : make_shared < CCallback > ( gs , color , this ) ) ;
2023-04-13 00:01:13 +02:00
if ( ! hasHumanPlayer & & gs - > players [ color ] . isHuman ( ) )
hasHumanPlayer = true ;
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-04-13 00:01:13 +02:00
if ( ! hasHumanPlayer )
{
Settings session = settings . write [ " session " ] ;
session [ " spectate " ] . Bool ( ) = true ;
session [ " spectate-skip-battle-result " ] . Bool ( ) = true ;
2023-04-13 22:22:47 +02:00
session [ " spectate-ignore-hero " ] . Bool ( ) = true ;
2023-04-13 00:01:13 +02: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
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) )
{
2023-04-16 19:42:56 +02:00
playerEnvironments [ PlayerColor : : SPECTATOR ] = std : : make_shared < CPlayerEnvironment > ( PlayerColor : : SPECTATOR , this , std : : make_shared < CCallback > ( gs , std : : nullopt , this ) ) ;
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
}
}
2018-01-05 19:21:07 +02:00
void CClient : : initPlayerInterfaces ( )
2009-01-11 00:08:18 +02:00
{
2023-06-29 18:09:47 +02:00
for ( auto & playerInfo : gs - > scenarioOps - > playerInfos )
2013-02-19 02:10:46 +03:00
{
2023-06-29 18:09:47 +02:00
PlayerColor color = playerInfo . first ;
2018-01-05 19:21:07 +02:00
if ( ! vstd : : contains ( CSH - > getAllClientPlayers ( CSH - > c - > connectionID ) , color ) )
continue ;
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
if ( ! vstd : : contains ( playerint , color ) )
2010-02-20 15:24:38 +02: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
logNetwork - > info ( " Preparing interface for player %s " , color . getStr ( ) ) ;
2023-06-29 18:09:47 +02:00
if ( playerInfo . second . isControlledByAI ( ) )
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-06-29 18:09:47 +02:00
bool alliedToHuman = false ;
for ( auto & allyInfo : gs - > scenarioOps - > playerInfos )
if ( gs - > getPlayerTeam ( allyInfo . first ) = = gs - > getPlayerTeam ( playerInfo . first ) & & allyInfo . second . isControlledByHuman ( ) )
alliedToHuman = true ;
auto AiToGive = aiNameForPlayer ( playerInfo . second , false , alliedToHuman ) ;
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
logNetwork - > info ( " Player %s will be lead by %s " , color . getStr ( ) , AiToGive ) ;
installNewPlayerInterface ( CDynLibHandler : : getNewAI ( AiToGive ) , color ) ;
}
else
{
logNetwork - > info ( " Player %s will be lead by human " , color . getStr ( ) ) ;
installNewPlayerInterface ( std : : make_shared < CPlayerInterface > ( color ) , color ) ;
}
2009-01-11 00:08:18 +02:00
}
}
2010-02-20 15:24:38 +02:00
2017-07-01 15:30:13 +02:00
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) )
2010-12-25 03:43:40 +02:00
{
2017-07-01 15:30:13 +02:00
installNewPlayerInterface ( std : : make_shared < CPlayerInterface > ( PlayerColor : : SPECTATOR ) , PlayerColor : : SPECTATOR , true ) ;
2010-12-25 03:43:40 +02:00
}
2018-01-05 19:21:07 +02:00
if ( CSH - > getAllClientPlayers ( CSH - > c - > connectionID ) . count ( PlayerColor : : NEUTRAL ) )
installNewBattleInterface ( CDynLibHandler : : getNewBattleAI ( settings [ " server " ] [ " neutralAI " ] . String ( ) ) , PlayerColor : : NEUTRAL ) ;
logNetwork - > trace ( " Initialized player interfaces %d ms " , CSH - > th - > getDiff ( ) ) ;
2009-01-11 00:08:18 +02:00
}
2023-06-29 18:09:47 +02:00
std : : string CClient : : aiNameForPlayer ( const PlayerSettings & ps , bool battleAI , bool alliedToHuman )
2009-03-28 20:46:20 +02:00
{
2018-01-05 19:21:07 +02:00
if ( ps . name . size ( ) )
2009-03-28 20:46:20 +02:00
{
2018-01-05 19:21:07 +02:00
const boost : : filesystem : : path aiPath = VCMIDirs : : get ( ) . fullLibraryPath ( " AI " , ps . name ) ;
if ( boost : : filesystem : : exists ( aiPath ) )
return ps . name ;
2009-03-28 20:46:20 +02:00
}
2018-01-05 19:21:07 +02:00
2023-06-29 18:09:47 +02:00
return aiNameForPlayer ( battleAI , alliedToHuman ) ;
2014-12-21 21:33:20 +02:00
}
2023-06-29 18:09:47 +02:00
std : : string CClient : : aiNameForPlayer ( bool battleAI , bool alliedToHuman )
2014-12-21 21:33:20 +02:00
{
2018-01-05 19:21:07 +02:00
const int sensibleAILimit = settings [ " session " ] [ " oneGoodAI " ] . Bool ( ) ? 1 : PlayerColor : : PLAYER_LIMIT_I ;
2023-06-29 18:09:47 +02:00
std : : string goodAdventureAI = alliedToHuman ? settings [ " server " ] [ " alliedAI " ] . String ( ) : settings [ " server " ] [ " playerAI " ] . String ( ) ;
std : : string goodBattleAI = settings [ " server " ] [ " neutralAI " ] . String ( ) ;
std : : string goodAI = battleAI ? goodBattleAI : goodAdventureAI ;
2018-01-05 19:21:07 +02:00
std : : string badAI = battleAI ? " StupidAI " : " EmptyAI " ;
2009-07-18 06:13:13 +03:00
2018-01-05 19:21:07 +02:00
//TODO what about human players
if ( battleints . size ( ) > = sensibleAILimit )
return badAI ;
2011-02-27 21:58:14 +02:00
2018-01-05 19:21:07 +02:00
return goodAI ;
2009-03-28 20:46:20 +02: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
void CClient : : installNewPlayerInterface ( std : : shared_ptr < CGameInterface > gameInterface , PlayerColor color , bool battlecb )
2014-10-21 15:11:54 +03:00
{
2018-01-05 19:21:07 +02:00
boost : : unique_lock < boost : : recursive_mutex > un ( * CPlayerInterface : : pim ) ;
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
playerint [ color ] = gameInterface ;
2018-01-05 19:21:07 +02: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
logGlobal - > trace ( " \t Initializing the interface for player %s " , color . getStr ( ) ) ;
2018-01-05 19:21:07 +02:00
auto cb = std : : make_shared < CCallback > ( gs , color , this ) ;
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
battleCallbacks [ color ] = cb ;
2022-12-07 21:50:45 +02:00
gameInterface - > initGameInterface ( playerEnvironments . at ( color ) , cb ) ;
2018-01-05 19:21:07 +02:00
installNewBattleInterface ( gameInterface , color , battlecb ) ;
2014-12-21 21:33:20 +02: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
void CClient : : installNewBattleInterface ( std : : shared_ptr < CBattleGameInterface > battleInterface , PlayerColor color , bool needCallback )
2014-12-21 21:33:20 +02:00
{
2018-01-05 19:21:07 +02:00
boost : : unique_lock < boost : : recursive_mutex > un ( * CPlayerInterface : : pim ) ;
2014-10-21 15:11:54 +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
battleints [ color ] = battleInterface ;
2014-10-21 15:11:54 +03:00
2018-01-05 19:21:07 +02:00
if ( needCallback )
{
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
logGlobal - > trace ( " \t Initializing the battle interface for player %s " , color . getStr ( ) ) ;
2018-01-05 19:21:07 +02:00
auto cbc = std : : make_shared < CBattleCallback > ( color , this ) ;
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
battleCallbacks [ color ] = cbc ;
2022-12-07 21:50:45 +02:00
battleInterface - > initBattleInterface ( playerEnvironments . at ( color ) , cbc ) ;
2014-10-21 15:11:54 +03:00
}
}
2018-01-05 19:21:07 +02:00
void CClient : : handlePack ( CPack * pack )
2014-10-25 12:04:08 +03:00
{
2018-01-05 19:21:07 +02:00
CBaseForCLApply * apply = applier - > getApplier ( typeList . getTypeID ( pack ) ) ; //find the applier
2010-01-02 03:48:44 +02:00
if ( apply )
{
2016-11-25 21:12:22 +02:00
boost : : unique_lock < boost : : recursive_mutex > guiLock ( * CPlayerInterface : : pim ) ;
2016-10-02 22:41:57 +02:00
apply - > applyOnClBefore ( this , pack ) ;
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " \t Made first apply on cl: %s " , typeList . getTypeInfo ( pack ) - > name ( ) ) ;
2010-01-02 03:48:44 +02:00
gs - > apply ( pack ) ;
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " \t Applied on gs: %s " , typeList . getTypeInfo ( pack ) - > name ( ) ) ;
2016-10-02 22:41:57 +02:00
apply - > applyOnClAfter ( this , pack ) ;
2018-01-05 19:21:07 +02:00
logNetwork - > trace ( " \t Made second apply on cl: %s " , typeList . getTypeInfo ( pack ) - > name ( ) ) ;
2010-01-02 03:48:44 +02:00
}
else
{
2016-11-18 16:45:59 +02:00
logNetwork - > error ( " Message %s cannot be applied, cannot find applier! " , typeList . getTypeInfo ( pack ) - > name ( ) ) ;
2010-01-02 03:48:44 +02:00
}
delete pack ;
}
2009-08-04 02:53:18 +03:00
2018-01-05 19:21:07 +02:00
int CClient : : sendRequest ( const CPackForServer * request , PlayerColor player )
2010-08-20 16:34:39 +03:00
{
2018-01-05 19:21:07 +02:00
static ui32 requestCounter = 0 ;
2010-08-20 16:34:39 +03:00
2018-01-05 19:21:07 +02:00
ui32 requestID = requestCounter + + ;
logNetwork - > trace ( " Sending a request \" %s \" . It'll have an ID=%d. " , typeid ( * request ) . name ( ) , requestID ) ;
2011-01-17 18:07:08 +02:00
2018-01-05 19:21:07 +02:00
waitingRequest . pushBack ( requestID ) ;
request - > requestID = requestID ;
request - > player = player ;
CSH - > c - > sendPack ( request ) ;
if ( vstd : : contains ( playerint , player ) )
playerint [ player ] - > requestSent ( request , requestID ) ;
2017-07-12 18:40:14 +02:00
2018-01-05 19:21:07 +02:00
return requestID ;
2010-08-20 16:34:39 +03:00
}
2010-12-23 02:33:48 +02:00
void CClient : : battleStarted ( const BattleInfo * info )
{
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
setBattle ( info ) ;
2021-03-23 16:47:07 +02:00
2018-01-05 19:21:07 +02:00
for ( auto & battleCb : battleCallbacks )
2012-08-26 12:07:48 +03:00
{
2016-01-16 17:36:16 +02:00
if ( vstd : : contains_if ( info - > sides , [ & ] ( const SideInBattle & side ) { return side . color = = battleCb . first ; } )
2018-01-05 19:21:07 +02:00
| | battleCb . first > = PlayerColor : : PLAYER_LIMIT )
2013-07-22 01:01:29 +03:00
{
2012-08-26 12:07:48 +03:00
battleCb . second - > setBattle ( info ) ;
2013-07-22 01:01:29 +03:00
}
2012-08-26 12:07:48 +03:00
}
2015-12-29 04:43:33 +02:00
std : : shared_ptr < CPlayerInterface > att , def ;
2018-01-05 19:21:07 +02:00
auto & leftSide = info - > sides [ 0 ] , & rightSide = info - > sides [ 1 ] ;
2010-12-23 02:33:48 +02:00
2013-06-23 14:25:48 +03:00
//If quick combat is not, do not prepare interfaces for battleint
2023-04-06 17:34:07 +02:00
auto callBattleStart = [ & ] ( PlayerColor color , ui8 side )
2013-06-23 14:25:48 +03:00
{
2023-04-06 17:34:07 +02:00
if ( vstd : : contains ( battleints , color ) )
battleints [ color ] - > battleStart ( leftSide . armyObject , rightSide . armyObject , info - > tile , leftSide . hero , rightSide . hero , side ) ;
} ;
callBattleStart ( leftSide . color , 0 ) ;
callBattleStart ( rightSide . color , 1 ) ;
callBattleStart ( PlayerColor : : UNFLAGGABLE , 1 ) ;
2023-04-13 22:18:29 +02:00
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) & & ! settings [ " session " ] [ " spectate-skip-battle " ] . Bool ( ) )
2023-04-06 17:34:07 +02:00
callBattleStart ( PlayerColor : : SPECTATOR , 1 ) ;
if ( vstd : : contains ( playerint , leftSide . color ) & & playerint [ leftSide . color ] - > human )
att = std : : dynamic_pointer_cast < CPlayerInterface > ( playerint [ leftSide . color ] ) ;
2013-06-23 14:25:48 +03:00
2023-04-06 17:34:07 +02:00
if ( vstd : : contains ( playerint , rightSide . color ) & & playerint [ rightSide . color ] - > human )
def = std : : dynamic_pointer_cast < CPlayerInterface > ( playerint [ rightSide . color ] ) ;
//Remove player interfaces for auto battle (quickCombat option)
if ( att & & att - > isAutoFightOn )
{
att . reset ( ) ;
def . reset ( ) ;
2013-06-23 14:25:48 +03:00
}
2023-04-13 22:20:51 +02:00
if ( ! settings [ " session " ] [ " headless " ] . Bool ( ) )
2012-02-20 00:03:43 +03:00
{
2017-07-01 15:30:13 +02:00
if ( ! ! att | | ! ! def )
2017-06-03 07:25:10 +02:00
{
boost : : unique_lock < boost : : recursive_mutex > un ( * CPlayerInterface : : pim ) ;
2022-12-21 17:02:53 +02:00
CPlayerInterface : : battleInt = std : : make_shared < BattleInterface > ( leftSide . armyObject , rightSide . armyObject , leftSide . hero , rightSide . hero , att , def ) ;
2017-06-03 07:25:10 +02:00
}
2023-04-13 22:20:51 +02:00
else if ( settings [ " session " ] [ " spectate " ] . Bool ( ) & & ! settings [ " session " ] [ " spectate-skip-battle " ] . Bool ( ) )
2017-06-03 07:25:10 +02:00
{
//TODO: This certainly need improvement
2023-04-13 22:20:51 +02:00
auto spectratorInt = std : : dynamic_pointer_cast < CPlayerInterface > ( playerint [ PlayerColor : : SPECTATOR ] ) ;
spectratorInt - > cb - > setBattle ( info ) ;
2017-06-03 07:25:10 +02:00
boost : : unique_lock < boost : : recursive_mutex > un ( * CPlayerInterface : : pim ) ;
2023-04-13 22:20:51 +02:00
CPlayerInterface : : battleInt = std : : make_shared < BattleInterface > ( leftSide . armyObject , rightSide . armyObject , leftSide . hero , rightSide . hero , att , def , spectratorInt ) ;
2017-06-03 07:25:10 +02:00
}
2012-02-20 00:03:43 +03:00
}
2010-12-23 02:33:48 +02:00
2018-01-05 19:21:07 +02:00
if ( info - > tacticDistance & & vstd : : contains ( battleints , info - > sides [ info - > tacticsSide ] . color ) )
2011-08-25 18:24:37 +03:00
{
2023-04-04 21:54:30 +02:00
PlayerColor color = info - > sides [ info - > tacticsSide ] . color ;
playerTacticThreads [ color ] = std : : make_unique < boost : : thread > ( & CClient : : commenceTacticPhaseForInt , this , battleints [ color ] ) ;
2011-08-25 18:24:37 +03:00
}
2010-12-23 02:33:48 +02:00
}
2015-12-29 04:43:33 +02:00
void CClient : : commenceTacticPhaseForInt ( std : : shared_ptr < CBattleGameInterface > battleInt )
2011-08-25 18:24:37 +03:00
{
2012-06-27 23:44:01 +03:00
setThreadName ( " CClient::commenceTacticPhaseForInt " ) ;
2011-08-25 18:24:37 +03:00
try
{
battleInt - > yourTacticPhase ( gs - > curB - > tacticDistance ) ;
2011-08-26 00:08:53 +03:00
if ( gs & & ! ! gs - > curB & & gs - > curB - > tacticDistance ) //while awaiting for end of tactics phase, many things can happen (end of battle... or game)
{
2023-04-16 19:42:56 +02:00
MakeAction ma ( BattleAction : : makeEndOFTacticPhase ( gs - > curB - > playerToSide ( battleInt - > playerID ) . value ( ) ) ) ;
2012-03-26 01:46:14 +03:00
sendRequest ( & ma , battleInt - > playerID ) ;
2011-08-26 00:08:53 +03:00
}
2015-02-14 21:42:47 +02:00
}
catch ( . . . )
{
handleException ( ) ;
2016-01-16 17:36:16 +02:00
}
2011-08-25 18:24:37 +03:00
}
2018-01-05 19:21:07 +02:00
void CClient : : battleFinished ( )
2017-03-14 01:40:39 +02:00
{
2018-01-05 19:21:07 +02:00
stopAllBattleActions ( ) ;
for ( auto & side : gs - > curB - > sides )
if ( battleCallbacks . count ( side . color ) )
battleCallbacks [ side . color ] - > setBattle ( nullptr ) ;
2013-06-22 17:47:20 +03:00
2023-04-13 22:20:51 +02:00
if ( settings [ " session " ] [ " spectate " ] . Bool ( ) & & ! settings [ " session " ] [ " spectate-skip-battle " ] . Bool ( ) )
2018-01-05 19:21:07 +02:00
battleCallbacks [ PlayerColor : : SPECTATOR ] - > setBattle ( nullptr ) ;
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
setBattle ( nullptr ) ;
2023-04-11 15:25:19 +02:00
gs - > curB . dellNull ( ) ;
2013-06-22 17:47:20 +03:00
}
2017-11-16 13:15:43 +02:00
void CClient : : startPlayerBattleAction ( PlayerColor color )
{
stopPlayerBattleAction ( color ) ;
if ( vstd : : contains ( battleints , color ) )
{
auto thread = std : : make_shared < boost : : thread > ( std : : bind ( & CClient : : waitForMoveAndSend , this , color ) ) ;
playerActionThreads [ color ] = thread ;
}
}
void CClient : : stopPlayerBattleAction ( PlayerColor color )
{
if ( vstd : : contains ( playerActionThreads , color ) )
{
auto thread = playerActionThreads . at ( color ) ;
if ( thread - > joinable ( ) )
{
thread - > interrupt ( ) ;
thread - > join ( ) ;
}
playerActionThreads . erase ( color ) ;
}
}
void CClient : : stopAllBattleActions ( )
{
while ( ! playerActionThreads . empty ( ) )
stopPlayerBattleAction ( playerActionThreads . begin ( ) - > first ) ;
}
2018-01-05 19:21:07 +02:00
void CClient : : waitForMoveAndSend ( PlayerColor color )
2010-09-03 21:42:54 +03:00
{
2018-01-05 19:21:07 +02:00
try
2017-06-04 14:59:11 +02:00
{
2018-01-05 19:21:07 +02:00
setThreadName ( " CClient::waitForMoveAndSend " ) ;
assert ( vstd : : contains ( battleints , color ) ) ;
BattleAction ba = battleints [ color ] - > activeStack ( gs - > curB - > battleGetStackByID ( gs - > curB - > activeStack , false ) ) ;
if ( ba . actionType ! = EActionType : : CANCEL )
{
logNetwork - > trace ( " Send battle action to server: %s " , ba . toString ( ) ) ;
MakeAction temp_action ( ba ) ;
sendRequest ( & temp_action , color ) ;
}
2017-06-04 14:59:11 +02:00
}
2018-01-05 19:21:07 +02:00
catch ( boost : : thread_interrupted & )
2010-09-03 21:42:54 +03:00
{
2018-01-05 19:21:07 +02:00
logNetwork - > debug ( " Wait for move thread was interrupted and no action will be send. Was a battle ended by spell? " ) ;
2016-03-12 03:41:27 +02:00
}
catch ( . . . )
{
2018-01-05 19:21:07 +02:00
handleException ( ) ;
2016-03-12 03:41:27 +02:00
}
2010-09-03 21:42:54 +03:00
}
2018-01-05 19:21:07 +02:00
void CClient : : invalidatePaths ( )
2010-09-03 21:42:54 +03:00
{
2019-01-15 05:00:00 +02:00
boost : : unique_lock < boost : : mutex > pathLock ( pathCacheMutex ) ;
pathCache . clear ( ) ;
2010-09-03 21:42:54 +03:00
}
2019-01-15 05:00:00 +02:00
std : : shared_ptr < const CPathsInfo > CClient : : getPathsInfo ( const CGHeroInstance * h )
2010-09-03 21:42:54 +03:00
{
2018-01-05 19:21:07 +02:00
assert ( h ) ;
2019-01-15 05:00:00 +02:00
boost : : unique_lock < boost : : mutex > pathLock ( pathCacheMutex ) ;
auto iter = pathCache . find ( h ) ;
if ( iter = = std : : end ( pathCache ) )
{
std : : shared_ptr < CPathsInfo > paths = std : : make_shared < CPathsInfo > ( getMapSize ( ) , h ) ;
gs - > calculatePaths ( h , * paths . get ( ) ) ;
pathCache [ h ] = paths ;
return paths ;
}
else
2012-11-16 00:29:22 +03:00
{
2019-01-15 05:00:00 +02:00
return iter - > second ;
2012-11-16 00:29:22 +03:00
}
2010-09-03 21:42:54 +03:00
}
2010-10-24 14:35:14 +03:00
2018-01-05 19:21:07 +02:00
PlayerColor CClient : : getLocalPlayer ( ) const
2010-10-24 14:35:14 +03:00
{
2018-01-05 19:21:07 +02:00
if ( LOCPLINT )
return LOCPLINT - > playerID ;
return getCurrentPlayer ( ) ;
2010-10-31 00:53:41 +03:00
}
2017-05-25 19:57:20 +02:00
2022-09-21 18:31:14 +02:00
# if SCRIPTING_ENABLED
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
scripting : : Pool * CClient : : getGlobalContextPool ( ) const
{
return clientScripts . get ( ) ;
}
scripting : : Pool * CClient : : getContextPool ( ) const
{
return clientScripts . get ( ) ;
}
2022-09-21 18:31:14 +02:00
# endif
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
void CClient : : reinitScripting ( )
{
2022-12-07 23:36:20 +02:00
clientEventBus = std : : make_unique < events : : EventBus > ( ) ;
2022-09-21 18:31:14 +02:00
# if SCRIPTING_ENABLED
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
clientScripts . reset ( new scripting : : PoolImpl ( this ) ) ;
2022-09-21 18:31:14 +02:00
# endif
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-01-11 18:11:44 +02:00
void CClient : : removeGUI ( )
{
// CClient::endGame
GH . curInt = nullptr ;
2023-05-16 15:07:03 +02:00
GH . windows ( ) . clear ( ) ;
2023-05-16 17:34:23 +02:00
adventureInt . reset ( ) ;
2023-01-11 18:11:44 +02:00
logGlobal - > info ( " Removed GUI. " ) ;
LOCPLINT = nullptr ;
}
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-04-04 21:54:30 +02:00
void CClient : : cleanThreads ( )
{
stopAllBattleActions ( ) ;
while ( ! playerTacticThreads . empty ( ) )
{
PlayerColor color = playerTacticThreads . begin ( ) - > first ;
//set tacticcMode of the players to false to stop tacticThread
if ( vstd : : contains ( battleints , color ) )
battleints [ color ] - > forceEndTacticPhase ( ) ;
playerTacticThreads [ color ] - > join ( ) ;
playerTacticThreads . erase ( color ) ;
}
}
2017-05-25 19:57:20 +02:00
# ifdef VCMI_ANDROID
2023-02-26 11:18:24 +02:00
# ifndef SINGLE_PROCESS_APP
2023-01-25 08:59:59 +02:00
extern " C " JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerClosed ( JNIEnv * env , jclass cls )
2020-01-06 18:43:02 +02:00
{
logNetwork - > info ( " Received server closed signal " ) ;
if ( CSH ) {
CSH - > campaignServerRestartLock . setn ( false ) ;
}
}
2023-01-25 08:59:59 +02:00
extern " C " JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerReady ( JNIEnv * env , jclass cls )
2017-05-25 19:57:20 +02:00
{
2017-08-10 18:39:27 +02:00
logNetwork - > info ( " Received server ready signal " ) ;
2017-05-25 19:57:20 +02:00
androidTestServerReadyFlag . store ( true ) ;
}
2023-02-26 11:18:24 +02:00
# endif
2017-05-25 19:57:20 +02:00
2023-01-25 08:59:59 +02:00
extern " C " JNIEXPORT jboolean JNICALL Java_eu_vcmi_vcmi_NativeMethods_tryToSaveTheGame ( JNIEnv * env , jclass cls )
2017-05-25 19:57:20 +02:00
{
2017-08-10 18:39:27 +02:00
logGlobal - > info ( " Received emergency save game request " ) ;
2017-05-25 19:57:20 +02:00
if ( ! LOCPLINT | | ! LOCPLINT - > cb )
{
return false ;
}
LOCPLINT - > cb - > save ( " Saves/_Android_Autosave " ) ;
return true ;
}
# endif