2008-07-01 11:01:02 +03:00
# pragma once
2008-07-25 20:28:28 +03:00
# include "../global.h"
# include <set>
2008-08-22 15:21:09 +03:00
# include "../client/FunctionList.h"
2008-08-04 12:05:52 +03:00
# include "../CGameState.h"
# include "../lib/Connection.h"
2008-08-13 03:44:31 +03:00
# include <boost/function.hpp>
2008-08-04 23:27:47 +03:00
# include <boost/thread.hpp>
2008-07-25 20:28:28 +03:00
class CVCMIServer ;
class CGameState ;
struct StartInfo ;
2008-07-30 20:51:19 +03:00
class CCPPObjectScript ;
class CScriptCallback ;
2008-09-12 11:51:46 +03:00
struct BattleResult ;
2008-09-29 14:03:30 +03:00
struct BattleAttack ;
2008-10-18 14:41:24 +03:00
struct BattleStackAttacked ;
2008-07-26 16:57:32 +03:00
template < typename T > struct CPack ;
2008-08-13 03:44:31 +03:00
template < typename T > struct Query ;
2008-08-04 18:56:36 +03:00
class CGHeroInstance ;
2008-08-22 15:21:09 +03:00
extern std : : map < ui32 , CFunctionList < void ( ui32 ) > > callbacks ; //question id => callback functions - for selection dialogs
2008-08-13 03:44:31 +03:00
extern boost : : mutex gsm ;
struct PlayerStatus
{
bool makingTurn , engagedIntoBattle ;
std : : set < ui32 > queries ;
2008-11-16 03:06:15 +02:00
2008-08-13 03:44:31 +03:00
PlayerStatus ( ) : makingTurn ( false ) , engagedIntoBattle ( false ) { } ;
2008-11-16 03:06:15 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & makingTurn & engagedIntoBattle & queries ;
}
2008-08-13 03:44:31 +03:00
} ;
class PlayerStatuses
{
public :
std : : map < ui8 , PlayerStatus > players ;
boost : : mutex mx ;
boost : : condition_variable cv ; //notifies when any changes are made
2008-11-16 03:06:15 +02:00
2008-08-13 03:44:31 +03:00
void addPlayer ( ui8 player ) ;
PlayerStatus operator [ ] ( ui8 player ) ;
bool hasQueries ( ui8 player ) ;
bool checkFlag ( ui8 player , bool PlayerStatus : : * flag ) ;
void setFlag ( ui8 player , bool PlayerStatus : : * flag , bool val ) ;
void addQuery ( ui8 player , ui32 id ) ;
void removeQuery ( ui8 player , ui32 id ) ;
2008-11-16 03:06:15 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & players ;
}
2008-08-13 03:44:31 +03:00
} ;
2008-07-01 11:01:02 +03:00
class CGameHandler
{
2008-08-13 03:44:31 +03:00
static ui32 QID ;
2008-07-25 20:28:28 +03:00
CGameState * gs ;
2008-07-30 20:51:19 +03:00
std : : set < CCPPObjectScript * > cppscripts ; //C++ scripts
//std::map<int, std::map<std::string, CObjectScript*> > objscr; //non-C++ scripts
2008-07-25 20:28:28 +03:00
CVCMIServer * s ;
2008-08-04 18:56:36 +03:00
std : : map < int , CConnection * > connections ; //player color -> connection to clinet with interface of that player
2008-08-13 03:44:31 +03:00
PlayerStatuses states ; //player color -> player state
2008-07-25 20:28:28 +03:00
std : : set < CConnection * > conns ;
2008-07-30 20:51:19 +03:00
void handleCPPObjS ( std : : map < int , CCPPObjectScript * > * mapa , CCPPObjectScript * script ) ;
2008-08-04 18:56:36 +03:00
void changePrimSkill ( int ID , int which , int val , bool abs = false ) ;
2008-08-13 03:44:31 +03:00
void changeSecSkill ( int ID , ui16 which , int val , bool abs = false ) ;
2008-09-12 11:51:46 +03:00
void giveSpells ( const CGTownInstance * t , const CGHeroInstance * h ) ;
2008-08-09 02:02:32 +03:00
void moveStack ( int stack , int dest ) ;
2008-09-12 11:51:46 +03:00
void startBattle ( CCreatureSet army1 , CCreatureSet army2 , int3 tile , CGHeroInstance * hero1 , CGHeroInstance * hero2 , boost : : function < void ( BattleResult * ) > cb ) ; //use hero=NULL for no hero
2008-09-30 17:50:11 +03:00
void prepareAttack ( BattleAttack & bat , CStack * att , CStack * def ) ; //if last parameter is true, attack is by shooting, if false it's a melee attack
2008-10-18 14:41:24 +03:00
void prepareAttacked ( BattleStackAttacked & bsa , CStack * def ) ;
2008-09-09 10:05:02 +03:00
void checkForBattleEnd ( std : : vector < CStack * > & stacks ) ;
2008-08-15 15:11:42 +03:00
void setupBattle ( BattleInfo * curB , int3 tile , CCreatureSet & army1 , CCreatureSet & army2 , CGHeroInstance * hero1 , CGHeroInstance * hero2 ) ;
2008-07-30 20:51:19 +03:00
2008-07-01 11:01:02 +03:00
public :
CGameHandler ( void ) ;
~ CGameHandler ( void ) ;
2008-07-25 20:28:28 +03:00
void init ( StartInfo * si , int Seed ) ;
void handleConnection ( std : : set < int > players , CConnection & c ) ;
2008-11-16 03:06:15 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & QID & gs & cppscripts & states ;
}
2008-08-13 03:44:31 +03:00
template < typename T > void applyAndAsk ( Query < T > * sel , ui8 player , boost : : function < void ( ui32 ) > & callback )
{
gsm . lock ( ) ;
sel - > id = QID ;
callbacks [ QID ] = callback ;
states . addQuery ( player , QID ) ;
QID + + ;
sendAndApply ( sel ) ;
gsm . unlock ( ) ;
}
2008-08-22 15:21:09 +03:00
template < typename T > void ask ( Query < T > * sel , ui8 player , const CFunctionList < void ( ui32 ) > & callback )
2008-08-13 03:44:31 +03:00
{
gsm . lock ( ) ;
sel - > id = QID ;
callbacks [ QID ] = callback ;
states . addQuery ( player , QID ) ;
sendToAllClients ( sel ) ;
QID + + ;
gsm . unlock ( ) ;
}
2008-09-29 00:01:49 +03:00
template < typename T > void sendDataToClients ( const T & data )
{
for ( std : : set < CConnection * > : : iterator i = conns . begin ( ) ; i ! = conns . end ( ) ; i + + )
{
( * i ) - > wmx - > lock ( ) ;
* * i < < data ;
( * i ) - > wmx - > unlock ( ) ;
}
}
2008-07-30 20:51:19 +03:00
template < typename T > void sendToAllClients ( CPack < T > * info )
{
for ( std : : set < CConnection * > : : iterator i = conns . begin ( ) ; i ! = conns . end ( ) ; i + + )
{
2008-08-04 18:56:36 +03:00
( * i ) - > wmx - > lock ( ) ;
2008-07-30 20:51:19 +03:00
* * i < < info - > getType ( ) < < * info - > This ( ) ;
2008-08-04 18:56:36 +03:00
( * i ) - > wmx - > unlock ( ) ;
2008-07-30 20:51:19 +03:00
}
}
template < typename T > void sendAndApply ( CPack < T > * info )
{
gs - > apply ( info ) ;
sendToAllClients ( info ) ;
}
2008-07-25 20:28:28 +03:00
void run ( ) ;
void newTurn ( ) ;
friend class CVCMIServer ;
2008-07-30 20:51:19 +03:00
friend class CScriptCallback ;
2008-07-01 11:01:02 +03:00
} ;