2008-12-27 03:01:59 +02:00
# ifndef __CGAMEHANDLER_H__
# define __CGAMEHANDLER_H__
# include "../global.h"
# include <set>
2010-08-25 17:57:58 +03:00
# include <map>
2008-12-27 03:01:59 +02:00
# include "../client/FunctionList.h"
2009-05-20 13:08:56 +03:00
# include "../lib/CGameState.h"
2008-12-27 03:01:59 +02:00
# include "../lib/Connection.h"
# include "../lib/IGameCallback.h"
2009-03-09 12:37:49 +02:00
# include "../lib/BattleAction.h"
2010-08-18 17:24:30 +03:00
# include "../lib/NetPacks.h"
2008-12-27 03:01:59 +02:00
# include <boost/function.hpp>
# include <boost/thread.hpp>
2009-04-15 17:03:31 +03:00
/*
* CGameHandler . h , 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
*
*/
2008-12-27 03:01:59 +02:00
class CVCMIServer ;
class CGameState ;
struct StartInfo ;
class CCPPObjectScript ;
class CScriptCallback ;
struct BattleResult ;
struct BattleAttack ;
struct BattleStackAttacked ;
2009-03-07 00:11:17 +02:00
struct CPack ;
struct Query ;
2010-01-30 14:46:15 +02:00
struct SetGarrisons ;
struct SetResource ;
struct SetResources ;
struct NewStructures ;
2008-12-27 03:01:59 +02:00
class CGHeroInstance ;
2010-05-18 10:01:54 +03:00
class IMarket ;
2008-12-27 03:01:59 +02:00
extern std : : map < ui32 , CFunctionList < void ( ui32 ) > > callbacks ; //question id => callback functions - for selection dialogs
extern boost : : mutex gsm ;
struct PlayerStatus
{
bool makingTurn , engagedIntoBattle ;
std : : set < ui32 > queries ;
PlayerStatus ( ) : makingTurn ( false ) , engagedIntoBattle ( false ) { } ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & makingTurn & engagedIntoBattle & queries ;
}
} ;
class PlayerStatuses
{
public :
std : : map < ui8 , PlayerStatus > players ;
boost : : mutex mx ;
boost : : condition_variable cv ; //notifies when any changes are made
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 ) ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & players ;
}
} ;
class CGameHandler : public IGameCallback
{
2010-12-04 21:15:20 +02:00
private :
void makeStackDoNothing ( const CStack * next ) ;
2009-03-09 12:37:49 +02:00
public :
2008-12-27 03:01:59 +02:00
CVCMIServer * s ;
2009-04-12 03:58:41 +03:00
std : : map < int , CConnection * > connections ; //player color -> connection to client with interface of that player
2008-12-27 03:01:59 +02:00
PlayerStatuses states ; //player color -> player state
std : : set < CConnection * > conns ;
2009-04-12 03:58:41 +03:00
//queries stuff
2009-04-12 04:48:50 +03:00
boost : : recursive_mutex gsm ;
2009-04-12 03:58:41 +03:00
ui32 QID ;
std : : map < ui32 , CFunctionList < void ( ui32 ) > > callbacks ; //query id => callback function - for selection and yes/no dialogs
std : : map < ui32 , boost : : function < void ( ) > > garrisonCallbacks ; //query id => callback - for garrison dialogs
std : : map < ui32 , std : : pair < si32 , si32 > > allowedExchanges ;
bool isAllowedExchange ( int id1 , int id2 ) ;
2008-12-27 03:01:59 +02:00
void giveSpells ( const CGTownInstance * t , const CGHeroInstance * h ) ;
2009-08-22 18:29:30 +03:00
int moveStack ( int stack , int dest ) ; //returned value - travelled distance
2010-12-06 01:10:02 +02:00
void takeCasualties ( const CArmedInstance * army , BattleInfo * bat ) ;
2009-08-22 16:59:15 +03:00
void startBattle ( const CArmedInstance * army1 , const CArmedInstance * army2 , int3 tile , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 , bool creatureBank , boost : : function < void ( BattleResult * ) > cb , const CGTownInstance * town = NULL ) ; //use hero=NULL for no hero
2010-01-29 22:52:45 +02:00
void checkLossVictory ( ui8 player ) ;
void winLoseHandle ( ui8 players = 255 ) ; //players: bit field - colours of players to be checked; default: all
2010-02-02 01:30:03 +02:00
void getLossVicMessage ( ui8 player , ui8 standard , bool victory , InfoWindow & out ) const ;
2010-01-29 22:52:45 +02:00
2009-09-28 17:21:48 +03:00
////used only in endBattle - don't touch elsewhere
boost : : function < void ( BattleResult * ) > * battleEndCallback ;
const CArmedInstance * bEndArmy1 , * bEndArmy2 ;
2010-05-27 00:59:58 +03:00
bool visitObjectAfterVictory ;
2009-09-28 17:21:48 +03:00
//
void endBattle ( int3 tile , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 ) ; //ends battle
2009-09-15 15:20:11 +03:00
void prepareAttack ( BattleAttack & bat , const CStack * att , const CStack * def , int distance ) ; //distance - number of hexes travelled before attacking
void prepareAttacked ( BattleStackAttacked & bsa , const CStack * def ) ;
2008-12-27 03:01:59 +02:00
void checkForBattleEnd ( std : : vector < CStack * > & stacks ) ;
2010-05-02 21:20:26 +03:00
void setupBattle ( BattleInfo * curB , int3 tile , const CArmedInstance * army1 , const CArmedInstance * army2 , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 , bool creatureBank , const CGTownInstance * town ) ;
2008-12-27 03:01:59 +02:00
CGameHandler ( void ) ;
~ CGameHandler ( void ) ;
//////////////////////////////////////////////////////////////////////////
//from IGameCallback
//get info
int getCurrentPlayer ( ) ;
int getSelectedHero ( ) ;
//do sth
void changeSpells ( int hid , bool give , const std : : set < ui32 > & spells ) ;
2009-04-16 03:28:54 +03:00
bool removeObject ( int objid ) ;
2008-12-27 03:01:59 +02:00
void setBlockVis ( int objid , bool bv ) ;
void setOwner ( int objid , ui8 owner ) ;
void setHoverName ( int objid , MetaString * name ) ;
2009-08-17 13:02:29 +03:00
void setObjProperty ( int objid , int prop , si64 val ) ;
2010-07-29 01:39:56 +03:00
void levelUpHero ( int ID , int skill ) ; //handle client respond and send one more request if needed
void levelUpHero ( int ID ) ; //initial call - check if hero have remaining levelups & handle them
2009-08-16 18:39:18 +03:00
void changePrimSkill ( int ID , int which , si64 val , bool abs = false ) ;
2009-01-11 00:08:18 +02:00
void changeSecSkill ( int ID , int which , int val , bool abs = false ) ;
2008-12-27 03:01:59 +02:00
void showInfoDialog ( InfoWindow * iw ) ;
2009-04-11 04:32:50 +03:00
void showBlockingDialog ( BlockingDialog * iw , const CFunctionList < void ( ui32 ) > & callback ) ;
ui32 showBlockingDialog ( BlockingDialog * iw ) ; //synchronous version of above
2009-09-09 20:49:03 +03:00
void showGarrisonDialog ( int upobj , int hid , bool removableUnits , const boost : : function < void ( ) > & cb ) ;
2010-02-06 15:49:14 +02:00
void showThievesGuildWindow ( int requestingObjId ) ; //TODO: make something more general?
2008-12-27 03:01:59 +02:00
void giveResource ( int player , int which , int val ) ;
2010-12-10 01:10:28 +02:00
void giveCreatures ( int objid , const CGHeroInstance * h , CCreatureSet & creatures , bool remove ) ;
2010-11-22 02:34:46 +02:00
void takeCreatures ( int objid , std : : vector < CStackBasicDescriptor > creatures ) ;
2010-11-27 22:17:28 +02:00
bool changeStackType ( const StackLocation & sl , CCreature * c ) ;
bool changeStackCount ( const StackLocation & sl , TQuantity count , bool absoluteValue = false ) ;
bool insertNewStack ( const StackLocation & sl , const CCreature * c , TQuantity count ) ;
bool eraseStack ( const StackLocation & sl ) ;
bool swapStacks ( const StackLocation & sl1 , const StackLocation & sl2 ) ;
bool addToSlot ( const StackLocation & sl , const CCreature * c , TQuantity count ) ;
void tryJoiningArmy ( const CArmedInstance * src , const CArmedInstance * dst , bool removeObjWhenFinished ) ;
bool moveStack ( const StackLocation & src , const StackLocation & dst , TQuantity count = - 1 ) ;
2008-12-27 03:01:59 +02:00
void showCompInfo ( ShowInInfobox * comp ) ;
void heroVisitCastle ( int obj , int heroID ) ;
2009-10-04 17:20:19 +03:00
void vistiCastleObjects ( const CGTownInstance * t , const CGHeroInstance * h ) ;
2008-12-27 03:01:59 +02:00
void stopHeroVisitCastle ( int obj , int heroID ) ;
void giveHeroArtifact ( int artid , int hid , int position ) ; //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
2010-11-10 02:06:25 +02:00
void giveNewArtifact ( int hid , int position ) ;
bool removeArtifact ( CArtifact * art , int hid ) ;
2009-09-13 01:17:23 +03:00
void startBattleI ( const CArmedInstance * army1 , const CArmedInstance * army2 , int3 tile , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 , bool creatureBank = false , boost : : function < void ( BattleResult * ) > cb = 0 , const CGTownInstance * town = NULL ) ; //use hero=NULL for no hero
void startBattleI ( const CArmedInstance * army1 , const CArmedInstance * army2 , int3 tile , boost : : function < void ( BattleResult * ) > cb = 0 , bool creatureBank = false ) ; //if any of armies is hero, hero will be used
void startBattleI ( const CArmedInstance * army1 , const CArmedInstance * army2 , boost : : function < void ( BattleResult * ) > cb = 0 , bool creatureBank = false ) ; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle//void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
2008-12-27 03:01:59 +02:00
void setAmount ( int objid , ui32 val ) ;
2010-06-30 22:27:35 +03:00
bool teleportHero ( si32 hid , si32 dstid , ui8 source , ui8 asker = 255 ) ;
2009-04-16 03:28:54 +03:00
bool moveHero ( si32 hid , int3 dst , ui8 instant , ui8 asker = 255 ) ;
2010-06-01 00:14:15 +03:00
bool tryAttackingGuard ( const int3 & guardPos , const CGHeroInstance * h ) ;
2010-05-27 00:59:58 +03:00
void visitObjectOnTile ( const TerrainTile & t , const CGHeroInstance * h ) ;
2009-02-04 15:40:54 +02:00
void giveHeroBonus ( GiveBonus * bonus ) ;
void setMovePoints ( SetMovePoints * smp ) ;
2009-02-06 13:15:39 +02:00
void setManaPoints ( int hid , int val ) ;
2009-02-14 21:12:40 +02:00
void giveHero ( int id , int player ) ;
2009-02-20 12:36:15 +02:00
void changeObjPos ( int objid , int3 newPos , ui8 flags ) ;
2010-02-06 15:27:58 +02:00
void useScholarSkill ( si32 hero1 , si32 hero2 ) ;
2009-06-16 14:18:14 +03:00
void heroExchange ( si32 hero1 , si32 hero2 ) ;
2010-08-24 17:26:57 +03:00
void setPortalDwelling ( const CGTownInstance * town , bool forced , bool clear ) ;
2008-12-27 03:01:59 +02:00
//////////////////////////////////////////////////////////////////////////
void init ( StartInfo * si , int Seed ) ;
void handleConnection ( std : : set < int > players , CConnection & c ) ;
2009-03-09 12:37:49 +02:00
int getPlayerAt ( CConnection * c ) const ;
void playerMessage ( ui8 player , const std : : string & message ) ;
2009-04-16 03:28:54 +03:00
bool makeBattleAction ( BattleAction & ba ) ;
2010-02-24 20:11:08 +02:00
void handleSpellCasting ( int spellID , int spellLvl , int destination , ui8 casterSide , ui8 casterColor , const CGHeroInstance * caster , const CGHeroInstance * secHero , int usedSpellPower ) ;
2009-04-16 03:28:54 +03:00
bool makeCustomAction ( BattleAction & ba ) ;
bool queryReply ( ui32 qid , ui32 answer ) ;
2010-07-09 02:03:27 +03:00
bool hireHero ( const CGObjectInstance * obj , ui8 hid , ui8 player ) ;
2009-07-26 06:33:13 +03:00
bool buildBoat ( ui32 objid ) ;
2009-04-16 03:28:54 +03:00
bool setFormation ( si32 hid , ui8 formation ) ;
2010-05-18 10:01:54 +03:00
bool tradeResources ( const IMarket * market , ui32 val , ui8 player , ui32 id1 , ui32 id2 ) ;
2010-07-20 09:05:45 +03:00
bool sacrificeCreatures ( const IMarket * market , const CGHeroInstance * hero , TSlot slot , ui32 count ) ;
2010-05-08 01:10:32 +03:00
bool sendResources ( ui32 val , ui8 player , ui32 r1 , ui32 r2 ) ;
2010-05-26 12:47:53 +03:00
bool sellCreatures ( ui32 count , const IMarket * market , const CGHeroInstance * hero , ui32 slot , ui32 resourceID ) ;
2010-07-03 15:00:53 +03:00
bool transformInUndead ( const IMarket * market , const CGHeroInstance * hero , ui32 slot ) ;
2010-02-16 16:39:56 +02:00
bool assembleArtifacts ( si32 heroID , ui16 artifactSlot , bool assemble , ui32 assembleTo ) ;
2010-06-27 19:03:01 +03:00
bool buyArtifact ( ui32 hid , si32 aid ) ; //for blacksmith and mage guild only -> buying for gold in common buildings
bool buyArtifact ( const IMarket * m , const CGHeroInstance * h , int rid , int aid ) ; //for artifact merchant and black market -> buying for any resource in special building / advobject
2010-07-20 17:08:13 +03:00
bool buySecSkill ( const IMarket * m , const CGHeroInstance * h , int skill ) ;
2009-11-10 05:10:14 +02:00
bool swapArtifacts ( si32 srcHeroID , si32 destHeroID , ui16 srcSlot , ui16 destSlot ) ;
2009-04-16 03:28:54 +03:00
bool garrisonSwap ( si32 tid ) ;
bool upgradeCreature ( ui32 objid , ui8 pos , ui32 upgID ) ;
2010-07-10 19:50:23 +03:00
bool recruitCreatures ( si32 objid , ui32 crid , ui32 cram , si32 level ) ;
2010-08-18 17:24:30 +03:00
bool buildStructure ( si32 tid , si32 bid , bool force = false ) ; //force - for events: no cost, no checkings
2009-09-22 17:27:46 +03:00
bool razeStructure ( si32 tid , si32 bid ) ;
2009-04-16 03:28:54 +03:00
bool disbandCreature ( si32 id , ui8 pos ) ;
2010-08-12 18:54:25 +03:00
bool arrangeStacks ( si32 id1 , si32 id2 , ui8 what , ui8 p1 , ui8 p2 , si32 val , ui8 player ) ;
2009-03-09 12:37:49 +02:00
void save ( const std : : string & fname ) ;
void close ( ) ;
2009-03-09 21:40:43 +02:00
void handleTimeEvents ( ) ;
2010-08-25 17:57:58 +03:00
void handleTownEvents ( CGTownInstance * town , NewTurn & n , std : : map < si32 , std : : map < si32 , si32 > > & newCreas ) ;
2009-03-27 01:05:40 +02:00
bool complain ( const std : : string & problem ) ; //sends message to all clients, prints on the logs and return true
2009-07-06 22:41:27 +03:00
void objectVisited ( const CGObjectInstance * obj , const CGHeroInstance * h ) ;
2009-08-04 02:53:18 +03:00
void engageIntoBattle ( ui8 player ) ;
2010-02-21 17:03:30 +02:00
bool dig ( const CGHeroInstance * h ) ;
2010-03-11 01:16:30 +02:00
bool castSpell ( const CGHeroInstance * h , int spellID , const int3 & pos ) ;
2009-03-09 12:37:49 +02:00
2008-12-27 03:01:59 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2009-01-11 00:08:18 +02:00
h & QID & states ;
2008-12-27 03:01:59 +02:00
}
2009-03-09 12:37:49 +02:00
2009-04-11 04:32:50 +03:00
ui32 getQueryResult ( ui8 player , int queryID ) ;
2009-03-09 12:37:49 +02:00
void sendMessageToAll ( const std : : string & message ) ;
void sendMessageTo ( CConnection & c , const std : : string & message ) ;
2009-03-07 00:11:17 +02:00
void applyAndAsk ( Query * sel , ui8 player , boost : : function < void ( ui32 ) > & callback ) ;
void ask ( Query * sel , ui8 player , const CFunctionList < void ( ui32 ) > & callback ) ;
2009-03-09 12:37:49 +02:00
void sendToAllClients ( CPackForClient * info ) ;
void sendAndApply ( CPackForClient * info ) ;
2010-12-06 01:10:02 +02:00
void sendAndApply ( CGarrisonOperationPack * info ) ;
//void sendAndApply(SetGarrisons * info);
2010-01-30 14:46:15 +02:00
void sendAndApply ( SetResource * info ) ;
void sendAndApply ( SetResources * info ) ;
void sendAndApply ( NewStructures * info ) ;
2009-03-09 12:37:49 +02:00
2010-10-24 14:35:14 +03:00
void run ( bool resume ) ;
2008-12-27 03:01:59 +02:00
void newTurn ( ) ;
2010-02-23 17:39:31 +02:00
void handleAfterAttackCasting ( const BattleAttack & bat ) ;
2010-11-10 02:06:25 +02:00
bool sacrificeArtifact ( const IMarket * m , const CGHeroInstance * hero , CArtifact * art ) ;
2008-12-27 03:01:59 +02:00
friend class CVCMIServer ;
friend class CScriptCallback ;
} ;
# endif // __CGAMEHANDLER_H__
2010-12-04 21:15:20 +02:00
void makeStackDoNothing ( ) ;