mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-21 19:19:26 +02:00
More work on auto-fight.
Dynamic libraries return smart-pointers to what they create.
This commit is contained in:
parent
2be2143844
commit
4a0587d500
@ -19,18 +19,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT char* GetAiNameS()
|
||||
extern "C" DLL_EXPORT void GetNewBattleAI(shared_ptr<CBattleGameInterface> &out)
|
||||
{
|
||||
// need to be defined
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT CBattleGameInterface* GetNewBattleAI()
|
||||
{
|
||||
return new CBattleAI();
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void ReleaseBattleAI(CBattleGameInterface* i)
|
||||
{
|
||||
delete (CBattleAI*)i;
|
||||
}
|
||||
out = make_shared<CBattleAI>();
|
||||
}
|
@ -12,19 +12,8 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
{
|
||||
strcpy(name,NAME);
|
||||
}
|
||||
extern "C" DLL_EXPORT char * GetAiNameS()
|
||||
|
||||
extern "C" DLL_EXPORT void GetNewAI(shared_ptr<CGlobalAI> &out)
|
||||
{
|
||||
char * ret = new char[50];
|
||||
strcpy(ret,NAME);
|
||||
return ret;
|
||||
}
|
||||
extern "C" DLL_EXPORT CGlobalAI * GetNewAI()
|
||||
{
|
||||
return new CEmptyAI();
|
||||
// return
|
||||
}
|
||||
extern "C" DLL_EXPORT void ReleaseAI(CGlobalAI * i)
|
||||
{
|
||||
delete (CEmptyAI*)i;
|
||||
ais.erase(i);
|
||||
}
|
||||
out = make_shared<CEmptyAI>();
|
||||
}
|
@ -19,18 +19,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT char* GetAiNameS()
|
||||
extern "C" DLL_EXPORT void GetNewBattleAI(shared_ptr<CBattleGameInterface> &out)
|
||||
{
|
||||
// need to be defined
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT CBattleGameInterface* GetNewBattleAI()
|
||||
{
|
||||
return new CStupidAI();
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void ReleaseBattleAI(CBattleGameInterface* i)
|
||||
{
|
||||
delete (CStupidAI*)i;
|
||||
}
|
||||
out = make_shared<CStupidAI>();
|
||||
}
|
@ -17,7 +17,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT CGlobalAI* GetNewAI()
|
||||
extern "C" DLL_EXPORT void GetNewAI(shared_ptr<CGlobalAI> &out)
|
||||
{
|
||||
return new VCAI();
|
||||
out = make_shared<VCAI>();
|
||||
}
|
@ -361,7 +361,7 @@ void CCallback::validatePaths()
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
const CGHeroInstance *h = cl->IGameCallback::getSelectedHero(*player);
|
||||
if(h && ( cl->pathInfo->hero != h //wrong hero
|
||||
|| cl->pathInfo->hpos != h->getPosition(false) //wrong hero positoin
|
||||
|| cl->pathInfo->hpos != h->getPosition(false) //wrong hero position
|
||||
|| !cl->pathInfo->isValid)) //paths invalidated by game event
|
||||
{
|
||||
recalculatePaths();
|
||||
@ -376,25 +376,25 @@ int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance
|
||||
return swapCreatures(s1, s2, p1, p2);
|
||||
}
|
||||
|
||||
void CCallback::registerGameInterface(CGameInterface *cgi)
|
||||
void CCallback::registerGameInterface(shared_ptr<CGameInterface> cgi)
|
||||
{
|
||||
cl->additionalPlayerInts[*player].push_back(cgi);
|
||||
registerBattleInterface(cgi);
|
||||
}
|
||||
|
||||
void CCallback::registerBattleInterface(CBattleGameInterface *cbga)
|
||||
void CCallback::registerBattleInterface(shared_ptr<CBattleGameInterface> cbga)
|
||||
{
|
||||
cl->additionalBattleInts[*player].push_back(cbga);
|
||||
}
|
||||
|
||||
void CCallback::unregisterGameInterface(CGameInterface *cgi)
|
||||
void CCallback::unregisterGameInterface(shared_ptr<CGameInterface> cgi)
|
||||
{
|
||||
cl->additionalPlayerInts[*player] -= cgi;
|
||||
unregisterBattleInterface(cgi);
|
||||
|
||||
}
|
||||
|
||||
void CCallback::unregisterBattleInterface(CBattleGameInterface *cbga)
|
||||
void CCallback::unregisterBattleInterface(shared_ptr<CBattleGameInterface> cbga)
|
||||
{
|
||||
cl->additionalBattleInts[*player] -= cbga;
|
||||
}
|
||||
|
@ -114,10 +114,10 @@ public:
|
||||
virtual void recalculatePaths(); //updates main, client pathfinder info (should be called when moving hero is over)
|
||||
|
||||
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
||||
void registerGameInterface(CGameInterface *cgi);
|
||||
void registerBattleInterface(CBattleGameInterface *cbga);
|
||||
void unregisterGameInterface(CGameInterface *cgi);
|
||||
void unregisterBattleInterface(CBattleGameInterface *cbga);
|
||||
void registerGameInterface(shared_ptr<CGameInterface> cgi);
|
||||
void registerBattleInterface(shared_ptr<CBattleGameInterface> cbga);
|
||||
void unregisterGameInterface(shared_ptr<CGameInterface> cgi);
|
||||
void unregisterBattleInterface(shared_ptr<CBattleGameInterface> cbga);
|
||||
|
||||
void unregisterMyInterface(); //stops delivering information about game events to that player's interface -> can be called ONLY after victory/loss
|
||||
|
||||
|
@ -706,7 +706,6 @@ void processCommand(const std::string &message)
|
||||
{
|
||||
if(auto ai = CDynLibHandler::getNewBattleAI(fname)) //test that given AI is indeed available... heavy but it is easy to make a typo and break the game
|
||||
{
|
||||
delete ai;
|
||||
Settings neutralAI = settings.write["server"]["neutralAI"];
|
||||
neutralAI->String() = fname;
|
||||
std::cout << "Setting changed, from now the battle ai will be " << fname << "!\n";
|
||||
|
@ -207,13 +207,8 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
logNetwork->infoStream() << "Deleted mapHandler and gameState.";
|
||||
LOCPLINT = NULL;
|
||||
}
|
||||
while (!playerint.empty())
|
||||
{
|
||||
CGameInterface *pint = playerint.begin()->second;
|
||||
playerint.erase(playerint.begin());
|
||||
delete pint;
|
||||
}
|
||||
|
||||
playerint.clear();
|
||||
callbacks.clear();
|
||||
battleCallbacks.clear();
|
||||
logNetwork->infoStream() << "Deleted playerInts.";
|
||||
@ -391,7 +386,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
}
|
||||
else
|
||||
{
|
||||
installNewPlayerInterface(new CPlayerInterface(color), color);
|
||||
installNewPlayerInterface(make_shared<CPlayerInterface>(color), color);
|
||||
humanPlayers++;
|
||||
}
|
||||
}
|
||||
@ -407,10 +402,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
if(!gNoGUI)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||
CPlayerInterface *p = new CPlayerInterface(PlayerColor::NEUTRAL);
|
||||
auto p = make_shared<CPlayerInterface>(PlayerColor::NEUTRAL);
|
||||
p->observerInDuelMode = true;
|
||||
installNewPlayerInterface(p, boost::none);
|
||||
GH.curInt = p;
|
||||
GH.curInt = p.get();
|
||||
}
|
||||
battleStarted(gs->curB);
|
||||
}
|
||||
@ -469,7 +464,7 @@ void CClient::serialize( Handler &h, const int version )
|
||||
h & pid & dllname & isHuman;
|
||||
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
|
||||
|
||||
CGameInterface *nInt = nullptr;
|
||||
shared_ptr<CGameInterface> nInt = nullptr;
|
||||
if(dllname.length())
|
||||
{
|
||||
if(pid == PlayerColor::NEUTRAL)
|
||||
@ -487,7 +482,7 @@ void CClient::serialize( Handler &h, const int version )
|
||||
else
|
||||
{
|
||||
assert(isHuman);
|
||||
nInt = new CPlayerInterface(pid);
|
||||
nInt = make_shared<CPlayerInterface>(pid);
|
||||
}
|
||||
|
||||
nInt->dllName = dllname;
|
||||
@ -584,18 +579,18 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
// if(battleCallbacks.count(side))
|
||||
// battleCallbacks[side]->setBattle(info);
|
||||
|
||||
CPlayerInterface * att, * def;
|
||||
shared_ptr<CPlayerInterface> att, def;
|
||||
if(vstd::contains(playerint, info->sides[0]) && playerint[info->sides[0]]->human)
|
||||
att = static_cast<CPlayerInterface*>( playerint[info->sides[0]] );
|
||||
att = std::dynamic_pointer_cast<CPlayerInterface>( playerint[info->sides[0]] );
|
||||
else
|
||||
att = NULL;
|
||||
|
||||
if(vstd::contains(playerint, info->sides[1]) && playerint[info->sides[1]]->human)
|
||||
def = static_cast<CPlayerInterface*>( playerint[info->sides[1]] );
|
||||
def = std::dynamic_pointer_cast<CPlayerInterface>( playerint[info->sides[1]] );
|
||||
else
|
||||
def = NULL;
|
||||
|
||||
if(!gNoGUI && (att || def || gs->scenarioOps->mode == StartInfo::DUEL))
|
||||
if(!gNoGUI && (!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL))
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1],
|
||||
@ -650,7 +645,7 @@ void CClient::calculatePaths(const CGHeroInstance *h)
|
||||
gs->calculatePaths(h, *pathInfo);
|
||||
}
|
||||
|
||||
void CClient::commenceTacticPhaseForInt(CBattleGameInterface *battleInt)
|
||||
void CClient::commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleInt)
|
||||
{
|
||||
setThreadName("CClient::commenceTacticPhaseForInt");
|
||||
try
|
||||
@ -710,7 +705,7 @@ void CClient::campaignMapFinished( shared_ptr<CCampaignState> camp )
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::installNewPlayerInterface(CGameInterface *gameInterface, boost::optional<PlayerColor> color)
|
||||
void CClient::installNewPlayerInterface(shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
||||
@ -729,7 +724,7 @@ void CClient::installNewPlayerInterface(CGameInterface *gameInterface, boost::op
|
||||
installNewBattleInterface(gameInterface, color, false);
|
||||
}
|
||||
|
||||
void CClient::installNewBattleInterface(CBattleGameInterface* battleInterface, boost::optional<PlayerColor> color, bool needCallback /*= true*/)
|
||||
void CClient::installNewBattleInterface(shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback /*= true*/)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
||||
|
@ -114,13 +114,13 @@ class CClient : public IGameCallback
|
||||
public:
|
||||
std::map<PlayerColor,shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
|
||||
std::map<PlayerColor,shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
|
||||
std::vector<IGameEventsReceiver*> privilagedGameEventReceivers; //scripting modules, spectator interfaces
|
||||
std::vector<IBattleEventsReceiver*> privilagedBattleEventReceivers; //scripting modules, spectator interfaces
|
||||
std::map<PlayerColor,CGameInterface *> playerint;
|
||||
std::map<PlayerColor,CBattleGameInterface *> battleints;
|
||||
std::vector<shared_ptr<IGameEventsReceiver>> privilagedGameEventReceivers; //scripting modules, spectator interfaces
|
||||
std::vector<shared_ptr<IBattleEventsReceiver>> privilagedBattleEventReceivers; //scripting modules, spectator interfaces
|
||||
std::map<PlayerColor, shared_ptr<CGameInterface>> playerint;
|
||||
std::map<PlayerColor, shared_ptr<CBattleGameInterface>> battleints;
|
||||
|
||||
std::map<PlayerColor,std::vector<CGameInterface *>> additionalPlayerInts;
|
||||
std::map<PlayerColor,std::vector<CBattleGameInterface *>> additionalBattleInts;
|
||||
std::map<PlayerColor,std::vector<shared_ptr<CGameInterface>>> additionalPlayerInts;
|
||||
std::map<PlayerColor,std::vector<shared_ptr<CBattleGameInterface>>> additionalBattleInts;
|
||||
|
||||
bool hotSeat;
|
||||
CConnection *serv;
|
||||
@ -144,8 +144,8 @@ public:
|
||||
void newGame(CConnection *con, StartInfo *si); //con - connection to server
|
||||
|
||||
void loadNeutralBattleAI();
|
||||
void installNewPlayerInterface(CGameInterface *gameInterface, boost::optional<PlayerColor> color);
|
||||
void installNewBattleInterface(CBattleGameInterface* battleInterface, boost::optional<PlayerColor> color, bool needCallback = true);
|
||||
void installNewPlayerInterface(shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color);
|
||||
void installNewBattleInterface(shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback = true);
|
||||
std::string aiNameForPlayer(const PlayerSettings &ps, bool battleAI); //empty means no AI -> human
|
||||
|
||||
void endGame(bool closeConnection = true);
|
||||
@ -229,7 +229,7 @@ public:
|
||||
|
||||
void handlePack( CPack * pack ); //applies the given pack and deletes it
|
||||
void battleStarted(const BattleInfo * info);
|
||||
void commenceTacticPhaseForInt(CBattleGameInterface *battleInt); //will be called as separate thread
|
||||
void commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleInt); //will be called as separate thread
|
||||
|
||||
void commitPackage(CPackForClient *pack) OVERRIDE;
|
||||
|
||||
|
@ -88,24 +88,31 @@ void CBattleInterface::addNewAnim(CBattleAnimation * anim)
|
||||
animsAreDisplayed.setn(true);
|
||||
}
|
||||
|
||||
CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen)
|
||||
CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2,
|
||||
CGHeroInstance *hero1, CGHeroInstance *hero2,
|
||||
const SDL_Rect & myRect,
|
||||
shared_ptr<CPlayerInterface> att, shared_ptr<CPlayerInterface> defen)
|
||||
: queue(NULL), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
|
||||
activeStack(NULL), stackToActivate(NULL), selectedStack(NULL), mouseHoveredStack(-1), lastMouseHoveredStackAnimationTime(-1), previouslyHoveredHex(-1),
|
||||
currentlyHoveredHex(-1), attackingHex(-1), tacticianInterface(NULL), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(NULL), sp(NULL),
|
||||
siegeH(NULL), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0),
|
||||
givenCommand(NULL), myTurn(false), resWindow(NULL), moveStarted(false), moveSh(-1), bresult(NULL),
|
||||
autofightingAI(nullptr), background(nullptr)
|
||||
autofightingAI(nullptr), isAutoFightOn(false), aiThread(nullptr), background(nullptr)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
|
||||
if(!curInt) curInt = LOCPLINT; //may happen when we are defending during network MP game
|
||||
if(!curInt)
|
||||
{
|
||||
//May happen when we are defending during network MP game -> attacker interface is just not present
|
||||
curInt = defenderInt;
|
||||
}
|
||||
|
||||
animsAreDisplayed.setn(false);
|
||||
pos = myRect;
|
||||
strongInterest = true;
|
||||
givenCommand = new CondSh<BattleAction *>(NULL);
|
||||
|
||||
if(attackerInt && attackerInt->cb->battleGetTacticDist()) //hotseat -> check tactics for both players (defender may be local human)
|
||||
if(attackerInt && attackerInt->cb->battleGetTacticDist()) //hot-seat -> check tactics for both players (defender may be local human)
|
||||
tacticianInterface = attackerInt;
|
||||
else if(defenderInt && defenderInt->cb->battleGetTacticDist())
|
||||
tacticianInterface = defenderInt;
|
||||
@ -453,9 +460,7 @@ CBattleInterface::~CBattleInterface()
|
||||
delete bigForceField[1];
|
||||
|
||||
delete siegeH;
|
||||
|
||||
delete autofightingAI;
|
||||
|
||||
|
||||
//TODO: play AI tracks if battle was during AI turn
|
||||
//if (!curInt->makingTurn)
|
||||
//CCS->musich->playMusicFromSet(CCS->musich->aiMusics, -1);
|
||||
@ -493,6 +498,12 @@ void CBattleInterface::setPrintMouseShadow(bool set)
|
||||
|
||||
void CBattleInterface::activate()
|
||||
{
|
||||
if(isAutoFightOn)
|
||||
{
|
||||
bAutofight->activate();
|
||||
return;
|
||||
}
|
||||
|
||||
CIntObject::activate();
|
||||
bOptions->activate();
|
||||
bSurrender->activate();
|
||||
@ -1265,16 +1276,16 @@ void CBattleInterface::bAutofightf()
|
||||
if(spellDestSelectMode) //we are casting a spell
|
||||
return;
|
||||
|
||||
static bool isAutoFightOn = false;
|
||||
static unique_ptr<boost::thread> aiThread = nullptr;
|
||||
|
||||
//Stop auto-fight mode
|
||||
if(isAutoFightOn)
|
||||
{
|
||||
assert(autofightingAI);
|
||||
isAutoFightOn = false;
|
||||
logGlobal->traceStream() << "Stopping the autofight...";
|
||||
aiThread->interrupt();
|
||||
aiThread->join();
|
||||
|
||||
vstd::clear_pointer(autofightingAI);
|
||||
autofightingAI = nullptr;
|
||||
aiThread = nullptr;
|
||||
}
|
||||
else
|
||||
@ -1284,18 +1295,7 @@ void CBattleInterface::bAutofightf()
|
||||
autofightingAI->init(curInt->cb);
|
||||
autofightingAI->battleStart(army1, army2, int3(0,0,0), attackingHeroInstance, defendingHeroInstance, curInt->cb->battleGetMySide());
|
||||
|
||||
//Deactivate everything
|
||||
deactivate();
|
||||
bAutofight->activate(); //only autofight button is to remain active
|
||||
aiThread = make_unique<boost::thread>([&]
|
||||
{
|
||||
auto ba = new BattleAction(autofightingAI->activeStack(activeStack));
|
||||
|
||||
if(isAutoFightOn)
|
||||
{
|
||||
givenCommand->setn(ba);
|
||||
}
|
||||
});
|
||||
requestAutofightingAIToTakeAction();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1313,7 +1313,7 @@ void CBattleInterface::bSpellf()
|
||||
ESpellCastProblem::ESpellCastProblem spellCastProblem;
|
||||
if (curInt->cb->battleCanCastSpell(&spellCastProblem))
|
||||
{
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, curInt);
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, curInt.get());
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
else if(spellCastProblem == ESpellCastProblem::MAGIC_IS_BLOCKED)
|
||||
@ -2057,7 +2057,7 @@ void CBattleInterface::activateStack()
|
||||
const CStack *s = activeStack;
|
||||
|
||||
myTurn = true;
|
||||
if(attackerInt && defenderInt) //hotseat -> need to pick which interface "takes over" as active
|
||||
if(!!attackerInt && defenderInt) //hotseat -> need to pick which interface "takes over" as active
|
||||
curInt = attackerInt->playerID == s->owner ? attackerInt : defenderInt;
|
||||
|
||||
queue->update();
|
||||
@ -2096,6 +2096,9 @@ void CBattleInterface::activateStack()
|
||||
if(!pendingAnims.size() && !active)
|
||||
activate();
|
||||
|
||||
if(isAutoFightOn)
|
||||
requestAutofightingAIToTakeAction();
|
||||
|
||||
GH.fakeMouseMove();
|
||||
}
|
||||
|
||||
@ -3585,6 +3588,24 @@ InfoAboutHero CBattleInterface::enemyHero() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CBattleInterface::requestAutofightingAIToTakeAction()
|
||||
{
|
||||
assert(isAutoFightOn);
|
||||
|
||||
deactivate();
|
||||
bAutofight->activate();
|
||||
|
||||
aiThread = make_unique<boost::thread>([&]
|
||||
{
|
||||
auto ba = new BattleAction(autofightingAI->activeStack(activeStack));
|
||||
|
||||
if(isAutoFightOn)
|
||||
{
|
||||
givenCommand->setn(ba);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CBattleInterface::SiegeHelper::SiegeHelper(const CGTownInstance *siegeTown, const CBattleInterface * _owner)
|
||||
: owner(_owner), town(siegeTown)
|
||||
{
|
||||
|
@ -140,7 +140,7 @@ private:
|
||||
double getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group
|
||||
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
|
||||
|
||||
CPlayerInterface * tacticianInterface; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
|
||||
shared_ptr<CPlayerInterface> tacticianInterface; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
|
||||
bool tacticsMode;
|
||||
bool stackCanCastSpell; //if true, active stack could possibly cats some target spell
|
||||
bool creatureCasting; //if true, stack currently aims to cats a spell
|
||||
@ -156,7 +156,11 @@ private:
|
||||
PossibleActions selectedAction; //last action chosen (and saved) by player
|
||||
PossibleActions illegalAction; //most likely action that can't be performed here
|
||||
|
||||
CBattleGameInterface *autofightingAI;
|
||||
shared_ptr<CBattleGameInterface> autofightingAI;
|
||||
bool isAutoFightOn;
|
||||
unique_ptr<boost::thread> aiThread;
|
||||
|
||||
void requestAutofightingAIToTakeAction();
|
||||
|
||||
void getPossibleActionsForStack (const CStack * stack); //called when stack gets its turn
|
||||
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
|
||||
@ -198,16 +202,16 @@ private:
|
||||
friend class CBattleInterface;
|
||||
} * siegeH;
|
||||
|
||||
CPlayerInterface * attackerInt, * defenderInt; //because LOCPLINT is not enough in hotSeat
|
||||
shared_ptr<CPlayerInterface> attackerInt, defenderInt; //because LOCPLINT is not enough in hotSeat
|
||||
const CGHeroInstance * getActiveHero(); //returns hero that can currently cast a spell
|
||||
public:
|
||||
CPlayerInterface * curInt; //current player interface
|
||||
shared_ptr<CPlayerInterface> curInt; //current player interface
|
||||
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
|
||||
void addNewAnim(CBattleAnimation * anim); //adds new anim to pendingAnims
|
||||
ui32 animIDhelper; //for giving IDs for animations
|
||||
static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
|
||||
|
||||
CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen); //c-tor
|
||||
CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, shared_ptr<CPlayerInterface> att, shared_ptr<CPlayerInterface> defen); //c-tor
|
||||
~CBattleInterface(); //d-tor
|
||||
|
||||
//std::vector<TimeInterested*> timeinterested; //animation handling
|
||||
|
@ -174,7 +174,7 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
|
||||
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, myOwner->curInt);
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, myOwner->curInt.get());
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
}
|
||||
@ -483,7 +483,7 @@ void CBattleResultWindow::bExitf()
|
||||
return;
|
||||
}
|
||||
|
||||
CPlayerInterface * intTmp = owner->curInt;
|
||||
auto intTmp = owner->curInt;
|
||||
GH.popInts(2); //first - we; second - battle interface
|
||||
intTmp->showingDialog->setn(false);
|
||||
CCS->videoh->close();
|
||||
|
@ -22,27 +22,33 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
template<typename rett>
|
||||
rett * createAny(std::string dllname, std::string methodName)
|
||||
shared_ptr<rett> createAny(std::string dllname, std::string methodName)
|
||||
{
|
||||
char temp[50];
|
||||
rett * ret=NULL;
|
||||
rett*(*getAI)();
|
||||
void(*getName)(char*);
|
||||
typedef void(*TGetAIFun)(shared_ptr<rett>&);
|
||||
typedef void(*TGetNameFun)(char*);
|
||||
|
||||
char temp[150];
|
||||
|
||||
TGetAIFun getAI = nullptr;
|
||||
TGetNameFun getName = nullptr;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
HINSTANCE dll = LoadLibraryA(dllname.c_str());
|
||||
if (dll)
|
||||
{
|
||||
getName = (void(*)(char*))GetProcAddress(dll,"GetAiName");
|
||||
getAI = (rett*(*)())GetProcAddress(dll,methodName.c_str());
|
||||
getName = (TGetNameFun)GetProcAddress(dll,"GetAiName");
|
||||
getAI = (TGetAIFun)GetProcAddress(dll,methodName.c_str());
|
||||
}
|
||||
#else
|
||||
void *dll = dlopen(dllname.c_str(), RTLD_LOCAL | RTLD_LAZY);
|
||||
if (dll)
|
||||
{
|
||||
getName = (void(*)(char*))dlsym(dll,"GetAiName");
|
||||
getAI = (rett*(*)())dlsym(dll,methodName.c_str());
|
||||
getName = (TGetNameFun)dlsym(dll,"GetAiName");
|
||||
getAI = (TGetAIFun)dlsym(dll,methodName.c_str());
|
||||
}
|
||||
else
|
||||
logGlobal->errorStream() << "Error: " << dlerror();
|
||||
@ -65,8 +71,9 @@ rett * createAny(std::string dllname, std::string methodName)
|
||||
|
||||
getName(temp);
|
||||
logGlobal->infoStream() << "Loaded " << temp;
|
||||
ret = getAI();
|
||||
|
||||
shared_ptr<rett> ret;
|
||||
getAI(ret);
|
||||
if(!ret)
|
||||
logGlobal->errorStream() << "Cannot get AI!";
|
||||
|
||||
@ -74,26 +81,27 @@ rett * createAny(std::string dllname, std::string methodName)
|
||||
}
|
||||
|
||||
template<typename rett>
|
||||
rett * createAnyAI(std::string dllname, std::string methodName)
|
||||
shared_ptr<rett> createAnyAI(std::string dllname, std::string methodName)
|
||||
{
|
||||
logGlobal->infoStream() << "Opening " << dllname;
|
||||
std::string filename = VCMIDirs::get().libraryName(dllname);
|
||||
rett* ret = createAny<rett>(VCMIDirs::get().libraryPath() + "/AI/" + filename, methodName);
|
||||
|
||||
auto ret = createAny<rett>(VCMIDirs::get().libraryPath() + "/AI/" + filename, methodName);
|
||||
ret->dllName = dllname;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CGlobalAI * CDynLibHandler::getNewAI(std::string dllname)
|
||||
shared_ptr<CGlobalAI> CDynLibHandler::getNewAI(std::string dllname)
|
||||
{
|
||||
return createAnyAI<CGlobalAI>(dllname, "GetNewAI");
|
||||
}
|
||||
|
||||
CBattleGameInterface * CDynLibHandler::getNewBattleAI(std::string dllname )
|
||||
shared_ptr<CBattleGameInterface> CDynLibHandler::getNewBattleAI(std::string dllname )
|
||||
{
|
||||
return createAnyAI<CBattleGameInterface>(dllname, "GetNewBattleAI");
|
||||
}
|
||||
|
||||
CScriptingModule * CDynLibHandler::getNewScriptingModule(std::string dllname)
|
||||
shared_ptr<CScriptingModule> CDynLibHandler::getNewScriptingModule(std::string dllname)
|
||||
{
|
||||
return createAny<CScriptingModule>(dllname, "GetNewModule");
|
||||
}
|
||||
@ -187,7 +195,7 @@ void CAdventureAI::battleSpellCast(const BattleSpellCast *sc)
|
||||
void CAdventureAI::battleEnd(const BattleResult *br)
|
||||
{
|
||||
battleAI->battleEnd(br);
|
||||
vstd::clear_pointer(battleAI);
|
||||
battleAI = nullptr;
|
||||
}
|
||||
|
||||
void CAdventureAI::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom)
|
||||
|
@ -96,9 +96,9 @@ public:
|
||||
class DLL_LINKAGE CDynLibHandler
|
||||
{
|
||||
public:
|
||||
static CGlobalAI * getNewAI(std::string dllname);
|
||||
static CBattleGameInterface * getNewBattleAI(std::string dllname);
|
||||
static CScriptingModule * getNewScriptingModule(std::string dllname);
|
||||
static shared_ptr<CGlobalAI> getNewAI(std::string dllname);
|
||||
static shared_ptr<CBattleGameInterface> getNewBattleAI(std::string dllname);
|
||||
static shared_ptr<CScriptingModule> getNewScriptingModule(std::string dllname);
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGlobalAI : public CGameInterface // AI class (to derivate)
|
||||
@ -114,7 +114,7 @@ class DLL_LINKAGE CAdventureAI : public CGlobalAI
|
||||
public:
|
||||
CAdventureAI() : battleAI(NULL), cbc(NULL) {};
|
||||
|
||||
CBattleGameInterface *battleAI;
|
||||
shared_ptr<CBattleGameInterface> battleAI;
|
||||
shared_ptr<CBattleCallback> cbc;
|
||||
|
||||
virtual std::string getBattleAIName() const = 0; //has to return name of the battle AI to be used
|
||||
|
@ -28,7 +28,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT CScriptingModule* GetNewModule()
|
||||
extern "C" DLL_EXPORT void GetNewModule(shared_ptr<CScriptingModule> &out)
|
||||
{
|
||||
return new ERMInterpreter();
|
||||
out = make_shared<ERMInterpreter>();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user