1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Various player/AI interface related fixes and improvements.

This commit is contained in:
Michał W. Urbańczyk 2011-07-17 18:49:05 +00:00
parent ef954b8a4f
commit 79f5b29196
10 changed files with 48 additions and 34 deletions

View File

@ -58,6 +58,7 @@ bool CCallback::moveHero(const CGHeroInstance *h, int3 dst)
void CCallback::selectionMade(int selection, int asker)
{
QueryReply pack(asker,selection);
boost::unique_lock<boost::mutex> lock(*cl->serv->wmx);
*cl->serv << &pack;
}
void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level/*=-1*/)
@ -188,9 +189,12 @@ void CBattleCallback::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->waitingRequest.set(typeList.getTypeID<T>());
*cl->serv << request;
{
boost::unique_lock<boost::mutex> lock(*cl->serv->wmx);
*cl->serv << request;
}
if(waitTillRealize)
{

View File

@ -238,6 +238,13 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
const CGHeroInstance * ho = cb->getHero(details.id); //object representing this hero
int3 hp = details.start;
if(!ho)
{
//AI hero left the visible area (we can't obtain info)
//TODO - probably needs some handling
return;
}
adventureInt->centerOn(ho); //actualizing screen pos
adventureInt->minimap.draw(screen2);
adventureInt->heroList.draw(screen2);

View File

@ -100,13 +100,13 @@ void CClient::init()
}
CClient::CClient(void)
:waitingRequest(false)
:waitingRequest(0)
{
init();
}
CClient::CClient(CConnection *con, StartInfo *si)
:waitingRequest(false)
:waitingRequest(0)
{
init();
newGame(con,si);
@ -431,19 +431,19 @@ void CClient::newGame( CConnection *con, StartInfo *si )
serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
hotSeat = (humanPlayers > 1);
std::vector<FileInfo> scriptModules;
CFileUtility::getFilesWithExt(scriptModules, LIB_DIR "/Scripting", "." LIB_EXT);
BOOST_FOREACH(FileInfo &m, scriptModules)
{
CScriptingModule * nm = CDynLibHandler::getNewScriptingModule(m.name);
privilagedGameEventReceivers.push_back(nm);
privilagedBattleEventReceivers.push_back(nm);
nm->giveActionCB(this);
nm->giveInfoCB(this);
nm->init();
erm = nm; //something tells me that there'll at most one module and it'll be ERM
}
// std::vector<FileInfo> scriptModules;
// CFileUtility::getFilesWithExt(scriptModules, LIB_DIR "/Scripting", "." LIB_EXT);
// BOOST_FOREACH(FileInfo &m, scriptModules)
// {
// CScriptingModule * nm = CDynLibHandler::getNewScriptingModule(m.name);
// privilagedGameEventReceivers.push_back(nm);
// privilagedBattleEventReceivers.push_back(nm);
// nm->giveActionCB(this);
// nm->giveInfoCB(this);
// nm->init();
//
// erm = nm; //something tells me that there'll at most one module and it'll be ERM
// }
}
template <typename Handler>
@ -585,8 +585,8 @@ void CClient::battleStarted(const BattleInfo * info)
else
def = NULL;
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1], Rect((conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2, 800, 600), att, def);
if(att || def || gs->scenarioOps->mode == StartInfo::DUEL)
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1], Rect((conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2, 800, 600), att, def);
if(vstd::contains(battleints,info->sides[0]))
battleints[info->sides[0]]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);

View File

@ -78,7 +78,7 @@ public:
CScriptingModule *erm;
CondSh<bool> waitingRequest;
CondSh<int> waitingRequest;
std::queue<CPack *> packs;
boost::mutex packsM;

View File

@ -709,7 +709,7 @@ void PackageApplied::applyCl( CClient *cl )
{
ui8 player = GS(cl)->currentPlayer;
INTERFACE_CALL_IF_PRESENT(player, requestRealized, this);
if(cl->waitingRequest.get())
if(cl->waitingRequest.get() == packType)
cl->waitingRequest.setn(false);
}
@ -730,6 +730,7 @@ void PlayerBlocked::applyCl( CClient *cl )
void YourTurn::applyCl( CClient *cl )
{
CALL_IN_ALL_INTERFACES(playerStartsTurn, player);
CALL_ONLY_THAT_INTERFACE(player,yourTurn);
}

View File

@ -74,7 +74,7 @@ class CGameInterface : public CBattleGameInterface, public IGameEventsReceiver
{
public:
virtual void init(CCallback * CB){};
virtual void yourTurn(){};
virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
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 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, bool removableUnits, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done

View File

@ -99,7 +99,7 @@ public:
}
ui16 getTypeID(const std::type_info *type);
template <typename T> ui16 getTypeID(const T * t)
template <typename T> ui16 getTypeID(const T * t = NULL)
{
return getTypeID(getTypeInfo(t));
}

View File

@ -110,4 +110,5 @@ public:
virtual void objectRemoved(const CGObjectInstance *obj){}; //eg. collected resource, picked artifact, beaten hero
virtual void playerBlocked(int reason){}; //reason: 0 - upcoming battle
virtual void gameOver(ui8 player, bool victory){}; //player lost or won the game
virtual void playerStartsTurn(ui8 player){};
};

View File

@ -646,15 +646,12 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
tlog5 << "Message successfully applied (result=" << result << ")!\n";
//send confirmation that we've applied the package
if(pack->type != 6000) //WORKAROUND - not confirm query replies TODO: reconsider
PackageApplied applied;
applied.result = result;
applied.packType = packType;
{
PackageApplied applied;
applied.result = result;
applied.packType = packType;
{
boost::unique_lock<boost::mutex> lock(*c.wmx);
c << &applied;
}
boost::unique_lock<boost::mutex> lock(*c.wmx);
c << &applied;
}
}
else
@ -1757,6 +1754,7 @@ void CGameHandler::sendMessageTo( CConnection &c, const std::string &message )
{
SystemMessage sm;
sm.text = message;
boost::unique_lock<boost::mutex> lock(*c.wmx);
c << &sm;
}
@ -1925,9 +1923,8 @@ void CGameHandler::sendToAllClients( CPackForClient * info )
tlog5 << "Sending to all clients a package of type " << typeid(*info).name() << std::endl;
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
{
(*i)->wmx->lock();
boost::unique_lock<boost::mutex> lock(*(*i)->wmx);
**i << info;
(*i)->wmx->unlock();
}
}

View File

@ -65,7 +65,11 @@ bool CloseServer::applyGh( CGameHandler *gh )
bool EndTurn::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT(GS(gh)->currentPlayer);
int player = GS(gh)->currentPlayer;
ERROR_IF_NOT(player);
if(gh->states.checkFlag(player, &PlayerStatus::engagedIntoBattle))
COMPLAIN_AND_RETURN("Cannot end turn when in battle!");
gh->states.setFlag(GS(gh)->currentPlayer,&PlayerStatus::makingTurn,false);
return true;
}