mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
* version set 0.73b
* config entry for 1600x1200 resolution * several fixes * http://vcmi.antypika.aplus.pl/forum/viewtopic.php?p=3185#3185
This commit is contained in:
parent
b987f02cb0
commit
de1ed92379
@ -460,7 +460,7 @@ std::vector<int> CBattleLogic::GetAvailableHexesForAttacker(CStack *defender, CS
|
||||
BattleAction CBattleLogic::MakeDefend(int stackID)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = 1;
|
||||
ba.side = m_side;
|
||||
ba.actionType = action_defend;
|
||||
ba.stackNumber = stackID;
|
||||
ba.additionalInfo = -1;
|
||||
@ -470,7 +470,7 @@ BattleAction CBattleLogic::MakeDefend(int stackID)
|
||||
BattleAction CBattleLogic::MakeWait(int stackID)
|
||||
{
|
||||
BattleAction ba;
|
||||
ba.side = 1;
|
||||
ba.side = m_side;
|
||||
ba.actionType = action_wait;
|
||||
ba.stackNumber = stackID;
|
||||
ba.additionalInfo = -1;
|
||||
@ -479,11 +479,21 @@ BattleAction CBattleLogic::MakeWait(int stackID)
|
||||
|
||||
BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
{
|
||||
CStack *attackerStack = m_cb->battleGetStackByID(attackerID),
|
||||
*destinationStack = m_cb->battleGetStackByID(destinationID);
|
||||
assert(attackerStack && destinationStack);
|
||||
|
||||
//don't attack ourselves
|
||||
if(destinationStack->attackerOwned == !m_side)
|
||||
{
|
||||
return MakeDefend(attackerID);
|
||||
}
|
||||
|
||||
if (m_cb->battleCanShoot(attackerID, m_cb->battleGetPos(destinationID)))
|
||||
{
|
||||
// shoot
|
||||
BattleAction ba;
|
||||
ba.side = 1;
|
||||
ba.side = m_side;
|
||||
ba.additionalInfo = -1;
|
||||
ba.actionType = action_shoot; // shoot
|
||||
ba.stackNumber = attackerID;
|
||||
@ -528,7 +538,7 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
}
|
||||
|
||||
BattleAction ba;
|
||||
ba.side = 1;
|
||||
ba.side = m_side;
|
||||
//ba.actionType = 6; // go and attack
|
||||
ba.stackNumber = attackerID;
|
||||
ba.destinationTile = static_cast<ui16>(dest_tile);
|
||||
@ -547,9 +557,6 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
int nearest_pos = -1;
|
||||
|
||||
// if double wide calculate tail
|
||||
CStack *attackerStack = m_cb->battleGetStackByID(attackerID);
|
||||
assert(attackerStack != NULL);
|
||||
|
||||
int tail_pos = -1;
|
||||
if (attackerStack->creature->isDoubleWide())
|
||||
{
|
||||
@ -572,6 +579,8 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
#if defined PRINT_DEBUG
|
||||
PrintBattleAction(ba);
|
||||
#endif
|
||||
assert(m_cb->battleGetStackByPos(ba.additionalInfo)); //if action is action_walk_and_attack additional info must point on enemy stack
|
||||
assert(m_cb->battleGetStackByPos(ba.additionalInfo) != attackerStack); //don't attack ourselve
|
||||
return ba;
|
||||
}
|
||||
}
|
||||
@ -585,6 +594,8 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
#if defined PRINT_DEBUG
|
||||
PrintBattleAction(ba);
|
||||
#endif
|
||||
assert(m_cb->battleGetStackByPos(ba.additionalInfo)); //if action is action_walk_and_attack additional info must point on enemy stack
|
||||
assert(m_cb->battleGetStackByPos(ba.additionalInfo) != attackerStack); //don't attack ourselve
|
||||
return ba;
|
||||
}
|
||||
int d = m_battleHelper.GetDistanceWithObstacles(dest_tile, *it);
|
||||
@ -606,6 +617,7 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID)
|
||||
#if defined PRINT_DEBUG
|
||||
PrintBattleAction(ba);
|
||||
#endif
|
||||
|
||||
return ba;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ void DbgBox(const char *msg, bool messageBox)
|
||||
}
|
||||
|
||||
CGeniusAI::CGeniusAI()
|
||||
: m_generalAI(),turn(0),firstTurn(true)
|
||||
: m_generalAI(), turn(0), m_state(NO_BATTLE), firstTurn(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -272,6 +272,20 @@ void GeniusAI::CGeniusAI::showGarrisonDialog( const CArmedInstance *up, const CG
|
||||
onEnd();
|
||||
}
|
||||
|
||||
void GeniusAI::CGeniusAI::playerBlocked( int reason )
|
||||
{
|
||||
if(reason == 0) //battle is coming...
|
||||
{
|
||||
m_state.setn(UPCOMING_BATTLE);
|
||||
}
|
||||
}
|
||||
|
||||
void GeniusAI::CGeniusAI::battleResultsApplied()
|
||||
{
|
||||
assert(m_state.get() == ENDING_BATTLE);
|
||||
m_state.setn(NO_BATTLE);
|
||||
}
|
||||
|
||||
void CGeniusAI::showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel)
|
||||
{
|
||||
m_cb->selectionMade(cancel ? 0 : 1, askID);
|
||||
@ -321,7 +335,10 @@ void CGeniusAI::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
|
||||
|
||||
void CGeniusAI::battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side)
|
||||
{
|
||||
assert(!m_battleLogic); //************** assert fails when AI starts two battles at same time? ***************
|
||||
assert(!m_battleLogic);
|
||||
assert(playerID > PLAYER_LIMIT || m_state.get() == UPCOMING_BATTLE); //we have been informed that battle will start (or we are neutral AI)
|
||||
|
||||
m_state.setn(ONGOING_BATTLE);
|
||||
m_battleLogic = new BattleAI::CBattleLogic(m_cb, army1, army2, tile, hero1, hero2, side);
|
||||
|
||||
DbgBox("** CGeniusAI::battleStart **");
|
||||
@ -341,6 +358,9 @@ void CGeniusAI::battleEnd(BattleResult *br)
|
||||
delete m_battleLogic;
|
||||
m_battleLogic = NULL;
|
||||
|
||||
assert(m_state.get() == ONGOING_BATTLE);
|
||||
m_state.setn(ENDING_BATTLE);
|
||||
|
||||
DbgBox("** CGeniusAI::battleEnd **");
|
||||
}
|
||||
/**
|
||||
|
@ -4,12 +4,21 @@
|
||||
#include "Common.h"
|
||||
#include "BattleLogic.h"
|
||||
#include "GeneralAI.h"
|
||||
#include "..\..\lib\CondSh.h"
|
||||
#include "../../lib/VCMI_Lib.h"
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
namespace GeniusAI {
|
||||
|
||||
enum BattleState
|
||||
{
|
||||
NO_BATTLE,
|
||||
UPCOMING_BATTLE,
|
||||
ONGOING_BATTLE,
|
||||
ENDING_BATTLE
|
||||
};
|
||||
|
||||
class CGeniusAI : public CGlobalAI
|
||||
{
|
||||
private:
|
||||
@ -75,6 +84,7 @@ private:
|
||||
void getObjectives(HypotheticalGameState & hgs);
|
||||
void reportResources();
|
||||
int turn;
|
||||
CondSh<BattleState> m_state; //are we engaged into battle?
|
||||
bool firstTurn;
|
||||
|
||||
|
||||
@ -195,6 +205,7 @@ public:
|
||||
virtual void tileHidden(int3 pos);
|
||||
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
|
||||
virtual void playerBlocked(int reason);
|
||||
// battle
|
||||
virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero
|
||||
virtual void actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero
|
||||
@ -211,6 +222,7 @@ public:
|
||||
virtual void battleStackAttacking(int ID, int dest);
|
||||
virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting);
|
||||
virtual BattleAction activeStack(int stackID);
|
||||
void battleResultsApplied();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "GeneralAI.h"
|
||||
#include "../../CCallback.h"
|
||||
|
||||
using namespace GeniusAI::GeneralAI;
|
||||
|
||||
@ -15,4 +16,5 @@ void CGeneralAI::init(ICallback *CB)
|
||||
{
|
||||
assert(CB != NULL);
|
||||
m_cb = CB;
|
||||
CB->waitTillRealize = true;
|
||||
}
|
@ -58,10 +58,10 @@ template <ui16 N> bool isType(CPack *pack)
|
||||
return pack->getType() == N;
|
||||
}
|
||||
|
||||
bool CCallback::moveHero(const CGHeroInstance *h, int3 dst) const
|
||||
bool CCallback::moveHero(const CGHeroInstance *h, int3 dst)
|
||||
{
|
||||
MoveHero pack(dst,h->id);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return true;
|
||||
}
|
||||
void CCallback::selectionMade(int selection, int asker)
|
||||
@ -74,7 +74,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amou
|
||||
if(player!=obj->tempOwner) return;
|
||||
|
||||
RecruitCreatures pack(obj->id,ID,amount);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
|
||||
@ -84,20 +84,20 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
|
||||
return false;
|
||||
|
||||
DisbandCreature pack(stackPos,obj->id);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return true;
|
||||
}
|
||||
bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID)
|
||||
{
|
||||
UpgradeCreature pack(stackPos,obj->id,newID);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return false;
|
||||
}
|
||||
void CCallback::endTurn()
|
||||
{
|
||||
tlog5 << "Player " << (unsigned)player << " end his turn." << std::endl;
|
||||
EndTurn pack;
|
||||
*cl->serv << &pack; //report that we ended turn
|
||||
sendRequest(&pack); //report that we ended turn
|
||||
}
|
||||
UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) const
|
||||
{
|
||||
@ -349,20 +349,20 @@ const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj) const
|
||||
int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
|
||||
{
|
||||
ArrangeStacks pack(1,p1,p2,s1->id,s2->id,0);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CCallback::mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
|
||||
{
|
||||
ArrangeStacks pack(2,p1,p2,s1->id,s2->id,0);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return 0;
|
||||
}
|
||||
int CCallback::splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)
|
||||
{
|
||||
ArrangeStacks pack(3,p1,p2,s1->id,s2->id,val);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -371,7 +371,7 @@ bool CCallback::dismissHero(const CGHeroInstance *hero)
|
||||
if(player!=hero->tempOwner) return false;
|
||||
|
||||
DismissHero pack(hero->id);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGH
|
||||
return false;
|
||||
|
||||
ExchangeArtifacts ea(hero1->id, hero2->id, pos1, pos2);
|
||||
*cl->serv << &ea;
|
||||
sendRequest(&ea);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -403,7 +403,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
|
||||
return false; //lack of resources
|
||||
|
||||
BuildStructure pack(town->id,buildingID);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -444,7 +444,7 @@ CStack* CCallback::battleGetStackByID(int ID)
|
||||
int CCallback::battleMakeAction(BattleAction* action)
|
||||
{
|
||||
MakeCustomAction mca(*action);
|
||||
*cl->serv << &mca;
|
||||
sendRequest(&mca);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ void CCallback::swapGarrisonHero( const CGTownInstance *town )
|
||||
if(town->tempOwner != player) return;
|
||||
|
||||
GarrisonHeroSwap pack(town->id);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)
|
||||
@ -590,7 +590,7 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)
|
||||
if(hero->tempOwner != player) return;
|
||||
|
||||
BuyArtifact pack(hero->id,aid);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
std::vector < const CGObjectInstance * > CCallback::getBlockingObjs( int3 pos ) const
|
||||
@ -660,14 +660,14 @@ void CCallback::trade( int mode, int id1, int id2, int val1 )
|
||||
int p1, p2;
|
||||
getMarketOffer(id1,id2,p1,p2,mode);
|
||||
TradeOnMarketplace pack(player,mode,id1,id2,val1);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
|
||||
{
|
||||
const_cast<CGHeroInstance*>(hero)->army.formation = tight;
|
||||
SetFormation pack(hero->id,tight);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
}
|
||||
|
||||
void CCallback::setSelection(const CArmedInstance * obj)
|
||||
@ -675,7 +675,7 @@ void CCallback::setSelection(const CArmedInstance * obj)
|
||||
SetSelection ss;
|
||||
ss.player = player;
|
||||
ss.id = obj->id;
|
||||
*cl->serv << &ss;
|
||||
sendRequest(&ss);
|
||||
}
|
||||
|
||||
void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)
|
||||
@ -686,7 +686,7 @@ void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *he
|
||||
if(gs->players[player].availableHeroes[i] == hero)
|
||||
{
|
||||
HireHero pack(i,town->id);
|
||||
*cl->serv << &pack;
|
||||
sendRequest(&pack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -731,14 +731,33 @@ void CCallback::save( const std::string &fname )
|
||||
void CCallback::sendMessage(const std::string &mess)
|
||||
{
|
||||
PlayerMessage pm(player, mess);
|
||||
*cl->serv << ±
|
||||
sendRequest(&pm);
|
||||
}
|
||||
|
||||
void CCallback::buildBoat( const IShipyard *obj )
|
||||
{
|
||||
BuildBoat bb;
|
||||
bb.objid = obj->o->id;
|
||||
*cl->serv << &bb;
|
||||
sendRequest(&bb);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CCallback::sendRequest(const T* request)
|
||||
{
|
||||
//TODO? should be part of CClient but it would have to be very tricky cause template/serialization issues
|
||||
if(waitTillRealize)
|
||||
cl->waitingRequest.set(true);
|
||||
|
||||
*cl->serv << request;
|
||||
|
||||
if(waitTillRealize)
|
||||
cl->waitingRequest.waitWhileTrue();
|
||||
}
|
||||
|
||||
CCallback::CCallback( CGameState * GS, int Player, CClient *C )
|
||||
:gs(GS), cl(C), player(Player)
|
||||
{
|
||||
waitTillRealize = false;
|
||||
}
|
||||
|
||||
InfoAboutHero::InfoAboutHero()
|
||||
|
@ -38,6 +38,7 @@ class CClient;
|
||||
struct TerrainTile;
|
||||
class CHeroClass;
|
||||
class IShipyard;
|
||||
struct CPackForServer;
|
||||
|
||||
struct InfoAboutHero
|
||||
{
|
||||
@ -84,8 +85,9 @@ struct InfoAboutTown
|
||||
class ICallback
|
||||
{
|
||||
public:
|
||||
bool waitTillRealize; //if true, request functions will return after they are realized by server
|
||||
//hero
|
||||
virtual bool moveHero(const CGHeroInstance *h, int3 dst) const =0; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
virtual bool moveHero(const CGHeroInstance *h, int3 dst) =0; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses given hero; true - successfuly, false - not successfuly
|
||||
|
||||
//town
|
||||
@ -185,18 +187,19 @@ struct HeroMoveDetails
|
||||
class CCallback : public ICallback
|
||||
{
|
||||
private:
|
||||
CCallback(CGameState * GS, int Player, CClient *C):gs(GS), cl(C), player(Player){};
|
||||
CCallback(CGameState * GS, int Player, CClient *C);;
|
||||
CGameState * gs;
|
||||
CClient *cl;
|
||||
bool isVisible(int3 pos, int Player) const;
|
||||
bool isVisible(const CGObjectInstance *obj, int Player) const;
|
||||
template <typename T> void sendRequest(const T*request);
|
||||
|
||||
protected:
|
||||
int player;
|
||||
|
||||
public:
|
||||
//commands
|
||||
bool moveHero(const CGHeroInstance *h, int3 dst) const; //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
void selectionMade(int selection, int asker);
|
||||
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2);
|
||||
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
virtual void heroCreated(const CGHeroInstance*){};
|
||||
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||
virtual void heroInGarrisonChange(const CGTownInstance *town){};
|
||||
virtual void heroKilled(const CGHeroInstance*){};
|
||||
//virtual void heroKilled(const CGHeroInstance*){};
|
||||
virtual void heroMoved(const TryMoveHero & details){};
|
||||
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val){};
|
||||
virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts
|
||||
@ -87,8 +87,6 @@ public:
|
||||
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID){};
|
||||
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level){}
|
||||
virtual void showShipyardDialog(const IShipyard *obj){} //obj may be town or shipyard; state: 0 - can buid, 1 - lack of resources, 2 - dest tile is blocked, 3 - no water
|
||||
//virtual void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||
//virtual void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) = 0; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||
virtual void tileHidden(const std::set<int3> &pos){};
|
||||
@ -100,6 +98,8 @@ public:
|
||||
virtual void requestRealized(PackageApplied *pa){};
|
||||
virtual void heroExchangeStarted(si32 hero1, si32 hero2){};
|
||||
virtual void objectPropertyChanged(const SetObjectProperty * sop){}; //eg. mine has been flagged
|
||||
virtual void objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero
|
||||
virtual void playerBlocked(int reason){}; //reason: 0 - upcoming battle
|
||||
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
||||
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
|
||||
|
||||
@ -110,6 +110,7 @@ public:
|
||||
virtual void battleAttack(BattleAttack *ba){}; //called when stack is performing attack
|
||||
virtual void battleStacksAttacked(std::set<BattleStackAttacked> & bsa){}; //called when stack receives damage (after battleAttack())
|
||||
virtual void battleEnd(BattleResult *br){};
|
||||
virtual void battleResultsApplied(){}; //called when all effects of last battle are applied
|
||||
virtual void battleNewRound(int round){}; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||
virtual void battleStackMoved(int ID, int dest, int distance, bool end){};
|
||||
virtual void battleSpellCast(SpellCast *sc){};
|
||||
|
@ -1789,6 +1789,15 @@ void CPlayerInterface::newObject( const CGObjectInstance * obj )
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::objectRemoved( const CGObjectInstance *obj )
|
||||
{
|
||||
if(obj->ID == HEROI_TYPE && obj->tempOwner == playerID)
|
||||
{
|
||||
const CGHeroInstance *h = static_cast<const CGHeroInstance*>(obj);
|
||||
heroKilled(h);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemOptions::setMusicVolume( int newVolume )
|
||||
{
|
||||
musicVolume = newVolume;
|
||||
|
@ -154,7 +154,6 @@ public:
|
||||
void heroCreated(const CGHeroInstance* hero);
|
||||
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
void heroInGarrisonChange(const CGTownInstance *town);
|
||||
void heroKilled(const CGHeroInstance* hero);
|
||||
void heroMoved(const TryMoveHero & details);
|
||||
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
|
||||
void heroManaPointsChanged(const CGHeroInstance * hero);
|
||||
@ -175,6 +174,7 @@ public:
|
||||
void requestRealized(PackageApplied *pa);
|
||||
void heroExchangeStarted(si32 hero1, si32 hero2);
|
||||
void objectPropertyChanged(const SetObjectProperty * sop);
|
||||
void objectRemoved(const CGObjectInstance *obj);
|
||||
void serialize(COSer<CSaveFile> &h, const int version); //saving
|
||||
void serialize(CISer<CLoadFile> &h, const int version); //loading
|
||||
|
||||
@ -195,6 +195,7 @@ public:
|
||||
|
||||
|
||||
//-------------//
|
||||
void heroKilled(const CGHeroInstance* hero);
|
||||
void waitWhileDialog();
|
||||
bool shiftPressed() const; //determines if shift key is pressed (left or right or both)
|
||||
void redrawHeroWin(const CGHeroInstance * hero);
|
||||
|
@ -95,10 +95,12 @@ void CClient::init()
|
||||
}
|
||||
|
||||
CClient::CClient(void)
|
||||
:waitingRequest(false)
|
||||
{
|
||||
init();
|
||||
}
|
||||
CClient::CClient(CConnection *con, StartInfo *si)
|
||||
:waitingRequest(false)
|
||||
{
|
||||
init();
|
||||
newGame(con,si);
|
||||
@ -418,5 +420,16 @@ void CClient::serialize( Handler &h, const int version )
|
||||
}
|
||||
}
|
||||
|
||||
//void CClient::sendRequest( const CPackForServer *request, bool waitForRealization )
|
||||
//{
|
||||
// if(waitForRealization)
|
||||
// waitingRequest.set(true);
|
||||
//
|
||||
// *serv << request;
|
||||
//
|
||||
// if(waitForRealization)
|
||||
// waitingRequest.waitWhileTrue();
|
||||
//}
|
||||
|
||||
template void CClient::serialize( CISer<CLoadFile> &h, const int version );
|
||||
template void CClient::serialize( COSer<CSaveFile> &h, const int version );
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../global.h"
|
||||
#include <boost/thread.hpp>
|
||||
#include "../lib/IGameCallback.h"
|
||||
#include "../lib/CondSh.h"
|
||||
|
||||
/*
|
||||
* Client.h, part of VCMI engine
|
||||
@ -62,7 +63,10 @@ public:
|
||||
SharedMem *shared;
|
||||
BattleAction *curbaction;
|
||||
|
||||
CondSh<bool> waitingRequest;
|
||||
|
||||
void waitForMoveAndSend(int color);
|
||||
//void sendRequest(const CPackForServer *request, bool waitForRealization);
|
||||
CClient(void);
|
||||
CClient(CConnection *con, StartInfo *si);
|
||||
~CClient(void);
|
||||
|
@ -125,12 +125,18 @@ void ChangeObjPos::applyCl( CClient *cl )
|
||||
|
||||
void RemoveObject::applyFirstCl( CClient *cl )
|
||||
{
|
||||
CGI->mh->hideObject(cl->getObj(id));
|
||||
CGHeroInstance *h = GS(cl)->getHero(id);
|
||||
if(h)
|
||||
const CGObjectInstance *o = cl->getObj(id);
|
||||
CGI->mh->hideObject(o);
|
||||
|
||||
int3 pos = o->pos - o->getVisitableOffset();
|
||||
//notify interfaces about removal
|
||||
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
|
||||
{
|
||||
if(vstd::contains(cl->playerint,h->tempOwner))
|
||||
cl->playerint[h->tempOwner]->heroKilled(h);
|
||||
if(i->first >= PLAYER_LIMIT) continue;
|
||||
if(GS(cl)->players[i->first].fogOfWarMap[pos.x][pos.y][pos.z])
|
||||
{
|
||||
i->second->objectRemoved(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,6 +428,12 @@ void StacksInjured::applyCl( CClient *cl )
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2,battleStacksAttacked,stacks);
|
||||
}
|
||||
|
||||
void BattleResultsApplied::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(player1,battleResultsApplied);
|
||||
INTERFACE_CALL_IF_PRESENT(player2,battleResultsApplied);
|
||||
}
|
||||
|
||||
CGameState* CPackForClient::GS( CClient *cl )
|
||||
{
|
||||
return cl->gs;
|
||||
@ -439,6 +451,8 @@ void EndAction::applyCl( CClient *cl )
|
||||
void PackageApplied::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(GS(cl)->currentPlayer,requestRealized,this);
|
||||
if(cl->waitingRequest.get())
|
||||
cl->waitingRequest.setn(false);
|
||||
}
|
||||
|
||||
void SystemMessage::applyCl( CClient *cl )
|
||||
@ -451,6 +465,11 @@ void SystemMessage::applyCl( CClient *cl )
|
||||
LOCPLINT->cingconsole->print(str.str());
|
||||
}
|
||||
|
||||
void PlayerBlocked::applyCl( CClient *cl )
|
||||
{
|
||||
INTERFACE_CALL_IF_PRESENT(player,playerBlocked,reason);
|
||||
}
|
||||
|
||||
void YourTurn::applyCl( CClient *cl )
|
||||
{
|
||||
boost::thread(boost::bind(&CGameInterface::yourTurn,cl->playerint[player]));
|
||||
|
@ -125,4 +125,32 @@ GUISettings
|
||||
ButtonEndTurn: x=1159 y=524 graphic=IAM001.DEF playerColoured=1;
|
||||
};
|
||||
}
|
||||
1600x1200 //setting specific for this resolution
|
||||
{
|
||||
AdventureMap
|
||||
{
|
||||
AdvMap: x=7 y=6 width=1395 height=1147 smoothMove=1;
|
||||
InfoBox: x=1406 y=989;
|
||||
gem0: x=6 y=1108 graphic=agemLL.def;
|
||||
gem1: x=1356 y=1108 graphic=agemLR.def;
|
||||
gem2: x=6 y=6 graphic=agemUL.def;
|
||||
gem3: x=1356 y=6 graphic=agemUR.def;
|
||||
background=ADVMAP4.pcx;
|
||||
HeroList: size=23 x=1409 y=201 movePoints=IMOBIL.DEF manaPoints=IMANA.DEF arrowUp=IAM012.DEF arrowDown=IAM013.DEF;
|
||||
TownList: size=23 x=1547 y=201 arrowUp=IAM014.DEF arrowDown=IAM015.DEF;
|
||||
Minimap: width=144 height=144 x=1430 y=26;
|
||||
Statusbar: x=285 y=1155 graphic=ADROLLVR3.pcx;
|
||||
ResDataBar: x=0 y=1175 graphic=ZRESBAR3.pcx offsetX=65 offsetY=2 resSpace=192 resDateSpace=210;
|
||||
ButtonKingdomOv: x=1479 y=197 graphic=IAM002L.DEF playerColoured=1;
|
||||
ButtonUnderground: x=1479 y=229 graphic=IAM010L.DEF playerColoured=1 additionalDefs=(IAM003L.DEF);
|
||||
ButtonQuestLog: x=1479 y=261 graphic=IAM004L.DEF playerColoured=1;
|
||||
ButtonSleepWake: x=1479 y=294 graphic=IAM005L.DEF playerColoured=1;
|
||||
ButtonMoveHero: x=1479 y=327 graphic=IAM006L.DEF playerColoured=1;
|
||||
ButtonSpellbook: x=1479 y=359 graphic=IAM007L.DEF playerColoured=1;
|
||||
ButtonAdvOptions: x=1479 y=393 graphic=IAM008L.DEF playerColoured=1;
|
||||
ButtonSysOptions: x=1479 y=426 graphic=IAM009L.DEF playerColoured=1;
|
||||
ButtonNextHero: x=1479 y=458 graphic=IAM000.DEF playerColoured=1;
|
||||
ButtonEndTurn: x=1479 y=491 graphic=IAM001.DEF playerColoured=1;
|
||||
};
|
||||
}
|
||||
}
|
2
global.h
2
global.h
@ -19,7 +19,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
||||
#define THC
|
||||
#endif
|
||||
|
||||
#define NAME_VER ("VCMI 0.73")
|
||||
#define NAME_VER ("VCMI 0.73b")
|
||||
extern std::string NAME; //full name
|
||||
extern std::string NAME_AFFIX; //client / server
|
||||
#define CONSOLE_LOGGING_LEVEL 5
|
||||
|
@ -1868,7 +1868,7 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co
|
||||
cb->showInfoDialog(&iw);
|
||||
|
||||
//act as if player refused
|
||||
joinDecision(h,cost,true);
|
||||
joinDecision(h,cost,false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1625,7 +1625,9 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
|
||||
|
||||
void CGameState::apply(CPack *pack)
|
||||
{
|
||||
applierGs->apps[typeList.getTypeID(pack)]->applyOnGS(this,pack);
|
||||
ui16 typ = typeList.getTypeID(pack);
|
||||
assert(typ >= 0);
|
||||
applierGs->apps[typ]->applyOnGS(this,pack);
|
||||
}
|
||||
|
||||
PlayerState * CGameState::getPlayer( ui8 color )
|
||||
|
55
lib/CondSh.h
55
lib/CondSh.h
@ -17,10 +17,55 @@ template <typename T> struct CondSh
|
||||
T data;
|
||||
boost::condition_variable cond;
|
||||
boost::mutex mx;
|
||||
CondSh(){};
|
||||
CondSh(T t){data = t;};
|
||||
void set(T t){mx.lock();data=t;mx.unlock();}; //set data
|
||||
void setn(T t){mx.lock();data=t;mx.unlock();cond.notify_all();}; //set data and notify
|
||||
T get(){boost::unique_lock<boost::mutex> lock(mx); return data;};
|
||||
|
||||
CondSh()
|
||||
{}
|
||||
|
||||
CondSh(T t)
|
||||
{
|
||||
data = t;
|
||||
}
|
||||
|
||||
void set(T t)
|
||||
{
|
||||
mx.lock();
|
||||
data=t;
|
||||
mx.unlock();
|
||||
}
|
||||
|
||||
void setn(T t) //set data and notify
|
||||
{
|
||||
mx.lock();
|
||||
data=t;
|
||||
mx.unlock();
|
||||
cond.notify_all();
|
||||
};
|
||||
|
||||
T get() //get stored value
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mx);
|
||||
return data;
|
||||
}
|
||||
|
||||
void waitWhileTrue() //waits until data is set to false
|
||||
{
|
||||
boost::unique_lock<boost::mutex> un(mx);
|
||||
while(data)
|
||||
cond.wait(un);
|
||||
}
|
||||
|
||||
void waitWhile(const T &t) //waits while data is set to arg
|
||||
{
|
||||
boost::unique_lock<boost::mutex> un(mx);
|
||||
while(data == t)
|
||||
cond.wait(un);
|
||||
}
|
||||
|
||||
void waitUntil(const T &t) //waits until data is set to arg
|
||||
{
|
||||
boost::unique_lock<boost::mutex> un(mx);
|
||||
while(data != t)
|
||||
cond.wait(un);
|
||||
}
|
||||
};
|
||||
#endif // __CONDSH_H__
|
||||
|
@ -170,6 +170,22 @@ struct SystemMessage : public CPackForClient //95
|
||||
}
|
||||
};
|
||||
|
||||
struct PlayerBlocked : public CPackForClient //96
|
||||
{
|
||||
PlayerBlocked(){type = 96;};
|
||||
void applyCl(CClient *cl);
|
||||
|
||||
enum EReason { UPCOMING_BATTLE };
|
||||
|
||||
ui8 reason;
|
||||
ui8 player;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & reason & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct YourTurn : public CPackForClient //100
|
||||
{
|
||||
YourTurn(){type = 100;};
|
||||
@ -921,6 +937,19 @@ struct StacksInjured : public CPackForClient //3011
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleResultsApplied : public CPackForClient //3012
|
||||
{
|
||||
BattleResultsApplied(){type = 3012;}
|
||||
|
||||
ui8 player1, player2;
|
||||
|
||||
void applyCl(CClient *cl);
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player1 & player2;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShowInInfobox : public CPackForClient //107
|
||||
{
|
||||
ShowInInfobox(){type = 107;};
|
||||
@ -1152,8 +1181,8 @@ struct BuildBoat : public CPackForServer
|
||||
|
||||
struct QueryReply : public CPackForServer
|
||||
{
|
||||
QueryReply(){};
|
||||
QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){};
|
||||
QueryReply(){type = 6000;};
|
||||
QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){type = 6000;};
|
||||
ui32 qid, answer; //hero and artifact id
|
||||
|
||||
bool applyGh(CGameHandler *gh);
|
||||
|
@ -54,6 +54,7 @@ void registerTypes2(Serializer &s)
|
||||
{
|
||||
s.template registerType<PackageApplied>();
|
||||
s.template registerType<SystemMessage>();
|
||||
s.template registerType<PlayerBlocked>();
|
||||
s.template registerType<YourTurn>();
|
||||
s.template registerType<SetResource>();
|
||||
s.template registerType<SetResources>();
|
||||
@ -95,6 +96,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<SpellCast>();
|
||||
s.template registerType<SetStackEffect>();
|
||||
s.template registerType<StacksInjured>();
|
||||
s.template registerType<BattleResultsApplied>();
|
||||
s.template registerType<ShowInInfobox>();
|
||||
s.template registerType<OpenWindow>();
|
||||
s.template registerType<NewObject>();
|
||||
|
@ -403,11 +403,15 @@ askInterfaceForMove:
|
||||
}
|
||||
}
|
||||
|
||||
BattleResultsApplied resultsApplied;
|
||||
resultsApplied.player1 = army1->tempOwner;
|
||||
resultsApplied.player2 = army2->tempOwner;
|
||||
|
||||
//unblock engaged players
|
||||
if(hero1->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,false);
|
||||
if(hero2 && hero2->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,false);
|
||||
if(army1->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(army1->tempOwner,&PlayerStatus::engagedIntoBattle,false);
|
||||
if(army2 && army2->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(army2->tempOwner,&PlayerStatus::engagedIntoBattle,false);
|
||||
|
||||
//casualties among heroes armies
|
||||
SetGarrisons sg;
|
||||
@ -442,6 +446,7 @@ askInterfaceForMove:
|
||||
|
||||
delete battleResult.data;
|
||||
|
||||
sendAndApply(&resultsApplied);
|
||||
}
|
||||
void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
|
||||
{
|
||||
@ -513,12 +518,15 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
tlog5 << "Message successfully applied (result=" << result << ")!\n";
|
||||
|
||||
//send confirmation that we've applied the package
|
||||
PackageApplied applied;
|
||||
applied.result = result;
|
||||
applied.packType = packType;
|
||||
if(pack->type != 6000) //WORKAROUND - not confirm query replies TODO: reconsider
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.wmx);
|
||||
c << &applied;
|
||||
PackageApplied applied;
|
||||
applied.result = result;
|
||||
applied.packType = packType;
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.wmx);
|
||||
c << &applied;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1201,11 +1209,6 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
|
||||
|
||||
//premies given
|
||||
|
||||
//block engaged players
|
||||
if(hero1->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,true);
|
||||
if(hero2 && hero2->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
|
||||
|
||||
//send info about battles
|
||||
BattleStart bs;
|
||||
@ -1292,6 +1295,9 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
||||
return false;
|
||||
}
|
||||
|
||||
if(states.checkFlag(h->tempOwner, &PlayerStatus::engagedIntoBattle) && complain("Cannot move hero during the battle"))
|
||||
return false;
|
||||
|
||||
tlog5 << "Player " <<int(asker) << " wants to move hero "<< hid << " from "<< h->pos << " to " << dst << std::endl;
|
||||
int3 hmpos = dst + int3(-1,0,0);
|
||||
|
||||
@ -1356,11 +1362,9 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
||||
//checks for standard movement
|
||||
if(!instant)
|
||||
{
|
||||
if( (distance(h->pos,dst)>=1.5) //tiles are not neighbouring
|
||||
|| (h->movement < cost && h->movement < 100) //lack of movement points
|
||||
)
|
||||
if( distance(h->pos,dst) >= 1.5 && complain("Tiles are not neighbouring!")
|
||||
|| h->movement < cost && h->movement < 100 && complain("Not enough move points!"))
|
||||
{
|
||||
tlog2 << "Cannot move hero, not enough move points or tiles are not neighbouring!\n";
|
||||
sendAndApply(&tmh);
|
||||
return false;
|
||||
}
|
||||
@ -1556,6 +1560,12 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
|
||||
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb) //use hero=NULL for no hero
|
||||
{
|
||||
engageIntoBattle(army1->tempOwner);
|
||||
engageIntoBattle(army2->tempOwner);
|
||||
//block engaged players
|
||||
if(army2->tempOwner < PLAYER_LIMIT)
|
||||
states.setFlag(army2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
|
||||
|
||||
boost::thread(boost::bind(&CGameHandler::startBattle,this,army1,army2,tile,hero1,hero2,cb));
|
||||
}
|
||||
|
||||
@ -2442,19 +2452,35 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
{
|
||||
SetMana sm;
|
||||
ChangeSpells cs;
|
||||
SetHeroArtifacts sha;
|
||||
|
||||
CGHeroInstance *h = gs->getHero(gs->getPlayer(player)->currentSelection);
|
||||
if(!h && complain("Cannot realize cheat, no hero selected!")) return;
|
||||
|
||||
sm.hid = cs.hid = h->id;
|
||||
|
||||
//give all spells
|
||||
cs.learn = 1;
|
||||
for(int i=0;i<VLC->spellh->spells.size();i++)
|
||||
{
|
||||
if(!VLC->spellh->spells[i].creatureAbility)
|
||||
cs.spells.insert(i);
|
||||
}
|
||||
sm.hid = cs.hid = gs->players[player].currentSelection;
|
||||
|
||||
//give mana
|
||||
sm.val = 999;
|
||||
if(gs->getHero(cs.hid))
|
||||
|
||||
if(!h->getArt(17)) //hero doesn't have spellbook
|
||||
{
|
||||
sendAndApply(&cs);
|
||||
sendAndApply(&sm);
|
||||
//give spellbook
|
||||
sha.artifacts = h->artifacts;
|
||||
sha.artifWorn = h->artifWorn;
|
||||
sha.artifWorn[17] = 0;
|
||||
sendAndApply(&sha);
|
||||
}
|
||||
|
||||
sendAndApply(&cs);
|
||||
sendAndApply(&sm);
|
||||
}
|
||||
else if(message == "vcmiainur") //gives 5 archangels into each slot
|
||||
{
|
||||
@ -2467,7 +2493,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
sg.garrs[hero->id].slots[i] = std::pair<ui32,si32>(13,5);
|
||||
sendAndApply(&sg);
|
||||
}
|
||||
else if(message == "vcmiangband") //gives 10 black knightinto each slot
|
||||
else if(message == "vcmiangband") //gives 10 black knight into each slot
|
||||
{
|
||||
SetGarrisons sg;
|
||||
CGHeroInstance *hero = gs->getHero(gs->getPlayer(player)->currentSelection);
|
||||
@ -2513,6 +2539,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
|
||||
else if(message == "vcmieagles") //reveal FoW
|
||||
{
|
||||
FoWChange fc;
|
||||
fc.mode = 1;
|
||||
fc.player = player;
|
||||
for(int i=0;i<gs->map->width;i++)
|
||||
for(int j=0;j<gs->map->height;j++)
|
||||
@ -2979,3 +3006,15 @@ bool CGameHandler::buildBoat( ui32 objid )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameHandler::engageIntoBattle( ui8 player )
|
||||
{
|
||||
if(vstd::contains(states.players, player))
|
||||
states.setFlag(player,&PlayerStatus::engagedIntoBattle,true);
|
||||
|
||||
//notify interfaces
|
||||
PlayerBlocked pb;
|
||||
pb.player = player;
|
||||
pb.reason = PlayerBlocked::UPCOMING_BATTLE;
|
||||
sendAndApply(&pb);
|
||||
}
|
@ -160,6 +160,7 @@ public:
|
||||
void handleTimeEvents();
|
||||
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
|
||||
void objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h );
|
||||
void engageIntoBattle( ui8 player );
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -176,7 +177,6 @@ public:
|
||||
|
||||
void run(bool resume);
|
||||
void newTurn();
|
||||
|
||||
friend class CVCMIServer;
|
||||
friend class CScriptCallback;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user