mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-10 22:31:40 +02:00
Merge pull request #5713 from IvanSavenko/gamecallback_remove
Game callback rework (part 1?)
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
#include "../Goals/Goals.h"
|
||||
#include "../AIGateway.h"
|
||||
#include "../Engine/Nullkiller.h"
|
||||
#include "../../../lib/callback/IGameCallback.h"
|
||||
#include "../../../lib/callback/IGameInfoCallback.h"
|
||||
#include "../../../lib/mapping/CMap.h"
|
||||
#include "../../../lib/mapObjects/MapObjects.h"
|
||||
#include "../../../lib/pathfinder/CPathfinder.h"
|
||||
@@ -121,7 +121,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
|
||||
//TODO: fix this code duplication with NodeStorage::initialize, problem is to keep `resetTile` inline
|
||||
const PlayerColor fowPlayer = ai->playerID;
|
||||
const auto & fow = static_cast<const CGameInfoCallback *>(gs)->getPlayerTeam(fowPlayer)->fogOfWarMap;
|
||||
const auto & fow = static_cast<const IGameInfoCallback *>(gs)->getPlayerTeam(fowPlayer)->fogOfWarMap;
|
||||
const int3 sizes = gs->getMapSize();
|
||||
|
||||
//Each thread gets different x, but an array of y located next to each other in memory
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#include "AINodeStorage.h"
|
||||
#include "Actions/TownPortalAction.h"
|
||||
#include "../Goals/Goals.h"
|
||||
#include "../../../lib/callback/IGameCallback.h"
|
||||
#include "../../../lib/callback/IGameInfoCallback.h"
|
||||
#include "../../../lib/mapping/CMap.h"
|
||||
#include "../../../lib/mapObjects/MapObjects.h"
|
||||
#include "../../../lib/pathfinder/CPathfinder.h"
|
||||
@@ -33,7 +33,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
{
|
||||
int3 pos;
|
||||
const int3 sizes = gs->getMapSize();
|
||||
const auto & fow = static_cast<const CGameInfoCallback *>(gs)->getPlayerTeam(hero->tempOwner)->fogOfWarMap;
|
||||
const auto & fow = static_cast<const IGameInfoCallback *>(gs)->getPlayerTeam(hero->tempOwner)->fogOfWarMap;
|
||||
const PlayerColor player = hero->tempOwner;
|
||||
|
||||
//make 200% sure that these are loop invariants (also a bit shorter code), let compiler do the rest(loop unswitching)
|
||||
|
@@ -494,15 +494,6 @@ void CClient::startPlayerBattleAction(const BattleID & battleID, PlayerColor col
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
vstd::RNG & CClient::getRandomGenerator()
|
||||
{
|
||||
// Client should use CRandomGenerator::getDefault() for UI logic
|
||||
// Gamestate should never call this method on client!
|
||||
throw std::runtime_error("Illegal access to random number generator from client code!");
|
||||
}
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::Pool * CClient::getGlobalContextPool() const
|
||||
{
|
||||
|
@@ -13,13 +13,14 @@
|
||||
#include <vcmi/Environment.h>
|
||||
|
||||
#include "../lib/callback/IClient.h"
|
||||
#include "../lib/callback/IGameCallback.h"
|
||||
#include "../lib/callback/CGameInfoCallback.h"
|
||||
#include "../lib/ConditionalWait.h"
|
||||
#include "../lib/ResourceSet.h"
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct CPackForClient;
|
||||
struct CPackForServer;
|
||||
class IBattleEventsReceiver;
|
||||
class CBattleGameInterface;
|
||||
@@ -121,7 +122,7 @@ public:
|
||||
};
|
||||
|
||||
/// Class which handles client - server logic
|
||||
class CClient : public IGameCallback, public Environment, public IClient
|
||||
class CClient : public CGameInfoCallback, public Environment, public IClient
|
||||
{
|
||||
std::shared_ptr<CGameState> gamestate;
|
||||
public:
|
||||
@@ -176,70 +177,8 @@ public:
|
||||
friend class CCallback; //handling players actions
|
||||
friend class CBattleCallback; //handling players actions
|
||||
|
||||
void changeSpells(const CGHeroInstance * hero, bool give, const std::set<SpellID> & spells) override {};
|
||||
void setResearchedSpells(const CGTownInstance * town, int level, const std::vector<SpellID> & spells, bool accepted) override {};
|
||||
bool removeObject(const CGObjectInstance * obj, const PlayerColor & initiator) override {return false;};
|
||||
void createBoat(const int3 & visitablePosition, BoatId type, PlayerColor initiator) override {};
|
||||
void setOwner(const CGObjectInstance * obj, PlayerColor owner) override {};
|
||||
void giveExperience(const CGHeroInstance * hero, TExpType val) override {};
|
||||
void changePrimSkill(const CGHeroInstance * hero, PrimarySkill which, si64 val, bool abs = false) override {};
|
||||
void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs = false) override {};
|
||||
|
||||
void showBlockingDialog(const IObjectInterface * caller, BlockingDialog * iw) override {};
|
||||
void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) override {};
|
||||
void showTeleportDialog(TeleportDialog * iw) override {};
|
||||
void showObjectWindow(const CGObjectInstance * object, EOpenWindowMode window, const CGHeroInstance * visitor, bool addQuery) override {};
|
||||
void giveResource(PlayerColor player, GameResID which, int val) override {};
|
||||
void giveResources(PlayerColor player, ResourceSet resources) override {};
|
||||
|
||||
void giveCreatures(const CArmedInstance * objid, const CGHeroInstance * h, const CCreatureSet & creatures, bool remove) override {};
|
||||
void takeCreatures(ObjectInstanceID objid, const std::vector<CStackBasicDescriptor> & creatures, bool forceRemoval) override {};
|
||||
bool changeStackType(const StackLocation & sl, const CCreature * c) override {return false;};
|
||||
bool changeStackCount(const StackLocation & sl, TQuantity count, bool absoluteValue = false) override {return false;};
|
||||
bool insertNewStack(const StackLocation & sl, const CCreature * c, TQuantity count) override {return false;};
|
||||
bool eraseStack(const StackLocation & sl, bool forceRemoval = false) override {return false;};
|
||||
bool swapStacks(const StackLocation & sl1, const StackLocation & sl2) override {return false;}
|
||||
bool addToSlot(const StackLocation & sl, const CCreature * c, TQuantity count) override {return false;}
|
||||
void tryJoiningArmy(const CArmedInstance * src, const CArmedInstance * dst, bool removeObjWhenFinished, bool allowMerging) override {}
|
||||
bool moveStack(const StackLocation & src, const StackLocation & dst, TQuantity count = -1) override {return false;}
|
||||
|
||||
void removeAfterVisit(const ObjectInstanceID & id) override {};
|
||||
bool swapGarrisonOnSiege(ObjectInstanceID tid) override {return false;};
|
||||
bool giveHeroNewArtifact(const CGHeroInstance * h, const ArtifactID & artId, const ArtifactPosition & pos) override {return false;};
|
||||
bool giveHeroNewScroll(const CGHeroInstance * h, const SpellID & spellId, const ArtifactPosition & pos) override {return false;};
|
||||
bool putArtifact(const ArtifactLocation & al, const ArtifactInstanceID & id, std::optional<bool> askAssemble) override {return false;};
|
||||
void removeArtifact(const ArtifactLocation & al) override {};
|
||||
bool moveArtifact(const PlayerColor & player, const ArtifactLocation & al1, const ArtifactLocation & al2) override {return false;};
|
||||
|
||||
void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero) override {};
|
||||
void visitCastleObjects(const CGTownInstance * obj, const CGHeroInstance * hero) override {};
|
||||
void stopHeroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero) override {};
|
||||
void startBattle(const CArmedInstance * army1, const CArmedInstance * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, const BattleLayout & layout, const CGTownInstance * town) override {}; //use hero=nullptr for no hero
|
||||
void startBattle(const CArmedInstance * army1, const CArmedInstance * army2) override {}; //if any of armies is hero, hero will be used
|
||||
bool moveHero(ObjectInstanceID hid, int3 dst, EMovementMode movementMode, bool transit = false, PlayerColor asker = PlayerColor::NEUTRAL) override {return false;};
|
||||
void giveHeroBonus(GiveBonus * bonus) override {};
|
||||
void setMovePoints(SetMovePoints * smp) override {};
|
||||
void setMovePoints(ObjectInstanceID hid, int val, bool absolute) override {};
|
||||
void setManaPoints(ObjectInstanceID hid, int val) override {};
|
||||
void giveHero(ObjectInstanceID id, PlayerColor player, ObjectInstanceID boatId = ObjectInstanceID()) override {};
|
||||
void changeObjPos(ObjectInstanceID objid, int3 newPos, const PlayerColor & initiator) override {};
|
||||
void sendAndApply(CPackForClient & pack) override {};
|
||||
void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override {};
|
||||
void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) override {};
|
||||
|
||||
void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, ETileVisibility mode) override {}
|
||||
void changeFogOfWar(const std::unordered_set<int3> & tiles, PlayerColor player, ETileVisibility mode) override {}
|
||||
|
||||
void setObjPropertyValue(ObjectInstanceID objid, ObjProperty prop, int32_t value) override {};
|
||||
void setObjPropertyID(ObjectInstanceID objid, ObjProperty prop, ObjPropertyID identifier) override {};
|
||||
void setRewardableObjectConfiguration(ObjectInstanceID objid, const Rewardable::Configuration & configuration) override {};
|
||||
void setRewardableObjectConfiguration(ObjectInstanceID townInstanceID, BuildingID buildingID, const Rewardable::Configuration & configuration) override{};
|
||||
|
||||
void showInfoDialog(InfoWindow * iw) override {};
|
||||
void removeGUI() const;
|
||||
|
||||
vstd::RNG & getRandomGenerator() override;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::Pool * getGlobalContextPool() const override;
|
||||
#endif
|
||||
|
@@ -475,7 +475,7 @@ void ApplyFirstClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
|
||||
{
|
||||
//below line contains little cheat for AI so it will be aware of deletion of enemy heroes that moved or got re-covered by FoW
|
||||
//TODO: loose requirements as next AI related crashes appear, for example another pack.player collects object that got re-covered by FoW, unsure if AI code workarounds this
|
||||
if(gs.isVisible(o, i->first) || (!cl.getPlayerState(i->first)->human && o->ID == Obj::HERO && o->tempOwner != i->first))
|
||||
if(gs.isVisibleFor(o, i->first) || (!cl.getPlayerState(i->first)->human && o->ID == Obj::HERO && o->tempOwner != i->first))
|
||||
i->second->objectRemoved(o, pack.initiator);
|
||||
}
|
||||
|
||||
@@ -540,8 +540,8 @@ void ApplyClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
|
||||
if(i->first != PlayerColor::SPECTATOR && gs.checkForStandardLoss(i->first)) // Do not notify vanquished pack.player's interface
|
||||
continue;
|
||||
|
||||
if(gs.isVisible(h->convertToVisitablePos(pack.start), i->first)
|
||||
|| gs.isVisible(h->convertToVisitablePos(pack.end), i->first))
|
||||
if(gs.isVisibleFor(h->convertToVisitablePos(pack.start), i->first)
|
||||
|| gs.isVisibleFor(h->convertToVisitablePos(pack.end), i->first))
|
||||
{
|
||||
// pack.src and pack.dst of enemy hero move may be not visible => 'verbose' should be false
|
||||
const bool verbose = cl.getPlayerRelations(i->first, player) != PlayerRelations::ENEMIES;
|
||||
@@ -601,9 +601,9 @@ void ApplyClientNetPackVisitor::visitSetHeroesInTown(SetHeroesInTown & pack)
|
||||
if(!i->first.isValidPlayer())
|
||||
continue;
|
||||
|
||||
if(gs.isVisible(t, i->first) ||
|
||||
(hGarr && gs.isVisible(hGarr, i->first)) ||
|
||||
(hVisit && gs.isVisible(hVisit, i->first)))
|
||||
if(gs.isVisibleFor(t, i->first) ||
|
||||
(hGarr && gs.isVisibleFor(hGarr, i->first)) ||
|
||||
(hVisit && gs.isVisibleFor(hVisit, i->first)))
|
||||
{
|
||||
cl.playerint[i->first]->heroInGarrisonChange(t);
|
||||
}
|
||||
@@ -650,7 +650,7 @@ void ApplyFirstClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty &
|
||||
//inform all players that see this object
|
||||
for(auto it = cl.playerint.cbegin(); it != cl.playerint.cend(); ++it)
|
||||
{
|
||||
if(gs.isVisible(gs.getObjInstance(pack.id), it->first))
|
||||
if(gs.isVisibleFor(gs.getObjInstance(pack.id), it->first))
|
||||
callInterfaceIfPresent(cl, it->first, &IGameEventsReceiver::beforeObjectPropertyChanged, &pack);
|
||||
}
|
||||
|
||||
@@ -667,7 +667,7 @@ void ApplyClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack)
|
||||
//inform all players that see this object
|
||||
for(auto it = cl.playerint.cbegin(); it != cl.playerint.cend(); ++it)
|
||||
{
|
||||
if(gs.isVisible(gs.getObjInstance(pack.id), it->first))
|
||||
if(gs.isVisibleFor(gs.getObjInstance(pack.id), it->first))
|
||||
callInterfaceIfPresent(cl, it->first, &IGameEventsReceiver::objectPropertyChanged, &pack);
|
||||
}
|
||||
|
||||
@@ -1050,7 +1050,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
|
||||
|
||||
for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
|
||||
{
|
||||
if(gs.isVisible(obj, i->first))
|
||||
if(gs.isVisibleFor(obj, i->first))
|
||||
i->second->newObject(obj);
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,8 @@
|
||||
"seaMovement" : {
|
||||
"type" : "MOVEMENT",
|
||||
"subtype" : "heroMovementSea",
|
||||
"val" : 500
|
||||
"val" : 500,
|
||||
"propagator": "PLAYER_PROPAGATOR"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,8 @@ Currently, it is possible to make flaggable objects that provide player with:
|
||||
// Alternatively, it is possible to reuse existing string from H3 using form '@core.advevent.69'
|
||||
"onVisit" : "{Object Name}\r\n\r\nText of messages that player will see on visit.",
|
||||
|
||||
// List of bonuses that will be granted to player that owns this object
|
||||
// List of bonuses that player that owns this object may receive
|
||||
// Make sure to use required propagator, such as PLAYER_PROPAGATOR
|
||||
"bonuses" : {
|
||||
"firstBonus" : { BONUS FORMAT },
|
||||
"secondBonus" : { BONUS FORMAT },
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include "CCreatureHandler.h"
|
||||
#include "GameLibrary.h"
|
||||
#include "IGameSettings.h"
|
||||
#include "callback/IGameCallback.h"
|
||||
#include "callback/IGameInfoCallback.h"
|
||||
#include "entities/hero/CHeroHandler.h"
|
||||
#include "mapObjects/CGHeroInstance.h"
|
||||
#include "modding/ModScope.h"
|
||||
@@ -707,7 +707,7 @@ void CCreatureSet::serializeJson(JsonSerializeFormat & handler, const std::strin
|
||||
}
|
||||
}
|
||||
|
||||
CStackInstance::CStackInstance(IGameCallback *cb, bool isHypothetic)
|
||||
CStackInstance::CStackInstance(IGameInfoCallback *cb, bool isHypothetic)
|
||||
: CBonusSystemNode(isHypothetic)
|
||||
, CStackBasicDescriptor(nullptr, 0)
|
||||
, CArtifactSet(cb)
|
||||
@@ -719,7 +719,7 @@ CStackInstance::CStackInstance(IGameCallback *cb, bool isHypothetic)
|
||||
setNodeType(STACK_INSTANCE);
|
||||
}
|
||||
|
||||
CStackInstance::CStackInstance(IGameCallback *cb, const CreatureID & id, TQuantity Count, bool isHypothetic)
|
||||
CStackInstance::CStackInstance(IGameInfoCallback *cb, const CreatureID & id, TQuantity Count, bool isHypothetic)
|
||||
: CStackInstance(cb, false)
|
||||
{
|
||||
setType(id);
|
||||
@@ -1029,11 +1029,11 @@ const IBonusBearer* CStackInstance::getBonusBearer() const
|
||||
return this;
|
||||
}
|
||||
|
||||
CCommanderInstance::CCommanderInstance(IGameCallback *cb)
|
||||
CCommanderInstance::CCommanderInstance(IGameInfoCallback *cb)
|
||||
:CStackInstance(cb)
|
||||
{}
|
||||
|
||||
CCommanderInstance::CCommanderInstance(IGameCallback *cb, const CreatureID & id)
|
||||
CCommanderInstance::CCommanderInstance(IGameInfoCallback *cb, const CreatureID & id)
|
||||
: CStackInstance(cb)
|
||||
, name("Commando")
|
||||
{
|
||||
|
@@ -78,7 +78,7 @@ class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDe
|
||||
|
||||
CArmedInstance * armyInstance = nullptr; //stack must be part of some army, army must be part of some object
|
||||
|
||||
IGameCallback * getCallback() const final { return cb; }
|
||||
IGameInfoCallback * getCallback() const final { return cb; }
|
||||
|
||||
TExpType totalExperience;//commander needs same amount of exp as hero
|
||||
public:
|
||||
@@ -146,8 +146,8 @@ public:
|
||||
virtual int getLevel() const; //different for regular stack and commander
|
||||
CreatureID getCreatureID() const; //-1 if not available
|
||||
std::string getName() const; //plural or singular
|
||||
CStackInstance(IGameCallback *cb, bool isHypothetic = false);
|
||||
CStackInstance(IGameCallback *cb, const CreatureID & id, TQuantity count, bool isHypothetic = false);
|
||||
CStackInstance(IGameInfoCallback *cb, bool isHypothetic = false);
|
||||
CStackInstance(IGameInfoCallback *cb, const CreatureID & id, TQuantity count, bool isHypothetic = false);
|
||||
virtual ~CStackInstance() = default;
|
||||
|
||||
void setType(const CreatureID & creID);
|
||||
@@ -182,8 +182,8 @@ public:
|
||||
std::vector <ui8> secondarySkills; //ID -> level
|
||||
std::set <ui8> specialSkills;
|
||||
//std::vector <CArtifactInstance *> arts;
|
||||
CCommanderInstance(IGameCallback *cb);
|
||||
CCommanderInstance(IGameCallback *cb, const CreatureID & id);
|
||||
CCommanderInstance(IGameInfoCallback *cb);
|
||||
CCommanderInstance(IGameInfoCallback *cb, const CreatureID & id);
|
||||
void setAlive (bool alive);
|
||||
void levelUp ();
|
||||
|
||||
|
@@ -85,7 +85,6 @@ set(lib_MAIN_SRCS
|
||||
callback/CGameInfoCallback.cpp
|
||||
callback/CNonConstInfoCallback.cpp
|
||||
callback/CPlayerSpecificInfoCallback.cpp
|
||||
callback/CPrivilegedInfoCallback.cpp
|
||||
|
||||
campaign/CampaignHandler.cpp
|
||||
campaign/CampaignState.cpp
|
||||
@@ -469,13 +468,12 @@ set(lib_MAIN_HEADERS
|
||||
callback/CGlobalAI.h
|
||||
callback/CNonConstInfoCallback.h
|
||||
callback/CPlayerSpecificInfoCallback.h
|
||||
callback/CPrivilegedInfoCallback.h
|
||||
callback/GameCallbackHolder.h
|
||||
callback/IBattleCallback.h
|
||||
callback/IBattleEventsReceiver.h
|
||||
callback/IClient.h
|
||||
callback/IGameActionCallback.h
|
||||
callback/IGameCallback.h
|
||||
callback/CGameInfoCallback.h
|
||||
callback/IGameEventCallback.h
|
||||
callback/IGameEventsReceiver.h
|
||||
callback/IGameInfoCallback.h
|
||||
@@ -831,7 +829,7 @@ endif()
|
||||
if(MINGW AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set_source_files_properties(
|
||||
serializer/SerializerReflection.cpp
|
||||
IGameCallback.cpp
|
||||
CGameInfoCallback.cpp
|
||||
PROPERTIES
|
||||
COMPILE_OPTIONS "-Wa,-mbig-obj")
|
||||
endif()
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "CPlayerState.h"
|
||||
#include "GameLibrary.h"
|
||||
#include "callback/IGameCallback.h"
|
||||
#include "callback/IGameInfoCallback.h"
|
||||
#include "mapObjects/CGHeroInstance.h"
|
||||
#include "mapObjects/CGTownInstance.h"
|
||||
#include "gameState/CGameState.h"
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
PlayerState::PlayerState(IGameCallback *cb)
|
||||
PlayerState::PlayerState(IGameInfoCallback *cb)
|
||||
: CBonusSystemNode(PLAYER)
|
||||
, GameCallbackHolder(cb)
|
||||
, color(-1)
|
||||
|
@@ -75,7 +75,7 @@ public:
|
||||
std::optional<ui8> daysWithoutCastle;
|
||||
TurnTimerInfo turnTimer;
|
||||
|
||||
PlayerState(IGameCallback *cb);
|
||||
PlayerState(IGameInfoCallback *cb);
|
||||
~PlayerState();
|
||||
|
||||
std::string nodeName() const override;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
#include "bonuses/Limiters.h"
|
||||
#include "bonuses/Updaters.h"
|
||||
#include "../CStack.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../entities/artifact/CArtifact.h"
|
||||
#include "../entities/building/TownFortifications.h"
|
||||
#include "../filesystem/Filesystem.h"
|
||||
@@ -156,7 +156,7 @@ struct RangeGenerator
|
||||
std::function<int()> myRand;
|
||||
};
|
||||
|
||||
std::unique_ptr<BattleInfo> BattleInfo::setupBattle(IGameCallback *cb, const int3 & tile, TerrainId terrain, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town)
|
||||
std::unique_ptr<BattleInfo> BattleInfo::setupBattle(IGameInfoCallback *cb, const int3 & tile, TerrainId terrain, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town)
|
||||
{
|
||||
CMP_stack cmpst;
|
||||
auto currentBattle = std::make_unique<BattleInfo>(cb, layout);
|
||||
@@ -458,13 +458,13 @@ CStack * BattleInfo::getStack(int stackID, bool onlyAlive)
|
||||
return const_cast<CStack *>(battleGetStackByID(stackID, onlyAlive));
|
||||
}
|
||||
|
||||
BattleInfo::BattleInfo(IGameCallback *cb, const BattleLayout & layout):
|
||||
BattleInfo::BattleInfo(IGameInfoCallback *cb, const BattleLayout & layout):
|
||||
BattleInfo(cb)
|
||||
{
|
||||
*this->layout = layout;
|
||||
}
|
||||
|
||||
BattleInfo::BattleInfo(IGameCallback *cb)
|
||||
BattleInfo::BattleInfo(IGameInfoCallback *cb)
|
||||
:GameCallbackHolder(cb),
|
||||
sides({SideInBattle(cb), SideInBattle(cb)}),
|
||||
layout(std::make_unique<BattleLayout>()),
|
||||
|
@@ -74,8 +74,8 @@ public:
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
BattleInfo(IGameCallback *cb, const BattleLayout & layout);
|
||||
BattleInfo(IGameCallback *cb);
|
||||
BattleInfo(IGameInfoCallback *cb, const BattleLayout & layout);
|
||||
BattleInfo(IGameInfoCallback *cb);
|
||||
virtual ~BattleInfo();
|
||||
|
||||
const IBattleInfo * getBattle() const override;
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
const CGHeroInstance * getHero(const PlayerColor & player) const; //returns fighting hero that belongs to given player
|
||||
|
||||
void localInit();
|
||||
static std::unique_ptr<BattleInfo> setupBattle(IGameCallback *cb, const int3 & tile, TerrainId, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town);
|
||||
static std::unique_ptr<BattleInfo> setupBattle(IGameInfoCallback *cb, const int3 & tile, TerrainId, const BattleField & battlefieldType, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance * town);
|
||||
|
||||
BattleSide whatSide(const PlayerColor & player) const;
|
||||
|
||||
|
@@ -12,18 +12,18 @@
|
||||
|
||||
#include "../GameSettings.h"
|
||||
#include "../GameLibrary.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../json/JsonNode.h"
|
||||
#include "../mapObjects/CArmedInstance.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
BattleLayout BattleLayout::createDefaultLayout(IGameCallback * cb, const CArmedInstance * attacker, const CArmedInstance * defender)
|
||||
BattleLayout BattleLayout::createDefaultLayout(IGameInfoCallback * cb, const CArmedInstance * attacker, const CArmedInstance * defender)
|
||||
{
|
||||
return createLayout(cb, "default", attacker, defender);
|
||||
}
|
||||
|
||||
BattleLayout BattleLayout::createLayout(IGameCallback * cb, const std::string & layoutName, const CArmedInstance * attacker, const CArmedInstance * defender)
|
||||
BattleLayout BattleLayout::createLayout(IGameInfoCallback * cb, const std::string & layoutName, const CArmedInstance * attacker, const CArmedInstance * defender)
|
||||
{
|
||||
const auto & loadHex = [](const JsonNode & node)
|
||||
{
|
||||
|
@@ -17,7 +17,7 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CArmedInstance;
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
|
||||
struct DLL_EXPORT BattleLayout
|
||||
{
|
||||
@@ -32,8 +32,8 @@ struct DLL_EXPORT BattleLayout
|
||||
bool tacticsAllowed = false;
|
||||
bool obstaclesAllowed = false;
|
||||
|
||||
static BattleLayout createDefaultLayout(IGameCallback * cb, const CArmedInstance * attacker, const CArmedInstance * defender);
|
||||
static BattleLayout createLayout(IGameCallback * cb, const std::string & layoutName, const CArmedInstance * attacker, const CArmedInstance * defender);
|
||||
static BattleLayout createDefaultLayout(IGameInfoCallback * cb, const CArmedInstance * attacker, const CArmedInstance * defender);
|
||||
static BattleLayout createLayout(IGameInfoCallback * cb, const std::string & layoutName, const CArmedInstance * attacker, const CArmedInstance * defender);
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "SideInBattle.h"
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "../entities/building/CBuilding.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../gameState/UpgradeInfo.h"
|
||||
#include "../gameState/InfoAboutArmy.h"
|
||||
#include "../gameState/TavernHeroesPool.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
@@ -143,7 +144,7 @@ const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool v
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!isVisible(ret, getPlayerID()) && ret->tempOwner != getPlayerID())
|
||||
if(getPlayerID().has_value() && !isVisibleFor(ret, *getPlayerID()) && ret->tempOwner != getPlayerID())
|
||||
{
|
||||
if(verbose)
|
||||
logGlobal->error("Cannot get object with id %d. Object is not visible.", objid.getNum());
|
||||
@@ -183,7 +184,36 @@ void CGameInfoCallback::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackP
|
||||
{
|
||||
ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!");
|
||||
ERROR_RET_IF(!obj->hasStackAtSlot(stackPos), "There is no such stack!");
|
||||
gameState().fillUpgradeInfo(obj, stackPos, out);
|
||||
|
||||
const auto & stack = obj->getStack(stackPos);
|
||||
const CCreature *base = stack.getCreature();
|
||||
UpgradeInfo ret(base->getId());
|
||||
|
||||
if (stack.getArmy()->ID == Obj::HERO)
|
||||
{
|
||||
auto hero = dynamic_cast<const CGHeroInstance *>(stack.getArmy());
|
||||
hero->fillUpgradeInfo(ret, stack);
|
||||
|
||||
if (hero->getVisitedTown())
|
||||
{
|
||||
hero->getVisitedTown()->fillUpgradeInfo(ret, stack);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto object = vstd::frontOrNull(getVisitableObjs(hero->visitablePos()));
|
||||
auto upgradeSource = dynamic_cast<const ICreatureUpgrader*>(object);
|
||||
if (object != hero && upgradeSource != nullptr)
|
||||
upgradeSource->fillUpgradeInfo(ret, stack);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getArmy()->ID == Obj::TOWN)
|
||||
{
|
||||
auto town = dynamic_cast<const CGTownInstance *>(stack.getArmy());
|
||||
town->fillUpgradeInfo(ret, stack);
|
||||
}
|
||||
|
||||
out = ret;
|
||||
}
|
||||
|
||||
const StartInfo * CGameInfoCallback::getStartInfo() const
|
||||
@@ -244,7 +274,7 @@ int CGameInfoCallback::howManyTowns(PlayerColor Player) const
|
||||
|
||||
bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject) const
|
||||
{
|
||||
ERROR_RET_VAL_IF(!isVisible(town, getPlayerID()), "Town is not visible!", false); //it's not a town or it's not visible for layer
|
||||
ERROR_RET_VAL_IF(getPlayerID().has_value() && !isVisibleFor(town, *getPlayerID()), "Town is not visible!", false); //it's not a town or it's not visible for layer
|
||||
bool detailed = hasAccess(town->tempOwner);
|
||||
|
||||
if(town->ID == Obj::TOWN)
|
||||
@@ -270,10 +300,10 @@ const IGameSettings & CGameInfoCallback::getSettings() const
|
||||
return gameState().getSettings();
|
||||
}
|
||||
|
||||
int3 CGameInfoCallback::guardingCreaturePosition (int3 pos) const //FIXME: redundant?
|
||||
int3 CGameInfoCallback::guardingCreaturePosition (int3 pos) const
|
||||
{
|
||||
ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", int3(-1,-1,-1));
|
||||
return gameState().guardingCreaturePosition(pos);
|
||||
return gameState().getMap().guardingCreaturePositions[pos.z][pos.x][pos.y];
|
||||
}
|
||||
|
||||
std::vector<const CGObjectInstance*> CGameInfoCallback::getGuardingCreatures (int3 pos) const
|
||||
@@ -413,24 +443,28 @@ int CGameInfoCallback::getDate(Date mode) const
|
||||
return gameState().getDate(mode);
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::isVisible(int3 pos, const std::optional<PlayerColor> & Player) const
|
||||
bool CGameInfoCallback::isVisibleFor(int3 pos, PlayerColor player) const
|
||||
{
|
||||
return gameState().isVisible(pos, Player);
|
||||
return gameState().isVisibleFor(pos, player);
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::isVisible(int3 pos) const
|
||||
{
|
||||
return isVisible(pos, getPlayerID());
|
||||
if (!getPlayerID().has_value())
|
||||
return true; // weird, but we do have such calls
|
||||
return gameState().isVisibleFor(pos, *getPlayerID());
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & Player) const
|
||||
bool CGameInfoCallback::isVisibleFor(const CGObjectInstance * obj, PlayerColor player) const
|
||||
{
|
||||
return gameState().isVisible(obj, Player);
|
||||
return gameState().isVisibleFor(obj, player);
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::isVisible(const CGObjectInstance *obj) const
|
||||
{
|
||||
return isVisible(obj, getPlayerID());
|
||||
if (!getPlayerID().has_value())
|
||||
return true; // weird, but we do have such calls
|
||||
return gameState().isVisibleFor(obj, *getPlayerID());
|
||||
}
|
||||
|
||||
std::vector <const CGObjectInstance *> CGameInfoCallback::getBlockingObjs( int3 pos ) const
|
||||
@@ -500,7 +534,6 @@ std::vector<const CGHeroInstance *> CGameInfoCallback::getAvailableHeroes(const
|
||||
{
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
std::vector<const CGHeroInstance *> ret;
|
||||
//ERROR_RET_VAL_IF(!isOwnedOrVisited(townOrTavern), "Town or tavern must be owned or visited!", ret);
|
||||
//TODO: town needs to be owned, advmap tavern needs to be visited; to be reimplemented when visit tracking is done
|
||||
const CGTownInstance * town = getTown(townOrTavern->id);
|
||||
|
||||
@@ -685,17 +718,6 @@ int CGameInfoCallback::getHeroCount( PlayerColor player, bool includeGarrisoned
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::isOwnedOrVisited(const CGObjectInstance *obj) const
|
||||
{
|
||||
if(canGetFullInfo(obj))
|
||||
return true;
|
||||
|
||||
const TerrainTile *t = getTile(obj->visitablePos()); //get entrance tile
|
||||
const ObjectInstanceID visitorID = t->visitableObjects.back(); //visitong hero if present or the object itself at last
|
||||
const CGObjectInstance * visitor = getObj(visitorID);
|
||||
return visitor->ID == Obj::HERO && canGetFullInfo(visitor); //owned or allied hero is a visitor
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::isPlayerMakingTurn(PlayerColor player) const
|
||||
{
|
||||
return gameState().actingPlayers.count(player);
|
||||
@@ -778,7 +800,7 @@ std::vector<ObjectInstanceID> CGameInfoCallback::getVisibleTeleportObjects(std::
|
||||
vstd::erase_if(ids, [&](const ObjectInstanceID & id) -> bool
|
||||
{
|
||||
const auto * obj = getObj(id, false);
|
||||
return player != PlayerColor::UNFLAGGABLE && (!obj || !isVisible(obj->visitablePos(), player));
|
||||
return player != PlayerColor::UNFLAGGABLE && (!obj || !isVisibleFor(obj->visitablePos(), player));
|
||||
});
|
||||
return ids;
|
||||
}
|
||||
@@ -832,4 +854,130 @@ bool CGameInfoCallback::isTeleportEntrancePassable(const CGTeleport * obj, Playe
|
||||
return obj && obj->isEntrance() && !isTeleportChannelImpassable(obj->channel, player);
|
||||
}
|
||||
|
||||
void CGameInfoCallback::getFreeTiles(std::vector<int3> & tiles) const
|
||||
{
|
||||
std::vector<int> floors;
|
||||
floors.reserve(gameState().getMap().levels());
|
||||
for(int b = 0; b < gameState().getMap().levels(); ++b)
|
||||
{
|
||||
floors.push_back(b);
|
||||
}
|
||||
const TerrainTile * tinfo = nullptr;
|
||||
for (auto zd : floors)
|
||||
{
|
||||
for (int xd = 0; xd < gameState().getMap().width; xd++)
|
||||
{
|
||||
for (int yd = 0; yd < gameState().getMap().height; yd++)
|
||||
{
|
||||
tinfo = getTile(int3 (xd,yd,zd));
|
||||
if (tinfo->isLand() && tinfo->getTerrain()->isPassable() && !tinfo->blocked()) //land and free
|
||||
tiles.emplace_back(xd, yd, zd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameInfoCallback::getTilesInRange(std::unordered_set<int3> & tiles,
|
||||
const int3 & pos,
|
||||
int radious,
|
||||
ETileVisibility mode,
|
||||
std::optional<PlayerColor> player,
|
||||
int3::EDistanceFormula distanceFormula) const
|
||||
{
|
||||
if(player.has_value() && !player->isValidPlayer())
|
||||
{
|
||||
logGlobal->error("Illegal call to getTilesInRange!");
|
||||
return;
|
||||
}
|
||||
if(radious == CBuilding::HEIGHT_SKYSHIP) //reveal entire map
|
||||
getAllTiles (tiles, player, -1, [](auto * tile){return true;});
|
||||
else
|
||||
{
|
||||
const TeamState * team = !player ? nullptr : gameState().getPlayerTeam(*player);
|
||||
for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, gameState().getMap().width - 1); xd++)
|
||||
{
|
||||
for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gameState().getMap().height - 1); yd++)
|
||||
{
|
||||
int3 tilePos(xd,yd,pos.z);
|
||||
int distance = pos.dist(tilePos, distanceFormula);
|
||||
|
||||
if(distance <= radious)
|
||||
{
|
||||
if(!player
|
||||
|| (mode == ETileVisibility::HIDDEN && team->fogOfWarMap[pos.z][xd][yd] == 0)
|
||||
|| (mode == ETileVisibility::REVEALED && team->fogOfWarMap[pos.z][xd][yd] == 1)
|
||||
)
|
||||
tiles.insert(int3(xd,yd,pos.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std::optional<PlayerColor> Player, int level, std::function<bool(const TerrainTile *)> filter) const
|
||||
{
|
||||
if(Player.has_value() && !Player->isValidPlayer())
|
||||
{
|
||||
logGlobal->error("Illegal call to getAllTiles !");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> floors;
|
||||
if(level == -1)
|
||||
{
|
||||
for(int b = 0; b < gameState().getMap().levels(); ++b)
|
||||
{
|
||||
floors.push_back(b);
|
||||
}
|
||||
}
|
||||
else
|
||||
floors.push_back(level);
|
||||
|
||||
for(auto zd: floors)
|
||||
{
|
||||
for(int xd = 0; xd < gameState().getMap().width; xd++)
|
||||
{
|
||||
for(int yd = 0; yd < gameState().getMap().height; yd++)
|
||||
{
|
||||
int3 coordinates(xd, yd, zd);
|
||||
if (filter(getTile(coordinates)))
|
||||
tiles.insert(coordinates);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameInfoCallback::pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand)
|
||||
{
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(gameState().pickRandomArtifact(rand, EArtifactClass::ART_TREASURE));
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(gameState().pickRandomArtifact(rand, EArtifactClass::ART_MINOR));
|
||||
|
||||
out.push_back(gameState().pickRandomArtifact(rand, EArtifactClass::ART_MAJOR));
|
||||
}
|
||||
|
||||
void CGameInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
||||
{
|
||||
for (auto const & spellID : gameState().getMap().allowedSpells)
|
||||
{
|
||||
const auto * spell = spellID.toEntity(LIBRARY);
|
||||
|
||||
if (!isAllowed(spellID))
|
||||
continue;
|
||||
|
||||
if (level.has_value() && spell->getLevel() != level)
|
||||
continue;
|
||||
|
||||
out.push_back(spellID);
|
||||
}
|
||||
}
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::Pool * CGameInfoCallback::getGlobalContextPool() const
|
||||
{
|
||||
return nullptr; // TODO
|
||||
}
|
||||
#endif
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -11,130 +11,115 @@
|
||||
|
||||
#include "IGameInfoCallback.h"
|
||||
|
||||
#include "../int3.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct PlayerSettings;
|
||||
struct TerrainTile;
|
||||
struct InfoAboutHero;
|
||||
struct InfoAboutTown;
|
||||
struct SThievesGuildInfo;
|
||||
struct TeamState;
|
||||
struct TurnTimerInfo;
|
||||
struct ArtifactLocation;
|
||||
|
||||
class IGameSettings;
|
||||
class PlayerState;
|
||||
class UpgradeInfo;
|
||||
class CMapHeader;
|
||||
class CGameState;
|
||||
class PathfinderConfig;
|
||||
class CArtifactSet;
|
||||
class CArmedInstance;
|
||||
class CGTeleport;
|
||||
class CGTownInstance;
|
||||
class IMarket;
|
||||
class Player;
|
||||
|
||||
class DLL_LINKAGE CGameInfoCallback : public IGameInfoCallback
|
||||
{
|
||||
protected:
|
||||
virtual CGameState & gameState() = 0;
|
||||
virtual const CGameState & gameState() const = 0;
|
||||
|
||||
bool hasAccess(std::optional<PlayerColor> playerId) const;
|
||||
|
||||
bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode
|
||||
bool isOwnedOrVisited(const CGObjectInstance *obj) const;
|
||||
|
||||
public:
|
||||
//various
|
||||
int getDate(Date mode=Date::DAY)const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
const StartInfo * getStartInfo() const override;
|
||||
const StartInfo * getInitialStartInfo() const override;
|
||||
const StartInfo * getInitialStartInfo() const;
|
||||
bool isAllowed(SpellID id) const override;
|
||||
bool isAllowed(ArtifactID id) const override;
|
||||
bool isAllowed(SecondarySkill id) const override;
|
||||
const IGameSettings & getSettings() const;
|
||||
const IGameSettings & getSettings() const override;
|
||||
|
||||
//player
|
||||
std::optional<PlayerColor> getPlayerID() const override;
|
||||
const Player * getPlayer(PlayerColor color) const override;
|
||||
virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const;
|
||||
virtual int getResource(PlayerColor Player, GameResID which) const;
|
||||
virtual PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
|
||||
virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
|
||||
virtual EPlayerStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
|
||||
virtual bool isPlayerMakingTurn(PlayerColor player) const; //player that currently makes move // TODO synchronous turns
|
||||
virtual const PlayerSettings * getPlayerSettings(PlayerColor color) const;
|
||||
virtual TurnTimerInfo getPlayerTurnTime(PlayerColor color) const;
|
||||
virtual std::optional<PlayerColor> getPlayerID() const;
|
||||
const Player * getPlayer(PlayerColor color) const;
|
||||
const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const override;
|
||||
int getResource(PlayerColor Player, GameResID which) const override;
|
||||
PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const override;
|
||||
void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj);
|
||||
EPlayerStatus getPlayerStatus(PlayerColor player, bool verbose = true) const override;
|
||||
bool isPlayerMakingTurn(PlayerColor player) const;
|
||||
const PlayerSettings * getPlayerSettings(PlayerColor color) const override;
|
||||
TurnTimerInfo getPlayerTurnTime(PlayerColor color) const;
|
||||
|
||||
//map
|
||||
virtual bool isVisible(int3 pos, const std::optional<PlayerColor> & Player) const;
|
||||
virtual bool isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & Player) const;
|
||||
virtual bool isVisible(const CGObjectInstance * obj) const;
|
||||
virtual bool isVisible(int3 pos) const;
|
||||
bool isVisibleFor(int3 pos, PlayerColor player) const override;
|
||||
bool isVisibleFor(const CGObjectInstance * obj, PlayerColor player) const override;
|
||||
bool isVisible(const CGObjectInstance * obj) const;
|
||||
bool isVisible(int3 pos) const;
|
||||
|
||||
//armed object
|
||||
virtual void fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const;
|
||||
void fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const;
|
||||
|
||||
//hero
|
||||
const CGHeroInstance * getHero(ObjectInstanceID objid) const override;
|
||||
virtual int getHeroCount(PlayerColor player, bool includeGarrisoned) const;
|
||||
virtual bool getHeroInfo(const CGObjectInstance * hero, InfoAboutHero & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||
virtual int32_t getSpellCost(const spells::Spell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction
|
||||
virtual int64_t estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg
|
||||
virtual const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const;
|
||||
virtual const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const;
|
||||
virtual const CArtifactSet * getArtSet(const ArtifactLocation & loc) const;
|
||||
//virtual const CGObjectInstance * getArmyInstance(ObjectInstanceID oid) const;
|
||||
int getHeroCount(PlayerColor player, bool includeGarrisoned) const override;
|
||||
bool getHeroInfo(const CGObjectInstance * hero, InfoAboutHero & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||
int32_t getSpellCost(const spells::Spell * sp, const CGHeroInstance * caster) const;
|
||||
int64_t estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const;
|
||||
const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const override;
|
||||
const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const override;
|
||||
const CArtifactSet * getArtSet(const ArtifactLocation & loc) const;
|
||||
|
||||
//objects
|
||||
const CGObjectInstance * getObj(ObjectInstanceID objid, bool verbose = true) const override;
|
||||
virtual std::vector<const CGObjectInstance *> getBlockingObjs(int3 pos) const;
|
||||
std::vector<const CGObjectInstance *> getVisitableObjs(int3 pos, bool verbose = true) const override;
|
||||
std::vector<const CGObjectInstance *> getBlockingObjs(int3 pos) const;
|
||||
std::vector<const CGObjectInstance *> getVisitableObjs(int3 pos, bool verbose = true) const;
|
||||
std::vector<const CGObjectInstance *> getAllVisitableObjs() const;
|
||||
virtual std::vector<const CGObjectInstance *> getFlaggableObjects(int3 pos) const;
|
||||
virtual const CGObjectInstance * getTopObj(int3 pos) const;
|
||||
virtual PlayerColor getOwner(ObjectInstanceID heroID) const;
|
||||
virtual const IMarket * getMarket(ObjectInstanceID objid) const;
|
||||
std::vector<const CGObjectInstance *> getFlaggableObjects(int3 pos) const;
|
||||
const CGObjectInstance * getTopObj(int3 pos) const override;
|
||||
PlayerColor getOwner(ObjectInstanceID heroID) const;
|
||||
const IMarket * getMarket(ObjectInstanceID objid) const;
|
||||
|
||||
//map
|
||||
virtual int3 guardingCreaturePosition (int3 pos) const;
|
||||
virtual std::vector<const CGObjectInstance*> getGuardingCreatures (int3 pos) const;
|
||||
virtual bool isTileGuardedUnchecked(int3 tile) const;
|
||||
virtual const CMapHeader * getMapHeader()const;
|
||||
virtual int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||
virtual const TerrainTile * getTile(int3 tile, bool verbose = true) const;
|
||||
virtual const TerrainTile * getTileUnchecked(int3 tile) const;
|
||||
virtual bool isInTheMap(const int3 &pos) const;
|
||||
virtual void getVisibleTilesInRange(std::unordered_set<int3> &tiles, int3 pos, int radious, int3::EDistanceFormula distanceFormula = int3::DIST_2D) const;
|
||||
virtual void calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const;
|
||||
virtual EDiggingStatus getTileDigStatus(int3 tile, bool verbose = true) const;
|
||||
int3 guardingCreaturePosition (int3 pos) const;
|
||||
std::vector<const CGObjectInstance*> getGuardingCreatures (int3 pos) const;
|
||||
bool isTileGuardedUnchecked(int3 tile) const;
|
||||
const CMapHeader * getMapHeader()const override;
|
||||
int3 getMapSize() const override;
|
||||
const TerrainTile * getTile(int3 tile, bool verbose = true) const override;
|
||||
const TerrainTile * getTileUnchecked(int3 tile) const override;
|
||||
bool isInTheMap(const int3 &pos) const override;
|
||||
void getVisibleTilesInRange(std::unordered_set<int3> &tiles, int3 pos, int radious, int3::EDistanceFormula distanceFormula = int3::DIST_2D) const;
|
||||
void calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const override;
|
||||
EDiggingStatus getTileDigStatus(int3 tile, bool verbose = true) const override;
|
||||
|
||||
//town
|
||||
virtual const CGTownInstance* getTown(ObjectInstanceID objid) const;
|
||||
virtual int howManyTowns(PlayerColor Player) const;
|
||||
//virtual const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
|
||||
virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
|
||||
virtual std::string getTavernRumor(const CGObjectInstance * townOrTavern) const;
|
||||
virtual EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||
virtual bool getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||
const CGTownInstance* getTown(ObjectInstanceID objid) const override;
|
||||
int howManyTowns(PlayerColor Player) const;
|
||||
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const;
|
||||
std::string getTavernRumor(const CGObjectInstance * townOrTavern) const;
|
||||
EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);
|
||||
bool getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||
|
||||
//from gs
|
||||
virtual const TeamState *getTeam(TeamID teamID) const;
|
||||
virtual const TeamState *getPlayerTeam(PlayerColor color) const;
|
||||
//virtual EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||
const TeamState *getTeam(TeamID teamID) const override;
|
||||
const TeamState *getPlayerTeam(PlayerColor color) const override;
|
||||
|
||||
//teleport
|
||||
virtual std::vector<ObjectInstanceID> getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player) const;
|
||||
virtual std::vector<ObjectInstanceID> getTeleportChannelEntrances(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
|
||||
virtual std::vector<ObjectInstanceID> getTeleportChannelExits(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
|
||||
virtual ETeleportChannelType getTeleportChannelType(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
virtual bool isTeleportChannelImpassable(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
virtual bool isTeleportChannelBidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
virtual bool isTeleportChannelUnidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
virtual bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const;
|
||||
std::vector<ObjectInstanceID> getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player) const override;
|
||||
std::vector<ObjectInstanceID> getTeleportChannelEntrances(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const override;
|
||||
std::vector<ObjectInstanceID> getTeleportChannelExits(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const override;
|
||||
ETeleportChannelType getTeleportChannelType(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
bool isTeleportChannelImpassable(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const override;
|
||||
bool isTeleportChannelBidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const override;
|
||||
bool isTeleportChannelUnidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const override;
|
||||
bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const override;
|
||||
|
||||
//used for random spawns
|
||||
void getFreeTiles(std::vector<int3> &tiles) const;
|
||||
void getTilesInRange(std::unordered_set<int3> & tiles, const int3 & pos, int radius, ETileVisibility mode, std::optional<PlayerColor> player = std::optional<PlayerColor>(), int3::EDistanceFormula formula = int3::DIST_2D) const override;
|
||||
void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const override;
|
||||
|
||||
void pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand) override;
|
||||
void getAllowedSpells(std::vector<SpellID> &out, std::optional<ui16> level = std::nullopt);
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
virtual scripting::Pool * getGlobalContextPool() const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CPrivilegedInfoCallback.h"
|
||||
#include "CGameInfoCallback.h"
|
||||
|
||||
#include <vcmi/Metatype.h>
|
||||
|
||||
@@ -17,7 +17,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class JsonNode;
|
||||
|
||||
class DLL_LINKAGE CNonConstInfoCallback : public CPrivilegedInfoCallback
|
||||
class DLL_LINKAGE CNonConstInfoCallback : public CGameInfoCallback
|
||||
{
|
||||
public:
|
||||
//keep const version of callback accessible
|
||||
|
@@ -38,7 +38,7 @@ std::vector < const CGTownInstance *> CPlayerSpecificInfoCallback::getTownsInfo(
|
||||
{
|
||||
for(const auto & town : i.second.getTowns())
|
||||
{
|
||||
if(i.first == getPlayerID() || (!onlyOur && isVisible(town, getPlayerID())))
|
||||
if(i.first == getPlayerID() || (!onlyOur && isVisibleFor(town, *getPlayerID())))
|
||||
{
|
||||
ret.push_back(town);
|
||||
}
|
||||
|
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* CPrivilegedInfoCallback.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CPrivilegedInfoCallback.h"
|
||||
|
||||
#include "../CPlayerState.h"
|
||||
#include "../entities/artifact/EArtifactClass.h"
|
||||
#include "../entities/building/CBuilding.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../mapping/CMap.h"
|
||||
#include "../spells/CSpellHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
void CPrivilegedInfoCallback::getFreeTiles(std::vector<int3> & tiles) const
|
||||
{
|
||||
std::vector<int> floors;
|
||||
floors.reserve(gameState().getMap().levels());
|
||||
for(int b = 0; b < gameState().getMap().levels(); ++b)
|
||||
{
|
||||
floors.push_back(b);
|
||||
}
|
||||
const TerrainTile * tinfo = nullptr;
|
||||
for (auto zd : floors)
|
||||
{
|
||||
for (int xd = 0; xd < gameState().getMap().width; xd++)
|
||||
{
|
||||
for (int yd = 0; yd < gameState().getMap().height; yd++)
|
||||
{
|
||||
tinfo = getTile(int3 (xd,yd,zd));
|
||||
if (tinfo->isLand() && tinfo->getTerrain()->isPassable() && !tinfo->blocked()) //land and free
|
||||
tiles.emplace_back(xd, yd, zd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::getTilesInRange(std::unordered_set<int3> & tiles,
|
||||
const int3 & pos,
|
||||
int radious,
|
||||
ETileVisibility mode,
|
||||
std::optional<PlayerColor> player,
|
||||
int3::EDistanceFormula distanceFormula) const
|
||||
{
|
||||
if(!!player && !player->isValidPlayer())
|
||||
{
|
||||
logGlobal->error("Illegal call to getTilesInRange!");
|
||||
return;
|
||||
}
|
||||
if(radious == CBuilding::HEIGHT_SKYSHIP) //reveal entire map
|
||||
getAllTiles (tiles, player, -1, [](auto * tile){return true;});
|
||||
else
|
||||
{
|
||||
const TeamState * team = !player ? nullptr : gameState().getPlayerTeam(*player);
|
||||
for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, gameState().getMap().width - 1); xd++)
|
||||
{
|
||||
for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gameState().getMap().height - 1); yd++)
|
||||
{
|
||||
int3 tilePos(xd,yd,pos.z);
|
||||
int distance = pos.dist(tilePos, distanceFormula);
|
||||
|
||||
if(distance <= radious)
|
||||
{
|
||||
if(!player
|
||||
|| (mode == ETileVisibility::HIDDEN && team->fogOfWarMap[pos.z][xd][yd] == 0)
|
||||
|| (mode == ETileVisibility::REVEALED && team->fogOfWarMap[pos.z][xd][yd] == 1)
|
||||
)
|
||||
tiles.insert(int3(xd,yd,pos.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std::optional<PlayerColor> Player, int level, std::function<bool(const TerrainTile *)> filter) const
|
||||
{
|
||||
if(!!Player && !Player->isValidPlayer())
|
||||
{
|
||||
logGlobal->error("Illegal call to getAllTiles !");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> floors;
|
||||
if(level == -1)
|
||||
{
|
||||
for(int b = 0; b < gameState().getMap().levels(); ++b)
|
||||
{
|
||||
floors.push_back(b);
|
||||
}
|
||||
}
|
||||
else
|
||||
floors.push_back(level);
|
||||
|
||||
for(auto zd: floors)
|
||||
{
|
||||
for(int xd = 0; xd < gameState().getMap().width; xd++)
|
||||
{
|
||||
for(int yd = 0; yd < gameState().getMap().height; yd++)
|
||||
{
|
||||
int3 coordinates(xd, yd, zd);
|
||||
if (filter(getTile(coordinates)))
|
||||
tiles.insert(coordinates);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand)
|
||||
{
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(gameState().pickRandomArtifact(rand, EArtifactClass::ART_TREASURE));
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(gameState().pickRandomArtifact(rand, EArtifactClass::ART_MINOR));
|
||||
|
||||
out.push_back(gameState().pickRandomArtifact(rand, EArtifactClass::ART_MAJOR));
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
||||
{
|
||||
for (auto const & spellID : gameState().getMap().allowedSpells)
|
||||
{
|
||||
const auto * spell = spellID.toEntity(LIBRARY);
|
||||
|
||||
if (!isAllowed(spellID))
|
||||
continue;
|
||||
|
||||
if (level.has_value() && spell->getLevel() != level)
|
||||
continue;
|
||||
|
||||
out.push_back(spellID);
|
||||
}
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* CPrivilegedInfoCallback.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
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CGameInfoCallback.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
namespace vstd
|
||||
{
|
||||
class RNG;
|
||||
}
|
||||
|
||||
class DLL_LINKAGE CPrivilegedInfoCallback : public CGameInfoCallback
|
||||
{
|
||||
public:
|
||||
using CGameInfoCallback::gameState; // make public
|
||||
|
||||
//used for random spawns
|
||||
void getFreeTiles(std::vector<int3> &tiles) const;
|
||||
|
||||
//mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only revealed
|
||||
void getTilesInRange(std::unordered_set<int3> & tiles,
|
||||
const int3 & pos,
|
||||
int radius,
|
||||
ETileVisibility mode,
|
||||
std::optional<PlayerColor> player = std::optional<PlayerColor>(),
|
||||
int3::EDistanceFormula formula = int3::DIST_2D) const;
|
||||
|
||||
//returns all tiles on given level (-1 - both levels, otherwise number of level)
|
||||
void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const;
|
||||
|
||||
//gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||
void pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand);
|
||||
void getAllowedSpells(std::vector<SpellID> &out, std::optional<ui16> level = std::nullopt);
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@@ -11,14 +11,14 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
|
||||
class DLL_LINKAGE GameCallbackHolder
|
||||
{
|
||||
public:
|
||||
IGameCallback * cb;
|
||||
IGameInfoCallback * cb;
|
||||
|
||||
explicit GameCallbackHolder(IGameCallback *cb):
|
||||
explicit GameCallbackHolder(IGameInfoCallback *cb):
|
||||
cb(cb)
|
||||
{}
|
||||
};
|
||||
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* IGameCallback.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
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CPrivilegedInfoCallback.h"
|
||||
#include "IGameEventCallback.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
namespace scripting
|
||||
{
|
||||
class Pool;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Interface class for handling general game logic and actions
|
||||
class DLL_LINKAGE IGameCallback : public CPrivilegedInfoCallback, public IGameEventCallback
|
||||
{
|
||||
public:
|
||||
virtual ~IGameCallback(){};
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
virtual scripting::Pool * getGlobalContextPool() const = 0;
|
||||
#endif
|
||||
|
||||
//get info
|
||||
virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) { return false; }
|
||||
|
||||
friend struct CPack;
|
||||
friend struct CPackForClient;
|
||||
friend struct CPackForServer;
|
||||
};
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@@ -115,6 +115,8 @@ public:
|
||||
|
||||
virtual void castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) = 0;
|
||||
|
||||
virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) = 0;
|
||||
|
||||
virtual vstd::RNG & getRandomGenerator() = 0;
|
||||
};
|
||||
|
||||
|
@@ -11,92 +11,157 @@
|
||||
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
#include "../constants/Enumerations.h"
|
||||
#include "../int3.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class int3;
|
||||
struct StartInfo;
|
||||
|
||||
class CGHeroInstance;
|
||||
class CGObjectInstance;
|
||||
class Player;
|
||||
|
||||
struct PlayerSettings;
|
||||
struct TerrainTile;
|
||||
struct InfoAboutHero;
|
||||
struct InfoAboutTown;
|
||||
struct TeamState;
|
||||
struct TurnTimerInfo;
|
||||
struct ArtifactLocation;
|
||||
|
||||
class IGameSettings;
|
||||
class PlayerState;
|
||||
class UpgradeInfo;
|
||||
class CMapHeader;
|
||||
class CGameState;
|
||||
class PathfinderConfig;
|
||||
class CArtifactSet;
|
||||
class CArmedInstance;
|
||||
class CGTeleport;
|
||||
class CGTownInstance;
|
||||
class IMarket;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
namespace scripting
|
||||
{
|
||||
class Pool;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace vstd
|
||||
{
|
||||
class RNG;
|
||||
}
|
||||
|
||||
/// Provide interfaces through which map objects can access game state data
|
||||
/// TODO: currently it is also used as Environment::GameCb. Consider separating these two interfaces
|
||||
class DLL_LINKAGE IGameInfoCallback : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
//TODO: all other public methods of CGameInfoCallback
|
||||
~IGameInfoCallback() = default;
|
||||
|
||||
// //various
|
||||
virtual int getDate(Date mode=Date::DAY) const = 0; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
/// Access underlying non-const gamestate
|
||||
/// TODO: remove ASAP
|
||||
virtual CGameState & gameState() = 0;
|
||||
|
||||
/// Access underlying gamestate
|
||||
/// TODO: remove
|
||||
virtual const CGameState & gameState() const = 0;
|
||||
|
||||
/// Returns current date:
|
||||
/// DAY - number of days since start of the game (1..inf)
|
||||
/// DAY_OF_WEEK - number of days since start of the week (1..7)
|
||||
/// WEEK - number of week within month (1..4)
|
||||
/// MONTH - current month (1..inf)
|
||||
/// DAY_OF_MONTH - number of day within current month, (1..28)
|
||||
virtual int getDate(Date mode=Date::DAY)const = 0;
|
||||
|
||||
/// Return pointer to static map header for current map
|
||||
virtual const CMapHeader * getMapHeader()const = 0;
|
||||
|
||||
/// Returns post-randomized startin information on current game
|
||||
virtual const StartInfo * getStartInfo() const = 0;
|
||||
virtual const StartInfo * getInitialStartInfo() const = 0;
|
||||
|
||||
/// Returns true if corresponding spell is allowed, and not banned in map settings
|
||||
virtual bool isAllowed(SpellID id) const = 0;
|
||||
/// Returns true if corresponding artifact is allowed, and not banned in map settings
|
||||
virtual bool isAllowed(ArtifactID id) const = 0;
|
||||
/// Returns true if corresponding secondary skill is allowed, and not banned in map settings
|
||||
virtual bool isAllowed(SecondarySkill id) const = 0;
|
||||
|
||||
//player
|
||||
virtual std::optional<PlayerColor> getPlayerID() const = 0;
|
||||
virtual const Player * getPlayer(PlayerColor color) const = 0;
|
||||
// virtual int getResource(PlayerColor Player, EGameResID which) const = 0;
|
||||
// bool isVisible(int3 pos) const;
|
||||
// PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
|
||||
// void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
|
||||
// EPlayerStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
|
||||
// const PlayerSettings * getPlayerSettings(PlayerColor color) const;
|
||||
/// Returns true if specified tile is visible for specific player. Player must be valid
|
||||
virtual bool isVisibleFor(int3 pos, PlayerColor player) const = 0;
|
||||
|
||||
/// Returns true if specified object is visible for specific player. Player must be valid
|
||||
virtual bool isVisibleFor(const CGObjectInstance * obj, PlayerColor player) const = 0;
|
||||
|
||||
// //armed object
|
||||
// void fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out)const;
|
||||
//// Returns game settings for current map
|
||||
virtual const IGameSettings & getSettings() const = 0;
|
||||
|
||||
//hero
|
||||
/// Returns dimesions for current map. 'z' coordinate indicates number of level (2 for maps with underground layer)
|
||||
virtual int3 getMapSize() const = 0;
|
||||
/// Returns true if tile with specified position exists within map
|
||||
virtual bool isInTheMap(const int3 &pos) const = 0;
|
||||
|
||||
/// Returns pointer to specified team. Team must be valid
|
||||
virtual const TeamState *getTeam(TeamID teamID) const = 0;
|
||||
/// Returns pointer to specified team. Player must be valid. Players without belong to a team with single member
|
||||
virtual const TeamState *getPlayerTeam(PlayerColor color) const = 0;
|
||||
/// Returns current state of a specific player. Player must be valid
|
||||
virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const = 0;
|
||||
/// Returns starting settings of a specified player. Player must be valid
|
||||
virtual const PlayerSettings * getPlayerSettings(PlayerColor color) const = 0;
|
||||
/// Returns relations (allies, enemies, etc) of two specified, valid players
|
||||
virtual PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const = 0;
|
||||
/// Returns number of wandering heroes or wandering and garrisoned heroes for specified player
|
||||
virtual int getHeroCount(PlayerColor player, bool includeGarrisoned) const = 0;
|
||||
/// Returns in-game status if specified player. Player must be valid
|
||||
virtual EPlayerStatus getPlayerStatus(PlayerColor player, bool verbose = true) const = 0;
|
||||
/// Returns amount of resource of a specific type owned by a specified player
|
||||
virtual int getResource(PlayerColor Player, GameResID which) const = 0;
|
||||
|
||||
/// Returns pointer to hero using provided object ID. Returns null on failure
|
||||
virtual const CGHeroInstance * getHero(ObjectInstanceID objid) const = 0;
|
||||
// int getHeroCount(PlayerColor player, bool includeGarrisoned) const;
|
||||
// bool getHeroInfo(const CGObjectInstance * hero, InfoAboutHero & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||
// int32_t getSpellCost(const spells::Spell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction
|
||||
// int64_t estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg
|
||||
// const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const;
|
||||
// const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const;
|
||||
// const CGObjectInstance * getArmyInstance(ObjectInstanceID oid) const;
|
||||
|
||||
//objects
|
||||
/// Returns pointer to town using provided object ID. Returns null on failure
|
||||
virtual const CGTownInstance* getTown(ObjectInstanceID objid) const = 0;
|
||||
/// Returns pointer to object using provided object ID. Returns null on failure
|
||||
virtual const CGObjectInstance * getObj(ObjectInstanceID objid, bool verbose = true) const = 0;
|
||||
// std::vector <const CGObjectInstance * > getBlockingObjs(int3 pos) const;
|
||||
virtual std::vector<const CGObjectInstance *> getVisitableObjs(int3 pos, bool verbose = true) const = 0;
|
||||
// std::vector <const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
|
||||
// const CGObjectInstance * getTopObj (int3 pos) const;
|
||||
// PlayerColor getOwner(ObjectInstanceID heroID) const;
|
||||
/// Returns pointer to object using provided object ID. Returns null on failure
|
||||
virtual const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const = 0;
|
||||
/// Returns pointer to artifact using provided object ID. Returns null on failure
|
||||
virtual const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const = 0;
|
||||
|
||||
//map
|
||||
// int3 guardingCreaturePosition (int3 pos) const;
|
||||
// std::vector<const CGObjectInstance*> getGuardingCreatures (int3 pos) const;
|
||||
// const CMapHeader * getMapHeader()const;
|
||||
// int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||
// const TerrainTile * getTile(int3 tile, bool verbose = true) const;
|
||||
// bool isInTheMap(const int3 &pos) const;
|
||||
/// Returns pointer to specified tile or nullptr on error
|
||||
virtual const TerrainTile * getTile(int3 tile, bool verbose = true) const = 0;
|
||||
/// Returns pointer to specified tile without checking for permissions. Avoid its usage!
|
||||
virtual const TerrainTile * getTileUnchecked(int3 tile) const = 0;
|
||||
/// Returns pointer to top-most object on specified tile, or nullptr on error
|
||||
virtual const CGObjectInstance * getTopObj(int3 pos) const = 0;
|
||||
/// Returns whether it is possible to dig for Grail on specified tile
|
||||
virtual EDiggingStatus getTileDigStatus(int3 tile, bool verbose = true) const = 0;
|
||||
/// Calculates pathfinding data into specified pathfinder config
|
||||
virtual void calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const = 0;
|
||||
|
||||
//town
|
||||
// const CGTownInstance* getTown(ObjectInstanceID objid) const;
|
||||
// int howManyTowns(PlayerColor Player) const;
|
||||
// const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
|
||||
// std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
|
||||
// std::string getTavernRumor(const CGObjectInstance * townOrTavern) const;
|
||||
// EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||
// virtual bool getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||
/// Returns all tiles within specified range with specific tile visibility mode
|
||||
virtual void getTilesInRange(std::unordered_set<int3> & tiles, const int3 & pos, int radius, ETileVisibility mode, std::optional<PlayerColor> player = std::optional<PlayerColor>(), int3::EDistanceFormula formula = int3::DIST_2D) const = 0;
|
||||
|
||||
//from gs
|
||||
// const TeamState *getTeam(TeamID teamID) const;
|
||||
// const TeamState *getPlayerTeam(PlayerColor color) const;
|
||||
// EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||
/// returns all tiles on given level (-1 - both levels, otherwise number of level)
|
||||
virtual void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const = 0;
|
||||
|
||||
//teleport
|
||||
// std::vector<ObjectInstanceID> getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player) const;
|
||||
// std::vector<ObjectInstanceID> getTeleportChannelEntrances(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
|
||||
// std::vector<ObjectInstanceID> getTeleportChannelExits(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const;
|
||||
// ETeleportChannelType getTeleportChannelType(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
// bool isTeleportChannelImpassable(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
// bool isTeleportChannelBidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
// bool isTeleportChannelUnidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const;
|
||||
// bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const;
|
||||
virtual std::vector<ObjectInstanceID> getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player) const = 0;
|
||||
virtual std::vector<ObjectInstanceID> getTeleportChannelEntrances(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const = 0;
|
||||
virtual std::vector<ObjectInstanceID> getTeleportChannelExits(TeleportChannelID id, PlayerColor Player = PlayerColor::UNFLAGGABLE) const = 0;
|
||||
virtual bool isTeleportChannelImpassable(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const = 0;
|
||||
virtual bool isTeleportChannelBidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const = 0;
|
||||
virtual bool isTeleportChannelUnidirectional(TeleportChannelID id, PlayerColor player = PlayerColor::UNFLAGGABLE) const = 0;
|
||||
virtual bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const = 0;
|
||||
|
||||
/// gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||
/// TODO: remove non-const method from this interface
|
||||
virtual void pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand) = 0;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
virtual scripting::Pool * getGlobalContextPool() const = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -420,7 +420,7 @@ std::optional<ui8> CampaignState::getBonusID(CampaignScenarioID which) const
|
||||
return chosenCampaignBonuses.at(which);
|
||||
}
|
||||
|
||||
std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId, IGameCallback * cb)
|
||||
std::unique_ptr<CMap> CampaignState::getMap(CampaignScenarioID scenarioId, IGameInfoCallback * cb)
|
||||
{
|
||||
// FIXME: there is certainly better way to handle maps inside campaigns
|
||||
if(scenarioId == CampaignScenarioID::NONE)
|
||||
|
@@ -28,7 +28,7 @@ class CMap;
|
||||
class CMapHeader;
|
||||
class CMapInfo;
|
||||
class JsonNode;
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
|
||||
class DLL_LINKAGE CampaignRegions
|
||||
{
|
||||
@@ -338,7 +338,7 @@ public:
|
||||
/// Returns true if all available scenarios have been completed and campaign is finished
|
||||
bool isCampaignFinished() const;
|
||||
|
||||
std::unique_ptr<CMap> getMap(CampaignScenarioID scenarioId, IGameCallback * cb);
|
||||
std::unique_ptr<CMap> getMap(CampaignScenarioID scenarioId, IGameInfoCallback * cb);
|
||||
std::unique_ptr<CMapHeader> getMapHeader(CampaignScenarioID scenarioId) const;
|
||||
std::shared_ptr<CMapInfo> getMapInfo(CampaignScenarioID scenarioId) const;
|
||||
|
||||
|
@@ -43,7 +43,7 @@ class CCreature;
|
||||
class CHero;
|
||||
class CSpell;
|
||||
class CSkill;
|
||||
class CGameInfoCallback;
|
||||
class IGameInfoCallback;
|
||||
class CNonConstInfoCallback;
|
||||
|
||||
class ArtifactInstanceID : public StaticIdentifier<ArtifactInstanceID>
|
||||
|
@@ -11,11 +11,11 @@
|
||||
#include "StdInc.h"
|
||||
#include "ArtSlotInfo.h"
|
||||
|
||||
#include "../../callback/IGameCallback.h"
|
||||
#include "../../callback/IGameInfoCallback.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
ArtSlotInfo::ArtSlotInfo(IGameCallback * cb)
|
||||
ArtSlotInfo::ArtSlotInfo(IGameInfoCallback * cb)
|
||||
: GameCallbackHolder(cb)
|
||||
{
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ struct DLL_LINKAGE ArtSlotInfo : public GameCallbackHolder
|
||||
ArtifactInstanceID artifactID;
|
||||
bool locked = false; //if locked, then artifact points to the combined artifact
|
||||
|
||||
explicit ArtSlotInfo(IGameCallback * cb);
|
||||
explicit ArtSlotInfo(IGameInfoCallback * cb);
|
||||
ArtSlotInfo(const CArtifactInstance * artifact, bool locked);
|
||||
|
||||
const CArtifactInstance * getArt() const;
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
CArtifactFittingSet::CArtifactFittingSet(IGameCallback *cb, ArtBearer bearer)
|
||||
CArtifactFittingSet::CArtifactFittingSet(IGameInfoCallback *cb, ArtBearer bearer)
|
||||
: CArtifactSet(cb)
|
||||
, GameCallbackHolder(cb)
|
||||
, bearer(bearer)
|
||||
|
@@ -18,13 +18,13 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
// Used to try on artifacts before the claimed changes have been applied
|
||||
class DLL_LINKAGE CArtifactFittingSet : public CArtifactSet, public GameCallbackHolder
|
||||
{
|
||||
IGameCallback * getCallback() const final
|
||||
IGameInfoCallback * getCallback() const final
|
||||
{
|
||||
return cb;
|
||||
}
|
||||
|
||||
public:
|
||||
CArtifactFittingSet(IGameCallback * cb, ArtBearer Bearer);
|
||||
CArtifactFittingSet(IGameInfoCallback * cb, ArtBearer Bearer);
|
||||
explicit CArtifactFittingSet(const CArtifactSet & artSet);
|
||||
ArtBearer bearerType() const override;
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include "CArtifact.h"
|
||||
#include "CArtifactSet.h"
|
||||
|
||||
#include "../../callback/IGameCallback.h"
|
||||
#include "../../callback/IGameInfoCallback.h"
|
||||
#include "../../gameState/CGameState.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@@ -125,13 +125,13 @@ void CGrowingArtifactInstance::growingUp()
|
||||
}
|
||||
}
|
||||
|
||||
CArtifactInstance::CArtifactInstance(IGameCallback *cb, const CArtifact * art)
|
||||
CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb, const CArtifact * art)
|
||||
:CArtifactInstance(cb)
|
||||
{
|
||||
setType(art);
|
||||
}
|
||||
|
||||
CArtifactInstance::CArtifactInstance(IGameCallback *cb)
|
||||
CArtifactInstance::CArtifactInstance(IGameInfoCallback *cb)
|
||||
: CBonusSystemNode(ARTIFACT_INSTANCE)
|
||||
, CCombinedArtifactInstance(cb)
|
||||
{
|
||||
|
@@ -82,8 +82,8 @@ class DLL_LINKAGE CArtifactInstance final
|
||||
ArtifactID artTypeID;
|
||||
|
||||
public:
|
||||
CArtifactInstance(IGameCallback *cb, const CArtifact * art);
|
||||
CArtifactInstance(IGameCallback *cb);
|
||||
CArtifactInstance(IGameInfoCallback *cb, const CArtifact * art);
|
||||
CArtifactInstance(IGameInfoCallback *cb);
|
||||
void setType(const CArtifact * art);
|
||||
std::string nodeName() const override;
|
||||
ArtifactID getTypeId() const;
|
||||
|
@@ -184,7 +184,7 @@ CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition &
|
||||
return resArtPlacement;
|
||||
}
|
||||
|
||||
CArtifactSet::CArtifactSet(IGameCallback * cb)
|
||||
CArtifactSet::CArtifactSet(IGameInfoCallback * cb)
|
||||
:artifactsTransitionPos(cb)
|
||||
{}
|
||||
|
||||
|
@@ -40,11 +40,11 @@ public:
|
||||
bool hasScroll(const SpellID & aid, bool onlyWorn = false) const;
|
||||
bool isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck = false) const;
|
||||
|
||||
virtual IGameCallback * getCallback() const = 0;
|
||||
virtual IGameInfoCallback * getCallback() const = 0;
|
||||
virtual ArtBearer bearerType() const = 0;
|
||||
virtual ArtPlacementMap putArtifact(const ArtifactPosition & slot, const CArtifactInstance * art);
|
||||
virtual void removeArtifact(const ArtifactPosition & slot);
|
||||
CArtifactSet(IGameCallback * cb);
|
||||
CArtifactSet(IGameInfoCallback * cb);
|
||||
virtual ~CArtifactSet() = default;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#include "../bonuses/Propagators.h"
|
||||
#include "../bonuses/Updaters.h"
|
||||
#include "../battle/BattleInfo.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../campaign/CampaignState.h"
|
||||
#include "../constants/StringConstants.h"
|
||||
#include "../entities/artifact/ArtifactUtils.h"
|
||||
@@ -71,7 +71,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
std::shared_mutex CGameState::mutex;
|
||||
|
||||
HeroTypeID CGameState::pickNextHeroType(const PlayerColor & owner)
|
||||
HeroTypeID CGameState::pickNextHeroType(vstd::RNG & randomGenerator, const PlayerColor & owner)
|
||||
{
|
||||
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
||||
if(ps.hero.isValid() && !isUsedHero(HeroTypeID(ps.hero))) //we haven't used selected hero
|
||||
@@ -79,10 +79,10 @@ HeroTypeID CGameState::pickNextHeroType(const PlayerColor & owner)
|
||||
return HeroTypeID(ps.hero);
|
||||
}
|
||||
|
||||
return pickUnusedHeroTypeRandomly(owner);
|
||||
return pickUnusedHeroTypeRandomly(randomGenerator, owner);
|
||||
}
|
||||
|
||||
HeroTypeID CGameState::pickUnusedHeroTypeRandomly(const PlayerColor & owner)
|
||||
HeroTypeID CGameState::pickUnusedHeroTypeRandomly(vstd::RNG & randomGenerator, const PlayerColor & owner)
|
||||
{
|
||||
//list of available heroes for this faction and others
|
||||
std::vector<HeroTypeID> factionHeroes;
|
||||
@@ -100,13 +100,13 @@ HeroTypeID CGameState::pickUnusedHeroTypeRandomly(const PlayerColor & owner)
|
||||
// select random hero native to "our" faction
|
||||
if(!factionHeroes.empty())
|
||||
{
|
||||
return *RandomGeneratorUtil::nextItem(factionHeroes, getRandomGenerator());
|
||||
return *RandomGeneratorUtil::nextItem(factionHeroes, randomGenerator);
|
||||
}
|
||||
|
||||
logGlobal->warn("Cannot find free hero of appropriate faction for player %s - trying to get first available...", owner.toString());
|
||||
if(!otherHeroes.empty())
|
||||
{
|
||||
return *RandomGeneratorUtil::nextItem(otherHeroes, getRandomGenerator());
|
||||
return *RandomGeneratorUtil::nextItem(otherHeroes, randomGenerator);
|
||||
}
|
||||
|
||||
logGlobal->error("No free allowed heroes!");
|
||||
@@ -150,7 +150,7 @@ int CGameState::getDate(Date mode) const
|
||||
return getDate(day, mode);
|
||||
}
|
||||
|
||||
CGameState::CGameState(IGameCallback * callback)
|
||||
CGameState::CGameState(IGameInfoCallback * callback)
|
||||
: GameCallbackHolder(callback)
|
||||
{
|
||||
heroesPool = std::make_unique<TavernHeroesPool>(this);
|
||||
@@ -173,7 +173,7 @@ void CGameState::preInit(Services * newServices)
|
||||
services = newServices;
|
||||
}
|
||||
|
||||
void CGameState::init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator & progressTracking, bool allowSavingRandomMap)
|
||||
void CGameState::init(const IMapService * mapService, StartInfo * si, vstd::RNG & randomGenerator, Load::ProgressAccumulator & progressTracking, bool allowSavingRandomMap)
|
||||
{
|
||||
assert(services);
|
||||
assert(cb);
|
||||
@@ -184,7 +184,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
|
||||
switch(scenarioOps->mode)
|
||||
{
|
||||
case EStartMode::NEW_GAME:
|
||||
initNewGame(mapService, allowSavingRandomMap, progressTracking);
|
||||
initNewGame(mapService, randomGenerator, allowSavingRandomMap, progressTracking);
|
||||
break;
|
||||
case EStartMode::CAMPAIGN:
|
||||
initCampaign();
|
||||
@@ -202,20 +202,20 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
|
||||
initGlobalBonuses();
|
||||
initPlayerStates();
|
||||
if (campaign)
|
||||
campaign->placeCampaignHeroes();
|
||||
campaign->placeCampaignHeroes(randomGenerator);
|
||||
removeHeroPlaceholders();
|
||||
initGrailPosition();
|
||||
initRandomFactionsForPlayers();
|
||||
randomizeMapObjects();
|
||||
placeStartingHeroes();
|
||||
initGrailPosition(randomGenerator);
|
||||
initRandomFactionsForPlayers(randomGenerator);
|
||||
randomizeMapObjects(randomGenerator);
|
||||
placeStartingHeroes(randomGenerator);
|
||||
initOwnedObjects();
|
||||
initDifficulty();
|
||||
initHeroes();
|
||||
initStartingBonus();
|
||||
initTowns();
|
||||
initTownNames();
|
||||
initHeroes(randomGenerator);
|
||||
initStartingBonus(randomGenerator);
|
||||
initTowns(randomGenerator);
|
||||
initTownNames(randomGenerator);
|
||||
placeHeroesInTowns();
|
||||
initMapObjects();
|
||||
initMapObjects(randomGenerator);
|
||||
buildBonusSystemTree();
|
||||
initVisitingAndGarrisonedHeroes();
|
||||
initFogOfWar();
|
||||
@@ -291,7 +291,7 @@ void CGameState::updateOnLoad(StartInfo * si)
|
||||
scenarioOps->simturnsInfo = si->simturnsInfo;
|
||||
}
|
||||
|
||||
void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking)
|
||||
void CGameState::initNewGame(const IMapService * mapService, vstd::RNG & randomGenerator, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking)
|
||||
{
|
||||
if(scenarioOps->createRandomMap())
|
||||
{
|
||||
@@ -299,7 +299,7 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
|
||||
CStopWatch sw;
|
||||
|
||||
// Gen map
|
||||
CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, cb, getRandomGenerator().nextInt());
|
||||
CMapGenerator mapGenerator(*scenarioOps->mapGenOptions, cb, randomGenerator.nextInt());
|
||||
progressTracking.include(mapGenerator);
|
||||
|
||||
map = mapGenerator.generate();
|
||||
@@ -425,7 +425,7 @@ void CGameState::initDifficulty()
|
||||
campaign->initStartingResources();
|
||||
}
|
||||
|
||||
void CGameState::initGrailPosition()
|
||||
void CGameState::initGrailPosition(vstd::RNG & randomGenerator)
|
||||
{
|
||||
logGlobal->debug("\tPicking grail position");
|
||||
//pick grail location
|
||||
@@ -463,7 +463,7 @@ void CGameState::initGrailPosition()
|
||||
|
||||
if(!allowedPos.empty())
|
||||
{
|
||||
map->grailPos = *RandomGeneratorUtil::nextItem(allowedPos, getRandomGenerator());
|
||||
map->grailPos = *RandomGeneratorUtil::nextItem(allowedPos, randomGenerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -472,14 +472,14 @@ void CGameState::initGrailPosition()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initRandomFactionsForPlayers()
|
||||
void CGameState::initRandomFactionsForPlayers(vstd::RNG & randomGenerator)
|
||||
{
|
||||
logGlobal->debug("\tPicking random factions for players");
|
||||
for(auto & elem : scenarioOps->playerInfos)
|
||||
{
|
||||
if(elem.second.castle==FactionID::RANDOM)
|
||||
{
|
||||
auto randomID = getRandomGenerator().nextInt((int)map->players[elem.first.getNum()].allowedFactions.size() - 1);
|
||||
auto randomID = randomGenerator.nextInt((int)map->players[elem.first.getNum()].allowedFactions.size() - 1);
|
||||
auto iter = map->players[elem.first.getNum()].allowedFactions.begin();
|
||||
std::advance(iter, randomID);
|
||||
|
||||
@@ -488,12 +488,12 @@ void CGameState::initRandomFactionsForPlayers()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::randomizeMapObjects()
|
||||
void CGameState::randomizeMapObjects(vstd::RNG & randomGenerator)
|
||||
{
|
||||
logGlobal->debug("\tRandomizing objects");
|
||||
for(const auto & object : map->getObjects())
|
||||
{
|
||||
object->pickRandomObject(getRandomGenerator());
|
||||
object->pickRandomObject(randomGenerator);
|
||||
|
||||
//handle Favouring Winds - mark tiles under it
|
||||
if(object->ID == Obj::FAVORABLE_WINDS)
|
||||
@@ -562,7 +562,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
|
||||
map->getEditManager()->insertObject(hero);
|
||||
}
|
||||
|
||||
void CGameState::placeStartingHeroes()
|
||||
void CGameState::placeStartingHeroes(vstd::RNG & randomGenerator)
|
||||
{
|
||||
logGlobal->debug("\tGiving starting hero");
|
||||
|
||||
@@ -576,7 +576,7 @@ void CGameState::placeStartingHeroes()
|
||||
if (campaign && campaign->playerHasStartingHero(playerColor))
|
||||
continue;
|
||||
|
||||
HeroTypeID heroTypeId = pickNextHeroType(playerColor);
|
||||
HeroTypeID heroTypeId = pickNextHeroType(randomGenerator, playerColor);
|
||||
if(playerSettingPair.second.hero == HeroTypeID::NONE || playerSettingPair.second.hero == HeroTypeID::RANDOM)
|
||||
playerSettingPair.second.hero = heroTypeId;
|
||||
|
||||
@@ -594,7 +594,7 @@ void CGameState::removeHeroPlaceholders()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initHeroes()
|
||||
void CGameState::initHeroes(vstd::RNG & randomGenerator)
|
||||
{
|
||||
//heroes instances initialization
|
||||
for (auto heroID : map->getHeroesOnMap())
|
||||
@@ -605,7 +605,7 @@ void CGameState::initHeroes()
|
||||
logGlobal->warn("Hero with uninitialized owner!");
|
||||
continue;
|
||||
}
|
||||
hero->initHero(getRandomGenerator());
|
||||
hero->initHero(randomGenerator);
|
||||
}
|
||||
|
||||
// generate boats for all heroes on water
|
||||
@@ -622,7 +622,7 @@ void CGameState::initHeroes()
|
||||
{
|
||||
auto handler = LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, hero->getBoatType().getNum());
|
||||
auto boat = std::dynamic_pointer_cast<CGBoat>(handler->create(cb, nullptr));
|
||||
handler->configureObject(boat.get(), getRandomGenerator());
|
||||
handler->configureObject(boat.get(), randomGenerator);
|
||||
|
||||
boat->setAnchorPos(hero->anchorPos());
|
||||
boat->appearance = handler->getTemplates().front();
|
||||
@@ -648,7 +648,7 @@ void CGameState::initHeroes()
|
||||
heroInPool = newHeroPtr.get();
|
||||
}
|
||||
map->generateUniqueInstanceName(heroInPool);
|
||||
heroInPool->initHero(getRandomGenerator());
|
||||
heroInPool->initHero(randomGenerator);
|
||||
heroesPool->addHeroToPool(htype);
|
||||
}
|
||||
|
||||
@@ -685,7 +685,7 @@ void CGameState::initFogOfWar()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initStartingBonus()
|
||||
void CGameState::initStartingBonus(vstd::RNG & randomGenerator)
|
||||
{
|
||||
if (scenarioOps->mode == EStartMode::CAMPAIGN)
|
||||
return;
|
||||
@@ -697,25 +697,25 @@ void CGameState::initStartingBonus()
|
||||
{
|
||||
//starting bonus
|
||||
if(scenarioOps->playerInfos[elem.first].bonus == PlayerStartingBonus::RANDOM)
|
||||
scenarioOps->playerInfos[elem.first].bonus = static_cast<PlayerStartingBonus>(getRandomGenerator().nextInt(2));
|
||||
scenarioOps->playerInfos[elem.first].bonus = static_cast<PlayerStartingBonus>(randomGenerator.nextInt(2));
|
||||
|
||||
switch(scenarioOps->playerInfos[elem.first].bonus)
|
||||
{
|
||||
case PlayerStartingBonus::GOLD:
|
||||
elem.second.resources[EGameResID::GOLD] += getRandomGenerator().nextInt(5, 10) * 100;
|
||||
elem.second.resources[EGameResID::GOLD] += randomGenerator.nextInt(5, 10) * 100;
|
||||
break;
|
||||
case PlayerStartingBonus::RESOURCE:
|
||||
{
|
||||
auto res = (*LIBRARY->townh)[scenarioOps->playerInfos[elem.first].castle]->town->primaryRes;
|
||||
if(res == EGameResID::WOOD_AND_ORE)
|
||||
{
|
||||
int amount = getRandomGenerator().nextInt(5, 10);
|
||||
int amount = randomGenerator.nextInt(5, 10);
|
||||
elem.second.resources[EGameResID::WOOD] += amount;
|
||||
elem.second.resources[EGameResID::ORE] += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
elem.second.resources[res] += getRandomGenerator().nextInt(3, 6);
|
||||
elem.second.resources[res] += randomGenerator.nextInt(3, 6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -726,7 +726,7 @@ void CGameState::initStartingBonus()
|
||||
logGlobal->error("Cannot give starting artifact - no heroes!");
|
||||
break;
|
||||
}
|
||||
const Artifact * toGive = pickRandomArtifact(getRandomGenerator(), EArtifactClass::ART_TREASURE).toEntity(LIBRARY);
|
||||
const Artifact * toGive = pickRandomArtifact(randomGenerator, EArtifactClass::ART_TREASURE).toEntity(LIBRARY);
|
||||
|
||||
CGHeroInstance *hero = elem.second.getHeroes()[0];
|
||||
if(!giveHeroArtifact(hero, toGive->getId()))
|
||||
@@ -737,7 +737,7 @@ void CGameState::initStartingBonus()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initTownNames()
|
||||
void CGameState::initTownNames(vstd::RNG & randomGenerator)
|
||||
{
|
||||
std::map<FactionID, std::vector<int>> availableNames;
|
||||
for(const auto & faction : LIBRARY->townh->getDefaultAllowed())
|
||||
@@ -770,9 +770,9 @@ void CGameState::initTownNames()
|
||||
|
||||
// If town has no available names (for example - all were picked) - pick names from some other faction that still has names available
|
||||
if(!availableNames.count(faction))
|
||||
faction = RandomGeneratorUtil::nextItem(availableNames, getRandomGenerator())->first;
|
||||
faction = RandomGeneratorUtil::nextItem(availableNames, randomGenerator)->first;
|
||||
|
||||
auto nameIt = RandomGeneratorUtil::nextItem(availableNames[faction], getRandomGenerator());
|
||||
auto nameIt = RandomGeneratorUtil::nextItem(availableNames[faction], randomGenerator);
|
||||
vti->setNameTextId(faction.toFaction()->town->getRandomNameTextID(*nameIt));
|
||||
|
||||
availableNames[faction].erase(nameIt);
|
||||
@@ -781,7 +781,7 @@ void CGameState::initTownNames()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initTowns()
|
||||
void CGameState::initTowns(vstd::RNG & randomGenerator)
|
||||
{
|
||||
logGlobal->debug("\tTowns");
|
||||
|
||||
@@ -816,7 +816,7 @@ void CGameState::initTowns()
|
||||
|
||||
for(int i = 0; i < definesBuildingsChances.size(); i++)
|
||||
{
|
||||
if((getRandomGenerator().nextInt(1,100) <= definesBuildingsChances[i]))
|
||||
if((randomGenerator.nextInt(1,100) <= definesBuildingsChances[i]))
|
||||
{
|
||||
vti->addBuilding(basicDwellings[i]);
|
||||
}
|
||||
@@ -912,7 +912,7 @@ void CGameState::initTowns()
|
||||
|
||||
while(!vti->possibleSpells.empty())
|
||||
{
|
||||
size_t index = RandomGeneratorUtil::nextItemWeighted(spellWeights, getRandomGenerator());
|
||||
size_t index = RandomGeneratorUtil::nextItemWeighted(spellWeights, randomGenerator);
|
||||
|
||||
const auto * s = vti->possibleSpells[index].toSpell();
|
||||
vti->spells[s->getLevel()-1].push_back(s->id);
|
||||
@@ -923,12 +923,12 @@ void CGameState::initTowns()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initMapObjects()
|
||||
void CGameState::initMapObjects(vstd::RNG & randomGenerator)
|
||||
{
|
||||
logGlobal->debug("\tObject initialization");
|
||||
|
||||
for(auto & obj : map->getObjects())
|
||||
obj->initObj(getRandomGenerator());
|
||||
obj->initObj(randomGenerator);
|
||||
|
||||
logGlobal->debug("\tObject initialization done");
|
||||
for(auto & q : map->getObjects<CGSeerHut>())
|
||||
@@ -1029,7 +1029,7 @@ BattleInfo * CGameState::getBattle(const BattleID & battle)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand)
|
||||
BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & randomGenerator)
|
||||
{
|
||||
assert(tile.isValid());
|
||||
|
||||
@@ -1063,49 +1063,10 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand)
|
||||
if (t.getTerrain()->battleFields.empty())
|
||||
throw std::runtime_error("Failed to find battlefield for terrain " + t.getTerrain()->getJsonKey());
|
||||
|
||||
return BattleField(*RandomGeneratorUtil::nextItem(t.getTerrain()->battleFields, rand));
|
||||
return BattleField(*RandomGeneratorUtil::nextItem(t.getTerrain()->battleFields, randomGenerator));
|
||||
}
|
||||
|
||||
void CGameState::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const
|
||||
{
|
||||
assert(obj);
|
||||
assert(obj->hasStackAtSlot(stackPos));
|
||||
|
||||
out = fillUpgradeInfo(obj->getStack(stackPos));
|
||||
}
|
||||
|
||||
UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance & stack) const
|
||||
{
|
||||
const CCreature *base = stack.getCreature();
|
||||
|
||||
UpgradeInfo ret(base->getId());
|
||||
|
||||
if (stack.getArmy()->ID == Obj::HERO)
|
||||
{
|
||||
auto hero = dynamic_cast<const CGHeroInstance *>(stack.getArmy());
|
||||
hero->fillUpgradeInfo(ret, stack);
|
||||
|
||||
if (hero->getVisitedTown())
|
||||
{
|
||||
hero->getVisitedTown()->fillUpgradeInfo(ret, stack);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto object = vstd::frontOrNull(getVisitableObjs(hero->visitablePos()));
|
||||
auto upgradeSource = dynamic_cast<const ICreatureUpgrader*>(object);
|
||||
if (object != hero && upgradeSource != nullptr)
|
||||
upgradeSource->fillUpgradeInfo(ret, stack);
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.getArmy()->ID == Obj::TOWN)
|
||||
{
|
||||
auto town = dynamic_cast<const CGTownInstance *>(stack.getArmy());
|
||||
town->fillUpgradeInfo(ret, stack);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PlayerRelations CGameState::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const
|
||||
{
|
||||
@@ -1187,29 +1148,21 @@ std::vector<const CGObjectInstance*> CGameState::guardingCreatures (int3 pos) co
|
||||
pos.x++;
|
||||
}
|
||||
return guards;
|
||||
|
||||
}
|
||||
|
||||
int3 CGameState::guardingCreaturePosition (int3 pos) const
|
||||
{
|
||||
return getMap().guardingCreaturePositions[pos.z][pos.x][pos.y];
|
||||
}
|
||||
|
||||
bool CGameState::isVisible(int3 pos, const std::optional<PlayerColor> & player) const
|
||||
bool CGameState::isVisibleFor(int3 pos, PlayerColor player) const
|
||||
{
|
||||
if (!map->isInTheMap(pos))
|
||||
return false;
|
||||
if (!player)
|
||||
return true;
|
||||
if(player == PlayerColor::NEUTRAL)
|
||||
return false;
|
||||
if(player->isSpectator())
|
||||
if(player.isSpectator())
|
||||
return true;
|
||||
|
||||
return getPlayerTeam(*player)->fogOfWarMap[pos.z][pos.x][pos.y];
|
||||
return getPlayerTeam(player)->fogOfWarMap[pos.z][pos.x][pos.y];
|
||||
}
|
||||
|
||||
bool CGameState::isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & player) const
|
||||
bool CGameState::isVisibleFor(const CGObjectInstance * obj, PlayerColor player) const
|
||||
{
|
||||
if(!player)
|
||||
return true;
|
||||
@@ -1218,8 +1171,9 @@ bool CGameState::isVisible(const CGObjectInstance * obj, const std::optional<Pla
|
||||
if (player == obj->tempOwner)
|
||||
return true;
|
||||
|
||||
if(*player == PlayerColor::NEUTRAL) //-> TODO ??? needed?
|
||||
if(player == PlayerColor::NEUTRAL) //-> TODO ??? needed?
|
||||
return false;
|
||||
|
||||
//object is visible when at least one blocked tile is visible
|
||||
for(int fy=0; fy < obj->getHeight(); ++fy)
|
||||
{
|
||||
@@ -1229,7 +1183,7 @@ bool CGameState::isVisible(const CGObjectInstance * obj, const std::optional<Pla
|
||||
|
||||
if ( map->isInTheMap(pos) &&
|
||||
obj->coveringAt(pos) &&
|
||||
isVisible(pos, *player))
|
||||
isVisibleFor(pos, player))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1353,7 +1307,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
|
||||
case EventCondition::CONTROL:
|
||||
{
|
||||
// list of players that need to control object to fulfull condition
|
||||
// NOTE: cgameinfocallback specified explicitly in order to get const version
|
||||
// NOTE: CGameInfoCallback specified explicitly in order to get const version
|
||||
const auto * team = CGameInfoCallback::getPlayerTeam(player);
|
||||
|
||||
if (condition.objectID != ObjectInstanceID::NONE) // mode A - flag one specific object, like town
|
||||
@@ -1571,7 +1525,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
|
||||
void CGameState::buildBonusSystemTree()
|
||||
{
|
||||
buildGlobalTeamPlayerTree();
|
||||
for(auto & armed : map->getObjects<CArmedInstance>())
|
||||
for(auto & armed : map->getObjects<CGObjectInstance>())
|
||||
armed->attachToBonusSystem(*this);
|
||||
}
|
||||
|
||||
@@ -1580,7 +1534,7 @@ void CGameState::restoreBonusSystemTree()
|
||||
heroesPool->setGameState(this);
|
||||
|
||||
buildGlobalTeamPlayerTree();
|
||||
for(auto & armed : map->getObjects<CArmedInstance>())
|
||||
for(auto & armed : map->getObjects<CGObjectInstance>())
|
||||
armed->restoreBonusSystem(*this);
|
||||
|
||||
for(auto & art : map->getArtifacts())
|
||||
@@ -1656,19 +1610,12 @@ CGHeroInstance * CGameState::getUsedHero(const HeroTypeID & hid) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TeamState::TeamState()
|
||||
{
|
||||
setNodeType(TEAM);
|
||||
}
|
||||
|
||||
vstd::RNG & CGameState::getRandomGenerator()
|
||||
{
|
||||
return cb->getRandomGenerator();
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::optional<EArtifactClass> type, std::function<bool(ArtifactID)> accepts)
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & randomGenerator, std::optional<EArtifactClass> type, std::function<bool(ArtifactID)> accepts)
|
||||
{
|
||||
std::set<ArtifactID> potentialPicks;
|
||||
|
||||
@@ -1691,10 +1638,10 @@ ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::optional<EArtif
|
||||
potentialPicks.insert(artifact->getId());
|
||||
}
|
||||
|
||||
return pickRandomArtifact(rand, potentialPicks);
|
||||
return pickRandomArtifact(randomGenerator, potentialPicks);
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID> potentialPicks)
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & randomGenerator, std::set<ArtifactID> potentialPicks)
|
||||
{
|
||||
// No allowed artifacts at all - give Grail - this can't be banned (hopefully)
|
||||
// FIXME: investigate how such cases are handled by H3 - some heavily customized user-made maps likely rely on H3 behavior
|
||||
@@ -1718,19 +1665,19 @@ ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID>
|
||||
|
||||
assert(!preferredPicks.empty());
|
||||
|
||||
ArtifactID artID = *RandomGeneratorUtil::nextItem(preferredPicks, rand);
|
||||
ArtifactID artID = *RandomGeneratorUtil::nextItem(preferredPicks, randomGenerator);
|
||||
allocatedArtifacts[artID] += 1; // record +1 more usage
|
||||
return artID;
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::function<bool(ArtifactID)> accepts)
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & randomGenerator, std::function<bool(ArtifactID)> accepts)
|
||||
{
|
||||
return pickRandomArtifact(rand, std::nullopt, std::move(accepts));
|
||||
return pickRandomArtifact(randomGenerator, std::nullopt, std::move(accepts));
|
||||
}
|
||||
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, std::optional<EArtifactClass> type)
|
||||
ArtifactID CGameState::pickRandomArtifact(vstd::RNG & randomGenerator, std::optional<EArtifactClass> type)
|
||||
{
|
||||
return pickRandomArtifact(rand, type, [](const ArtifactID &) { return true; });
|
||||
return pickRandomArtifact(randomGenerator, type, [](const ArtifactID &) { return true; });
|
||||
}
|
||||
|
||||
CArtifactInstance * CGameState::createScroll(const SpellID & spellId)
|
||||
@@ -1782,6 +1729,13 @@ void CGameState::loadGame(CLoadFile & file)
|
||||
}
|
||||
}
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::Pool * CGameState::getGlobalContextPool() const
|
||||
{
|
||||
return nullptr; // TODO
|
||||
}
|
||||
#endif
|
||||
|
||||
void CGameState::saveCompatibilityRegisterMissingArtifacts()
|
||||
{
|
||||
for( const auto & newArtifact : saveCompatibilityUnregisteredArtifacts)
|
||||
|
@@ -68,7 +68,7 @@ public:
|
||||
/// list of players currently making turn. Usually - just one, except for simturns
|
||||
std::set<PlayerColor> actingPlayers;
|
||||
|
||||
CGameState(IGameCallback * callback);
|
||||
CGameState(IGameInfoCallback * callback);
|
||||
virtual ~CGameState();
|
||||
|
||||
CGameState & gameState() final { return *this; }
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
|
||||
void preInit(Services * services);
|
||||
|
||||
void init(const IMapService * mapService, StartInfo * si, Load::ProgressAccumulator &, bool allowSavingRandomMap = true);
|
||||
void init(const IMapService * mapService, StartInfo * si, vstd::RNG & randomGenerator, Load::ProgressAccumulator &, bool allowSavingRandomMap = true);
|
||||
void updateOnLoad(StartInfo * si);
|
||||
|
||||
ui32 day; //total number of days in game
|
||||
@@ -94,23 +94,21 @@ public:
|
||||
|
||||
bool giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid);
|
||||
/// picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
|
||||
HeroTypeID pickNextHeroType(const PlayerColor & owner);
|
||||
HeroTypeID pickNextHeroType(vstd::RNG & randomGenerator, const PlayerColor & owner);
|
||||
|
||||
void apply(CPackForClient & pack);
|
||||
BattleField battleGetBattlefieldType(int3 tile, vstd::RNG & rand);
|
||||
BattleField battleGetBattlefieldType(int3 tile, vstd::RNG & randomGenerator);
|
||||
|
||||
void fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const override;
|
||||
PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const override;
|
||||
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
|
||||
void calculatePaths(const std::shared_ptr<PathfinderConfig> & config) const override;
|
||||
int3 guardingCreaturePosition (int3 pos) const override;
|
||||
std::vector<const CGObjectInstance*> guardingCreatures (int3 pos) const;
|
||||
|
||||
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::optional<EArtifactClass> type);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::optional<EArtifactClass> type, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID> filtered);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & randomGenerator, std::optional<EArtifactClass> type);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & randomGenerator, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & randomGenerator, std::optional<EArtifactClass> type, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & randomGenerator, std::set<ArtifactID> filtered);
|
||||
|
||||
/// Creates instance of spell scroll artifact with provided spell
|
||||
CArtifactInstance * createScroll(const SpellID & spellId);
|
||||
@@ -135,7 +133,7 @@ public:
|
||||
bool checkForStandardLoss(const PlayerColor & player) const; //checks if given player lost the game
|
||||
|
||||
void obtainPlayersStats(SThievesGuildInfo & tgi, int level); //fills tgi with info about other players that is available at given level of thieves' guild
|
||||
const IGameSettings & getSettings() const;
|
||||
const IGameSettings & getSettings() const override;
|
||||
|
||||
StartInfo * getStartInfo()
|
||||
{
|
||||
@@ -145,7 +143,7 @@ public:
|
||||
{
|
||||
return scenarioOps.get();
|
||||
}
|
||||
const StartInfo * getInitialStartInfo() const final
|
||||
const StartInfo * getInitialStartInfo() const
|
||||
{
|
||||
return initialOpts.get();
|
||||
}
|
||||
@@ -159,22 +157,15 @@ public:
|
||||
return *map;
|
||||
}
|
||||
|
||||
bool isVisible(int3 pos, const std::optional<PlayerColor> & player) const override;
|
||||
bool isVisible(const CGObjectInstance * obj, const std::optional<PlayerColor> & player) const override;
|
||||
bool isVisibleFor(int3 pos, const PlayerColor player) const override;
|
||||
bool isVisibleFor(const CGObjectInstance * obj, const PlayerColor player) const override;
|
||||
|
||||
static int getDate(int day, Date mode);
|
||||
int getDate(Date mode=Date::DAY) const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
|
||||
// ----- getters, setters -----
|
||||
|
||||
/// This RNG should only be used inside GS or CPackForClient-derived applyGs
|
||||
/// If this doesn't work for your code that mean you need a new netpack
|
||||
///
|
||||
/// Client-side must use vstd::RNG::getDefault which is not serialized
|
||||
///
|
||||
/// CGameHandler have it's own getter for vstd::RNG::getDefault
|
||||
/// Any server-side code outside of GH must use vstd::RNG::getDefault
|
||||
vstd::RNG & getRandomGenerator();
|
||||
#if SCRIPTING_ENABLED
|
||||
scripting::Pool * getGlobalContextPool() const override;
|
||||
#endif
|
||||
|
||||
void saveGame(CSaveFile & file) const;
|
||||
void loadGame(CLoadFile & file);
|
||||
@@ -206,24 +197,24 @@ public:
|
||||
|
||||
private:
|
||||
// ----- initialization -----
|
||||
void initNewGame(const IMapService * mapService, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking);
|
||||
void initNewGame(const IMapService * mapService, vstd::RNG & randomGenerator, bool allowSavingRandomMap, Load::ProgressAccumulator & progressTracking);
|
||||
void initGlobalBonuses();
|
||||
void initGrailPosition();
|
||||
void initRandomFactionsForPlayers();
|
||||
void initGrailPosition(vstd::RNG & randomGenerator);
|
||||
void initRandomFactionsForPlayers(vstd::RNG & randomGenerator);
|
||||
void initOwnedObjects();
|
||||
void randomizeMapObjects();
|
||||
void randomizeMapObjects(vstd::RNG & randomGenerator);
|
||||
void initPlayerStates();
|
||||
void placeStartingHeroes();
|
||||
void placeStartingHeroes(vstd::RNG & randomGenerator);
|
||||
void placeStartingHero(const PlayerColor & playerColor, const HeroTypeID & heroTypeId, int3 townPos);
|
||||
void removeHeroPlaceholders();
|
||||
void initDifficulty();
|
||||
void initHeroes();
|
||||
void initHeroes(vstd::RNG & randomGenerator);
|
||||
void placeHeroesInTowns();
|
||||
void initFogOfWar();
|
||||
void initStartingBonus();
|
||||
void initTowns();
|
||||
void initTownNames();
|
||||
void initMapObjects();
|
||||
void initStartingBonus(vstd::RNG & randomGenerator);
|
||||
void initTowns(vstd::RNG & randomGenerator);
|
||||
void initTownNames(vstd::RNG & randomGenerator);
|
||||
void initMapObjects(vstd::RNG & randomGenerator);
|
||||
void initVisitingAndGarrisonedHeroes();
|
||||
void initCampaign();
|
||||
|
||||
@@ -238,8 +229,7 @@ private:
|
||||
CGHeroInstance * getUsedHero(const HeroTypeID & hid) const;
|
||||
bool isUsedHero(const HeroTypeID & hid) const; //looks in heroes and prisons
|
||||
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
||||
HeroTypeID pickUnusedHeroTypeRandomly(const PlayerColor & owner); // picks a unused hero type randomly
|
||||
UpgradeInfo fillUpgradeInfo(const CStackInstance &stack) const;
|
||||
HeroTypeID pickUnusedHeroTypeRandomly(vstd::RNG & randomGenerator, const PlayerColor & owner); // picks a unused hero type randomly
|
||||
|
||||
// ---- data -----
|
||||
Services * services;
|
||||
@@ -247,7 +237,7 @@ private:
|
||||
/// Pointer to campaign state manager. Nullptr for single scenarios
|
||||
std::unique_ptr<CGameStateCampaign> campaign;
|
||||
|
||||
friend class IGameCallback;
|
||||
friend class IGameInfoCallback;
|
||||
friend class CMapHandler;
|
||||
friend class CGameHandler;
|
||||
};
|
||||
|
@@ -72,7 +72,7 @@ std::optional<CampaignScenarioID> CGameStateCampaign::getHeroesSourceScenario()
|
||||
return campaignState->lastScenario();
|
||||
}
|
||||
|
||||
void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & travelOptions)
|
||||
void CGameStateCampaign::trimCrossoverHeroesParameters(vstd::RNG & randomGenerator, const CampaignTravel & travelOptions)
|
||||
{
|
||||
// TODO this logic (what should be kept) should be part of CScenarioTravel and be exposed via some clean set of methods
|
||||
if(!travelOptions.whatHeroKeeps.experience)
|
||||
@@ -80,7 +80,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
|
||||
//trimming experience
|
||||
for(auto & hero : campaignHeroReplacements)
|
||||
{
|
||||
hero.hero->initExp(gameState->getRandomGenerator());
|
||||
hero.hero->initExp(randomGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
|
||||
}
|
||||
}
|
||||
|
||||
void CGameStateCampaign::placeCampaignHeroes()
|
||||
void CGameStateCampaign::placeCampaignHeroes(vstd::RNG & randomGenerator)
|
||||
{
|
||||
// place bonus hero
|
||||
auto campaignState = gameState->scenarioOps->campState;
|
||||
@@ -224,7 +224,7 @@ void CGameStateCampaign::placeCampaignHeroes()
|
||||
HeroTypeID heroTypeId = HeroTypeID(campaignBonus->info2);
|
||||
if(heroTypeId == HeroTypeID::CAMP_RANDOM) // random bonus hero
|
||||
{
|
||||
heroTypeId = gameState->pickUnusedHeroTypeRandomly(playerColor);
|
||||
heroTypeId = gameState->pickUnusedHeroTypeRandomly(randomGenerator, playerColor);
|
||||
}
|
||||
|
||||
gameState->placeStartingHero(playerColor, HeroTypeID(heroTypeId), gameState->map->players[playerColor.getNum()].posOfMainTown);
|
||||
@@ -235,7 +235,7 @@ void CGameStateCampaign::placeCampaignHeroes()
|
||||
generateCampaignHeroesToReplace();
|
||||
|
||||
logGlobal->debug("\tPrepare crossover heroes");
|
||||
trimCrossoverHeroesParameters(campaignState->scenario(*campaignState->currentScenario()).travelOptions);
|
||||
trimCrossoverHeroesParameters(randomGenerator, campaignState->scenario(*campaignState->currentScenario()).travelOptions);
|
||||
|
||||
// remove same heroes on the map which will be added through crossover heroes
|
||||
// INFO: we will remove heroes because later it may be possible that the API doesn't allow having heroes
|
||||
@@ -275,14 +275,14 @@ void CGameStateCampaign::placeCampaignHeroes()
|
||||
HeroTypeID heroTypeId;
|
||||
if(hero->ID == Obj::HERO)
|
||||
{
|
||||
heroTypeId = gameState->pickUnusedHeroTypeRandomly(hero->tempOwner);
|
||||
heroTypeId = gameState->pickUnusedHeroTypeRandomly(randomGenerator, hero->tempOwner);
|
||||
}
|
||||
else if(hero->ID == Obj::PRISON)
|
||||
{
|
||||
auto unusedHeroTypeIds = gameState->getUnusedAllowedHeroes();
|
||||
if(!unusedHeroTypeIds.empty())
|
||||
{
|
||||
heroTypeId = (*RandomGeneratorUtil::nextItem(unusedHeroTypeIds, gameState->getRandomGenerator()));
|
||||
heroTypeId = (*RandomGeneratorUtil::nextItem(unusedHeroTypeIds, randomGenerator));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -21,6 +21,11 @@ class CGHeroInstance;
|
||||
class CGameState;
|
||||
class CMap;
|
||||
|
||||
namespace vstd
|
||||
{
|
||||
class RNG;
|
||||
}
|
||||
|
||||
struct CampaignHeroReplacement
|
||||
{
|
||||
CampaignHeroReplacement(std::shared_ptr<CGHeroInstance> hero, const ObjectInstanceID & heroPlaceholderId);
|
||||
@@ -46,7 +51,7 @@ class CGameStateCampaign : public Serializeable
|
||||
std::optional<CampaignBonus> currentBonus() const;
|
||||
|
||||
/// Trims hero parameters that should not transfer between scenarios according to travelOptions flags
|
||||
void trimCrossoverHeroesParameters(const CampaignTravel & travelOptions);
|
||||
void trimCrossoverHeroesParameters(vstd::RNG & randomGenerator, const CampaignTravel & travelOptions);
|
||||
|
||||
void replaceHeroesPlaceholders();
|
||||
void transferMissingArtifacts(const CampaignTravel & travelOptions);
|
||||
@@ -58,7 +63,7 @@ public:
|
||||
CGameStateCampaign(CGameState * owner);
|
||||
void setGamestate(CGameState * owner);
|
||||
|
||||
void placeCampaignHeroes();
|
||||
void placeCampaignHeroes(vstd::RNG & randomGenerator);
|
||||
void initStartingResources();
|
||||
void initHeroes();
|
||||
void initTowns();
|
||||
|
@@ -366,16 +366,8 @@ void GameStatePackVisitor::visitRemoveObject(RemoveObject & pack)
|
||||
gs.getPlayerState(pack.initiator)->destroyedObjects.insert(pack.objectID);
|
||||
|
||||
if(obj->getOwner().isValidPlayer())
|
||||
{
|
||||
gs.getPlayerState(obj->getOwner())->removeOwnedObject(obj); //object removed via map event or hero got beaten
|
||||
|
||||
FlaggableMapObject* flaggableObject = dynamic_cast<FlaggableMapObject*>(obj);
|
||||
if(flaggableObject)
|
||||
{
|
||||
flaggableObject->markAsDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
if(obj->ID == Obj::HERO) //remove beaten hero
|
||||
{
|
||||
auto beatenHero = dynamic_cast<CGHeroInstance*>(obj);
|
||||
@@ -1080,8 +1072,6 @@ void GameStatePackVisitor::visitSetObjectProperty(SetObjectProperty & pack)
|
||||
return;
|
||||
}
|
||||
|
||||
auto * cai = dynamic_cast<CArmedInstance *>(obj);
|
||||
|
||||
if(pack.what == ObjProperty::OWNER && obj->asOwnable())
|
||||
{
|
||||
PlayerColor oldOwner = obj->getOwner();
|
||||
@@ -1093,7 +1083,7 @@ void GameStatePackVisitor::visitSetObjectProperty(SetObjectProperty & pack)
|
||||
gs.getPlayerState(newOwner)->addOwnedObject(obj);
|
||||
}
|
||||
|
||||
if(pack.what == ObjProperty::OWNER && cai)
|
||||
if(pack.what == ObjProperty::OWNER)
|
||||
{
|
||||
if(obj->ID == Obj::TOWN)
|
||||
{
|
||||
@@ -1116,9 +1106,9 @@ void GameStatePackVisitor::visitSetObjectProperty(SetObjectProperty & pack)
|
||||
}
|
||||
}
|
||||
|
||||
cai->detachFromBonusSystem(gs);
|
||||
obj->detachFromBonusSystem(gs);
|
||||
obj->setProperty(pack.what, pack.identifier);
|
||||
cai->attachToBonusSystem(gs);
|
||||
obj->attachToBonusSystem(gs);
|
||||
}
|
||||
else //not an armed instance
|
||||
{
|
||||
|
@@ -259,7 +259,7 @@ float Statistic::getMapExploredRatio(const CGameState * gs, PlayerColor player)
|
||||
if(tile.blocked() && !tile.visitable())
|
||||
continue;
|
||||
|
||||
if(gs->isVisible(int3(x, y, layer), player))
|
||||
if(gs->isVisibleFor(int3(x, y, layer), player))
|
||||
visible++;
|
||||
numTiles++;
|
||||
}
|
||||
|
@@ -10,12 +10,12 @@
|
||||
#include "StdInc.h"
|
||||
#include "QuestInfo.h"
|
||||
|
||||
#include "../callback/CGameInfoCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../mapObjects/CQuest.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
const CQuest * QuestInfo::getQuest(CGameInfoCallback *cb) const
|
||||
const CQuest * QuestInfo::getQuest(IGameInfoCallback *cb) const
|
||||
{
|
||||
auto questObject = dynamic_cast<const IQuestObject*>(getObject(cb));
|
||||
assert(questObject);
|
||||
@@ -23,12 +23,12 @@ const CQuest * QuestInfo::getQuest(CGameInfoCallback *cb) const
|
||||
return &questObject->getQuest();
|
||||
}
|
||||
|
||||
const CGObjectInstance * QuestInfo::getObject(CGameInfoCallback *cb) const
|
||||
const CGObjectInstance * QuestInfo::getObject(IGameInfoCallback *cb) const
|
||||
{
|
||||
return cb->getObjInstance(obj);
|
||||
}
|
||||
|
||||
int3 QuestInfo::getPosition(CGameInfoCallback *cb) const
|
||||
int3 QuestInfo::getPosition(IGameInfoCallback *cb) const
|
||||
{
|
||||
return getObject(cb)->visitablePos();
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CQuest;
|
||||
class CGObjectInstance;
|
||||
class CGameInfoCallback;
|
||||
class IGameInfoCallback;
|
||||
|
||||
struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
||||
{
|
||||
@@ -27,9 +27,9 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
||||
: obj(Obj)
|
||||
{}
|
||||
|
||||
const CQuest * getQuest(CGameInfoCallback *cb) const;
|
||||
const CGObjectInstance * getObject(CGameInfoCallback *cb) const;
|
||||
int3 getPosition(CGameInfoCallback *cb) const;
|
||||
const CQuest * getQuest(IGameInfoCallback *cb) const;
|
||||
const CGObjectInstance * getObject(IGameInfoCallback *cb) const;
|
||||
int3 getPosition(IGameInfoCallback *cb) const;
|
||||
|
||||
bool operator== (const QuestInfo & qi) const
|
||||
{
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "JsonBonus.h"
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../constants/StringConstants.h"
|
||||
#include "../GameLibrary.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
|
@@ -23,7 +23,7 @@ class RNG;
|
||||
class ObjectTemplate;
|
||||
class CGObjectInstance;
|
||||
class IObjectInfo;
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
|
||||
/// Class responsible for creation of objects of specific type & subtype
|
||||
class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
|
||||
/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
|
||||
/// to allow creating objects before game start (e.g. map loading)
|
||||
virtual std::shared_ptr<CGObjectInstance> create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
|
||||
virtual std::shared_ptr<CGObjectInstance> create(IGameInfoCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const = 0;
|
||||
|
||||
/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
|
||||
/// This should set remaining properties, including randomized or depending on map
|
||||
|
@@ -27,7 +27,7 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
|
||||
randomizeObject(castedObject, rng);
|
||||
}
|
||||
|
||||
std::shared_ptr<CGObjectInstance> create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const final
|
||||
std::shared_ptr<CGObjectInstance> create(IGameInfoCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const final
|
||||
{
|
||||
auto result = createObject(cb);
|
||||
|
||||
@@ -44,7 +44,7 @@ class CDefaultObjectTypeHandler : public AObjectTypeHandler
|
||||
protected:
|
||||
virtual void initializeObject(ObjectType * object) const {}
|
||||
virtual void randomizeObject(ObjectType * object, vstd::RNG & rng) const {}
|
||||
virtual std::shared_ptr<ObjectType> createObject(IGameCallback * cb) const
|
||||
virtual std::shared_ptr<ObjectType> createObject(IGameInfoCallback * cb) const
|
||||
{
|
||||
return std::make_shared<ObjectType>(cb);
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ bool CRewardableConstructor::hasNameTextID() const
|
||||
return !objectInfo.getParameters()["name"].isNull();
|
||||
}
|
||||
|
||||
std::shared_ptr<CGObjectInstance> CRewardableConstructor::create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const
|
||||
std::shared_ptr<CGObjectInstance> CRewardableConstructor::create(IGameInfoCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl) const
|
||||
{
|
||||
auto ret = std::make_shared<CRewardableObject>(cb);
|
||||
preInitObject(ret.get());
|
||||
@@ -55,7 +55,7 @@ void CRewardableConstructor::assignBonuses(std::vector<Bonus> & bonuses, MapObje
|
||||
}
|
||||
}
|
||||
|
||||
Rewardable::Configuration CRewardableConstructor::generateConfiguration(IGameCallback * cb, vstd::RNG & rand, MapObjectID objectID, const std::map<std::string, JsonNode> & presetVariables) const
|
||||
Rewardable::Configuration CRewardableConstructor::generateConfiguration(IGameInfoCallback * cb, vstd::RNG & rand, MapObjectID objectID, const std::map<std::string, JsonNode> & presetVariables) const
|
||||
{
|
||||
Rewardable::Configuration result;
|
||||
result.variables.preset = presetVariables;
|
||||
|
@@ -28,13 +28,13 @@ class DLL_LINKAGE CRewardableConstructor : public AObjectTypeHandler
|
||||
public:
|
||||
bool hasNameTextID() const override;
|
||||
|
||||
std::shared_ptr<CGObjectInstance> create(IGameCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
|
||||
std::shared_ptr<CGObjectInstance> create(IGameInfoCallback * cb, std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
|
||||
|
||||
void configureObject(CGObjectInstance * object, vstd::RNG & rng) const override;
|
||||
|
||||
std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
|
||||
|
||||
Rewardable::Configuration generateConfiguration(IGameCallback * cb, vstd::RNG & rand, MapObjectID objectID, const std::map<std::string, JsonNode> & presetVariables) const;
|
||||
Rewardable::Configuration generateConfiguration(IGameInfoCallback * cb, vstd::RNG & rand, MapObjectID objectID, const std::map<std::string, JsonNode> & presetVariables) const;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include "../GameLibrary.h"
|
||||
|
||||
#include "../CConfigHandler.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../entities/faction/CTownHandler.h"
|
||||
#include "../entities/hero/CHeroClass.h"
|
||||
#include "../json/JsonUtils.h"
|
||||
@@ -318,7 +318,7 @@ bool MarketInstanceConstructor::hasDescription() const
|
||||
return !descriptionTextID.empty();
|
||||
}
|
||||
|
||||
std::shared_ptr<CGMarket> MarketInstanceConstructor::createObject(IGameCallback * cb) const
|
||||
std::shared_ptr<CGMarket> MarketInstanceConstructor::createObject(IGameInfoCallback * cb) const
|
||||
{
|
||||
if(marketModes.size() == 1)
|
||||
{
|
||||
|
@@ -137,7 +137,7 @@ class MarketInstanceConstructor : public CDefaultObjectTypeHandler<CGMarket>
|
||||
|
||||
void initTypeData(const JsonNode & config) override;
|
||||
public:
|
||||
std::shared_ptr<CGMarket> createObject(IGameCallback * cb) const override;
|
||||
std::shared_ptr<CGMarket> createObject(IGameInfoCallback * cb) const override;
|
||||
void randomizeObject(CGMarket * object, vstd::RNG & rng) const override;
|
||||
|
||||
const std::set<EMarketMode> & availableModes() const;
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../CPlayerState.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../entities/faction/CFaction.h"
|
||||
#include "../entities/faction/CTown.h"
|
||||
#include "../entities/faction/CTownHandler.h"
|
||||
@@ -41,12 +41,12 @@ void CArmedInstance::randomizeArmy(FactionID type)
|
||||
}
|
||||
}
|
||||
|
||||
CArmedInstance::CArmedInstance(IGameCallback *cb)
|
||||
CArmedInstance::CArmedInstance(IGameInfoCallback *cb)
|
||||
:CArmedInstance(cb, false)
|
||||
{
|
||||
}
|
||||
|
||||
CArmedInstance::CArmedInstance(IGameCallback *cb, bool isHypothetic):
|
||||
CArmedInstance::CArmedInstance(IGameInfoCallback *cb, bool isHypothetic):
|
||||
CGObjectInstance(cb),
|
||||
CBonusSystemNode(isHypothetic),
|
||||
nonEvilAlignmentMix(this, Selector::type()(BonusType::NONEVIL_ALIGNMENT_MIX)), // Take Angelic Alliance troop-mixing freedom of non-evil units into account.
|
||||
|
@@ -50,8 +50,8 @@ public:
|
||||
void restoreBonusSystem(CGameState & gs) override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CArmedInstance(IGameCallback *cb);
|
||||
CArmedInstance(IGameCallback *cb, bool isHypothetic);
|
||||
CArmedInstance(IGameInfoCallback *cb);
|
||||
CArmedInstance(IGameInfoCallback *cb, bool isHypothetic);
|
||||
|
||||
PlayerColor getOwner() const override
|
||||
{
|
||||
|
@@ -15,7 +15,8 @@
|
||||
#include "../texts/CGeneralTextHandler.h"
|
||||
#include "../CConfigHandler.h"
|
||||
#include "../IGameSettings.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
@@ -154,7 +155,7 @@ std::vector<Component> CGCreature::getPopupComponents(PlayerColor player) const
|
||||
};
|
||||
}
|
||||
|
||||
void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGCreature::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
//show message
|
||||
if(!message.empty())
|
||||
@@ -163,18 +164,18 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.player = h->tempOwner;
|
||||
iw.text = message;
|
||||
iw.type = EInfoWindowMode::MODAL;
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
int action = takenAction(h);
|
||||
switch( action ) //decide what we do...
|
||||
{
|
||||
case FIGHT:
|
||||
fight(h);
|
||||
fight(gameEvents, h);
|
||||
break;
|
||||
case FLEE:
|
||||
{
|
||||
flee(h);
|
||||
flee(gameEvents, h);
|
||||
break;
|
||||
}
|
||||
case JOIN_FOR_FREE: //join for free
|
||||
@@ -183,7 +184,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
ynd.player = h->tempOwner;
|
||||
ynd.text.appendLocalString(EMetaText::ADVOB_TXT, 86);
|
||||
ynd.text.replaceName(getCreatureID(), getJoiningAmount());
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
break;
|
||||
}
|
||||
default: //join for gold
|
||||
@@ -199,7 +200,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
boost::algorithm::replace_first(tmp, "%d", std::to_string(action));
|
||||
boost::algorithm::replace_first(tmp,"%s",getCreature()->getNamePluralTranslated());
|
||||
ynd.text.appendRawString(tmp);
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -304,19 +305,19 @@ void CGCreature::initObj(vstd::RNG & rand)
|
||||
refusedJoining = false;
|
||||
}
|
||||
|
||||
void CGCreature::newTurn(vstd::RNG & rand) const
|
||||
void CGCreature::newTurn(IGameEventCallback & gameEvents) const
|
||||
{//Works only for stacks of single type of size up to 2 millions
|
||||
if (!notGrowingTeam)
|
||||
{
|
||||
if (stacks.begin()->second->getCount() < cb->getSettings().getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP) && cb->getDate(Date::DAY_OF_WEEK) == 1 && cb->getDate(Date::DAY) > 1)
|
||||
{
|
||||
ui32 power = static_cast<ui32>(temppower * (100 + cb->getSettings().getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT)) / 100);
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_COUNT, std::min<uint32_t>(power / 1000, cb->getSettings().getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP))); //set new amount
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_POWER, power); //increase temppower
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::MONSTER_COUNT, std::min<uint32_t>(power / 1000, cb->getSettings().getInteger(EGameSettings::CREATURES_WEEKLY_GROWTH_CAP))); //set new amount
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::MONSTER_POWER, power); //increase temppower
|
||||
}
|
||||
}
|
||||
if (cb->getSettings().getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_EXP, cb->getSettings().getInteger(EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE)); //for testing purpose
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::MONSTER_EXP, cb->getSettings().getInteger(EGameSettings::CREATURES_DAILY_STACK_EXPERIENCE)); //for testing purpose
|
||||
}
|
||||
void CGCreature::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
@@ -403,34 +404,34 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
||||
return FIGHT;
|
||||
}
|
||||
|
||||
void CGCreature::fleeDecision(const CGHeroInstance *h, ui32 pursue) const
|
||||
void CGCreature::fleeDecision(IGameEventCallback & gameEvents, const CGHeroInstance *h, ui32 pursue) const
|
||||
{
|
||||
if(refusedJoining)
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_REFUSED_JOIN, false);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::MONSTER_REFUSED_JOIN, false);
|
||||
|
||||
if(pursue)
|
||||
{
|
||||
fight(h);
|
||||
fight(gameEvents, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
cb->removeObject(this, h->getOwner());
|
||||
gameEvents.removeObject(this, h->getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) const
|
||||
void CGCreature::joinDecision(IGameEventCallback & gameEvents, const CGHeroInstance *h, int cost, ui32 accept) const
|
||||
{
|
||||
if(!accept)
|
||||
{
|
||||
if(takenAction(h,false) == FLEE)
|
||||
{
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_REFUSED_JOIN, true);
|
||||
flee(h);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::MONSTER_REFUSED_JOIN, true);
|
||||
flee(gameEvents, h);
|
||||
}
|
||||
else //they fight
|
||||
{
|
||||
h->showInfoDialog(87, 0, EInfoWindowMode::MODAL);//Insulted by your refusal of their offer, the monsters attack!
|
||||
fight(h);
|
||||
h->showInfoDialog(gameEvents, 87, 0, EInfoWindowMode::MODAL);//Insulted by your refusal of their offer, the monsters attack!
|
||||
fight(gameEvents, h);
|
||||
}
|
||||
}
|
||||
else //accepted
|
||||
@@ -440,27 +441,27 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendLocalString(EMetaText::GENERAL_TXT,29); //You don't have enough gold
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
|
||||
//act as if player refused
|
||||
joinDecision(h,cost,false);
|
||||
joinDecision(gameEvents, h, cost, false);
|
||||
return;
|
||||
}
|
||||
|
||||
//take gold
|
||||
if(cost)
|
||||
cb->giveResource(h->tempOwner,EGameResID::GOLD,-cost);
|
||||
gameEvents.giveResource(h->tempOwner,EGameResID::GOLD,-cost);
|
||||
|
||||
giveReward(h);
|
||||
giveReward(gameEvents, h);
|
||||
|
||||
for(auto & stack : this->stacks)
|
||||
stack.second->setCount(getJoiningAmount());
|
||||
|
||||
cb->tryJoiningArmy(this, h, true, true);
|
||||
gameEvents.tryJoiningArmy(this, h, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CGCreature::fight( const CGHeroInstance *h ) const
|
||||
void CGCreature::fight(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
//split stacks
|
||||
int stacksCount = getNumberOfStacks(h);
|
||||
@@ -475,13 +476,13 @@ void CGCreature::fight( const CGHeroInstance *h ) const
|
||||
for (int slotID = 1; slotID < a; ++slotID)
|
||||
{
|
||||
int stackSize = m + 1;
|
||||
cb->moveStack(StackLocation(id, sourceSlot), StackLocation(id, SlotID(slotID)), stackSize);
|
||||
gameEvents.moveStack(StackLocation(id, sourceSlot), StackLocation(id, SlotID(slotID)), stackSize);
|
||||
}
|
||||
for (int slotID = a; slotID < stacksCount; ++slotID)
|
||||
{
|
||||
int stackSize = m;
|
||||
if (slotID) //don't do this when a = 0 -> stack is single
|
||||
cb->moveStack(StackLocation(id, sourceSlot), StackLocation(id, SlotID(slotID)), stackSize);
|
||||
gameEvents.moveStack(StackLocation(id, sourceSlot), StackLocation(id, SlotID(slotID)), stackSize);
|
||||
}
|
||||
if (stacksCount > 1)
|
||||
{
|
||||
@@ -491,36 +492,36 @@ void CGCreature::fight( const CGHeroInstance *h ) const
|
||||
const auto & upgrades = getStack(slotID).getCreature()->upgrades;
|
||||
if(!upgrades.empty())
|
||||
{
|
||||
auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState().getRandomGenerator());
|
||||
cb->changeStackType(StackLocation(id, slotID), it->toCreature());
|
||||
auto it = RandomGeneratorUtil::nextItem(upgrades, gameEvents.getRandomGenerator());
|
||||
gameEvents.changeStackType(StackLocation(id, slotID), it->toCreature());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cb->startBattle(h, this);
|
||||
gameEvents.startBattle(h, this);
|
||||
|
||||
}
|
||||
|
||||
void CGCreature::flee( const CGHeroInstance * h ) const
|
||||
void CGCreature::flee(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
BlockingDialog ynd(true,false);
|
||||
ynd.player = h->tempOwner;
|
||||
ynd.text.appendLocalString(EMetaText::ADVOB_TXT,91);
|
||||
ynd.text.replaceName(getCreatureID(), getStackCount(SlotID(0)));
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
}
|
||||
|
||||
void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGCreature::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if(result.winner == BattleSide::ATTACKER)
|
||||
{
|
||||
giveReward(hero);
|
||||
cb->removeObject(this, hero->getOwner());
|
||||
giveReward(gameEvents, hero);
|
||||
gameEvents.removeObject(this, hero->getOwner());
|
||||
}
|
||||
else if(result.winner == BattleSide::NONE) // draw
|
||||
{
|
||||
// guarded reward is lost forever on draw
|
||||
cb->removeObject(this, hero->getOwner());
|
||||
gameEvents.removeObject(this, hero->getOwner());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -531,13 +532,13 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
{
|
||||
if(cre->isMyDirectUpgrade(i->second->getCreature()))
|
||||
{
|
||||
cb->changeStackType(StackLocation(id, i->first), cre); //un-upgrade creatures
|
||||
gameEvents.changeStackType(StackLocation(id, i->first), cre); //un-upgrade creatures
|
||||
}
|
||||
}
|
||||
|
||||
//first stack has to be at slot 0 -> if original one got killed, move there first remaining stack
|
||||
if(!hasStackAtSlot(SlotID(0)))
|
||||
cb->moveStack(StackLocation(id, stacks.begin()->first), StackLocation(id, SlotID(0)), stacks.begin()->second->getCount());
|
||||
gameEvents.moveStack(StackLocation(id, stacks.begin()->first), StackLocation(id, SlotID(0)), stacks.begin()->second->getCount());
|
||||
|
||||
while(stacks.size() > 1) //hopefully that's enough
|
||||
{
|
||||
@@ -548,20 +549,20 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
if(slot == i->first) //no reason to move stack to its own slot
|
||||
break;
|
||||
else
|
||||
cb->moveStack(StackLocation(id, i->first), StackLocation(id, slot), i->second->getCount());
|
||||
gameEvents.moveStack(StackLocation(id, i->first), StackLocation(id, slot), i->second->getCount());
|
||||
}
|
||||
|
||||
cb->setObjPropertyValue(id, ObjProperty::MONSTER_POWER, stacks.begin()->second->getCount() * 1000); //remember casualties
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::MONSTER_POWER, stacks.begin()->second->getCount() * 1000); //remember casualties
|
||||
}
|
||||
}
|
||||
|
||||
void CGCreature::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGCreature::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
auto action = takenAction(hero);
|
||||
if(!refusedJoining && action >= JOIN_FOR_FREE) //higher means price
|
||||
joinDecision(hero, action, answer);
|
||||
joinDecision(gameEvents, hero, action, answer);
|
||||
else if(action != FIGHT)
|
||||
fleeDecision(hero, answer);
|
||||
fleeDecision(gameEvents, hero, answer);
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
@@ -620,14 +621,14 @@ int CGCreature::getNumberOfStacks(const CGHeroInstance *hero) const
|
||||
return split;
|
||||
}
|
||||
|
||||
void CGCreature::giveReward(const CGHeroInstance * h) const
|
||||
void CGCreature::giveReward(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
|
||||
if(!resources.empty())
|
||||
{
|
||||
cb->giveResources(h->tempOwner, resources);
|
||||
gameEvents.giveResources(h->tempOwner, resources);
|
||||
for(const auto & res : GameResID::ALL_RESOURCES())
|
||||
{
|
||||
if(resources[res] > 0)
|
||||
@@ -637,7 +638,7 @@ void CGCreature::giveReward(const CGHeroInstance * h) const
|
||||
|
||||
if(gainedArtifact != ArtifactID::NONE)
|
||||
{
|
||||
cb->giveHeroNewArtifact(h, gainedArtifact, ArtifactPosition::FIRST_AVAILABLE);
|
||||
gameEvents.giveHeroNewArtifact(h, gainedArtifact, ArtifactPosition::FIRST_AVAILABLE);
|
||||
iw.components.emplace_back(ComponentType::ARTIFACT, gainedArtifact);
|
||||
}
|
||||
|
||||
@@ -646,7 +647,7 @@ void CGCreature::giveReward(const CGHeroInstance * h) const
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 183); // % has found treasure
|
||||
iw.text.replaceRawString(h->getNameTranslated());
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -38,7 +38,7 @@ public:
|
||||
|
||||
bool refusedJoining = false;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
std::string getHoverText(PlayerColor player) const override;
|
||||
std::string getHoverText(const CGHeroInstance * hero) const override;
|
||||
std::string getPopupText(PlayerColor player) const override;
|
||||
@@ -46,9 +46,9 @@ public:
|
||||
std::vector<Component> getPopupComponents(PlayerColor player) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void newTurn(IGameEventCallback & gameEvents) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
CreatureID getCreatureID() const;
|
||||
const CCreature * getCreature() const;
|
||||
TQuantity getJoiningAmount() const;
|
||||
@@ -76,13 +76,13 @@ protected:
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
|
||||
private:
|
||||
void fight(const CGHeroInstance *h) const;
|
||||
void flee( const CGHeroInstance * h ) const;
|
||||
void fleeDecision(const CGHeroInstance *h, ui32 pursue) const;
|
||||
void joinDecision(const CGHeroInstance *h, int cost, ui32 accept) const;
|
||||
void fight(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
void flee(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
void fleeDecision(IGameEventCallback & gameEvents, const CGHeroInstance * h, ui32 pursue) const;
|
||||
void joinDecision(IGameEventCallback & gameEvents, const CGHeroInstance * h, int cost, ui32 accept) const;
|
||||
|
||||
int takenAction(const CGHeroInstance *h, bool allowJoin=true) const; //action on confrontation: -2 - fight, -1 - flee, >=0 - will join for given value of gold (may be 0)
|
||||
void giveReward(const CGHeroInstance * h) const;
|
||||
void giveReward(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
std::string getMonsterLevelText() const;
|
||||
};
|
||||
|
||||
|
@@ -10,7 +10,8 @@
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CGDwelling.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../serializer/JsonSerializeFormat.h"
|
||||
#include "../entities/faction/CTownHandler.h"
|
||||
#include "../mapping/CMap.h"
|
||||
@@ -46,7 +47,7 @@ void CGDwellingRandomizationInfo::serializeJson(JsonSerializeFormat & handler)
|
||||
}
|
||||
}
|
||||
|
||||
CGDwelling::CGDwelling(IGameCallback *cb):
|
||||
CGDwelling::CGDwelling(IGameInfoCallback *cb):
|
||||
CArmedInstance(cb)
|
||||
{}
|
||||
|
||||
@@ -209,7 +210,7 @@ void CGDwelling::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
}
|
||||
}
|
||||
|
||||
void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGDwelling::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(ID == Obj::REFUGEE_CAMP && !creatures[0].first) //Refugee Camp, no available cres
|
||||
{
|
||||
@@ -218,7 +219,7 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 44); //{%s} \n\n The camp is deserted. Perhaps you should try next week.
|
||||
iw.text.replaceName(ID, subID);
|
||||
cb->sendAndApply(iw);
|
||||
gameEvents.sendAndApply(iw);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,14 +239,14 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
else
|
||||
bd.text.replaceLocalString(EMetaText::ARRAY_TXT, 173 + (int)Slots().begin()->second->getQuantityID()*3);
|
||||
bd.text.replaceName(*Slots().begin()->second);
|
||||
cb->showBlockingDialog(this, &bd);
|
||||
gameEvents.showBlockingDialog(this, &bd);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO this shouldn't be hardcoded
|
||||
if(relations == PlayerRelations::ENEMIES && ID != Obj::WAR_MACHINE_FACTORY && ID != Obj::REFUGEE_CAMP)
|
||||
{
|
||||
cb->setOwner(this, h->tempOwner);
|
||||
gameEvents.setOwner(this, h->tempOwner);
|
||||
}
|
||||
|
||||
BlockingDialog bd (true,false);
|
||||
@@ -274,10 +275,10 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
bd.flags |= BlockingDialog::SAFE_TO_AUTOACCEPT;
|
||||
}
|
||||
|
||||
cb->showBlockingDialog(this, &bd);
|
||||
gameEvents.showBlockingDialog(this, &bd);
|
||||
}
|
||||
|
||||
void CGDwelling::newTurn(vstd::RNG & rand) const
|
||||
void CGDwelling::newTurn(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
if(cb->getDate(Date::DAY_OF_WEEK) != 1) //not first day of week
|
||||
return;
|
||||
@@ -288,7 +289,7 @@ void CGDwelling::newTurn(vstd::RNG & rand) const
|
||||
|
||||
if(ID == Obj::REFUGEE_CAMP) //if it's a refugee camp, we need to pick an available creature
|
||||
{
|
||||
cb->setObjPropertyID(id, ObjProperty::AVAILABLE_CREATURE, LIBRARY->creh->pickRandomMonster(rand));
|
||||
gameEvents.setObjPropertyID(id, ObjProperty::AVAILABLE_CREATURE, LIBRARY->creh->pickRandomMonster(gameEvents.getRandomGenerator()));
|
||||
}
|
||||
|
||||
bool change = false;
|
||||
@@ -318,9 +319,9 @@ void CGDwelling::newTurn(vstd::RNG & rand) const
|
||||
}
|
||||
|
||||
if(change)
|
||||
cb->sendAndApply(sac);
|
||||
gameEvents.sendAndApply(sac);
|
||||
|
||||
updateGuards();
|
||||
updateGuards(gameEvents);
|
||||
}
|
||||
|
||||
std::vector<Component> CGDwelling::getPopupComponents(PlayerColor player) const
|
||||
@@ -356,7 +357,7 @@ std::vector<Component> CGDwelling::getPopupComponents(PlayerColor player) const
|
||||
return result;
|
||||
}
|
||||
|
||||
void CGDwelling::updateGuards() const
|
||||
void CGDwelling::updateGuards(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
//TODO: store custom guard config and use it
|
||||
//TODO: store boolean flag for guards
|
||||
@@ -386,7 +387,7 @@ void CGDwelling::updateGuards() const
|
||||
csc.slot = slot;
|
||||
csc.count = crea->getGrowth() * 3;
|
||||
csc.absoluteValue = true;
|
||||
cb->sendAndApply(csc);
|
||||
gameEvents.sendAndApply(csc);
|
||||
}
|
||||
else //slot is empty, create whole new stack
|
||||
{
|
||||
@@ -395,13 +396,13 @@ void CGDwelling::updateGuards() const
|
||||
ns.slot = slot;
|
||||
ns.type = crea->getId();
|
||||
ns.count = crea->getGrowth() * 3;
|
||||
cb->sendAndApply(ns);
|
||||
gameEvents.sendAndApply(ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
|
||||
void CGDwelling::heroAcceptsCreatures(IGameEventCallback & gameEvents, const CGHeroInstance *h) const
|
||||
{
|
||||
CreatureID crid = creatures[0].second[0];
|
||||
auto *crs = crid.toCreature();
|
||||
@@ -420,7 +421,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
|
||||
std::pair<SlotID, SlotID> toMerge;
|
||||
if (h->mergeableStacks(toMerge))
|
||||
{
|
||||
cb->moveStack(StackLocation(h->id, toMerge.first), StackLocation(h->id, toMerge.second), -1); //merge toMerge.first into toMerge.second
|
||||
gameEvents.moveStack(StackLocation(h->id, toMerge.first), StackLocation(h->id, toMerge.second), -1); //merge toMerge.first into toMerge.second
|
||||
assert(!h->hasStackAtSlot(toMerge.first)); //we have now a new free slot
|
||||
}
|
||||
}
|
||||
@@ -434,7 +435,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendLocalString(EMetaText::GENERAL_TXT, 425);//The %s would join your hero, but there aren't enough provisions to support them.
|
||||
iw.text.replaceNamePlural(crid);
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
else //give creatures
|
||||
{
|
||||
@@ -451,9 +452,9 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
|
||||
iw.text.replaceNumber(count);
|
||||
iw.text.replaceNamePlural(crid);
|
||||
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->sendAndApply(sac);
|
||||
cb->addToSlot(StackLocation(h->id, slot), crs, count);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
gameEvents.sendAndApply(sac);
|
||||
gameEvents.addToSlot(StackLocation(h->id, slot), crs, count);
|
||||
}
|
||||
}
|
||||
else //there no creatures
|
||||
@@ -463,7 +464,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
|
||||
iw.text.appendLocalString(EMetaText::GENERAL_TXT, 422); //There are no %s here to recruit.
|
||||
iw.text.replaceNamePlural(crid);
|
||||
iw.player = h->tempOwner;
|
||||
cb->sendAndApply(iw);
|
||||
gameEvents.sendAndApply(iw);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -485,33 +486,33 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
|
||||
else
|
||||
entry.first = 1;
|
||||
}
|
||||
cb->sendAndApply(sac);
|
||||
gameEvents.sendAndApply(sac);
|
||||
}
|
||||
|
||||
auto windowMode = (ID == Obj::CREATURE_GENERATOR1 || ID == Obj::REFUGEE_CAMP) ? EOpenWindowMode::RECRUITMENT_FIRST : EOpenWindowMode::RECRUITMENT_ALL;
|
||||
cb->showObjectWindow(this, windowMode, h, true);
|
||||
gameEvents.showObjectWindow(this, windowMode, h, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CGDwelling::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGDwelling::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if (result.winner == BattleSide::ATTACKER)
|
||||
{
|
||||
onHeroVisit(hero);
|
||||
onHeroVisit(gameEvents, hero);
|
||||
}
|
||||
}
|
||||
|
||||
void CGDwelling::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGDwelling::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
auto relations = cb->getPlayerRelations(getOwner(), hero->getOwner());
|
||||
if(stacksCount() > 0 && relations == PlayerRelations::ENEMIES) //guards present
|
||||
{
|
||||
if(answer)
|
||||
cb->startBattle(hero, this);
|
||||
gameEvents.startBattle(hero, this);
|
||||
}
|
||||
else if(answer)
|
||||
{
|
||||
heroAcceptsCreatures(hero);
|
||||
heroAcceptsCreatures(gameEvents, hero);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ public:
|
||||
std::optional<CGDwellingRandomizationInfo> randomizationInfo; //random dwelling options; not serialized
|
||||
TCreaturesSet creatures; //creatures[level] -> <vector of alternative ids (base creature and upgrades, creatures amount>
|
||||
|
||||
CGDwelling(IGameCallback *cb);
|
||||
CGDwelling(IGameInfoCallback *cb);
|
||||
~CGDwelling() override;
|
||||
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
@@ -55,15 +55,15 @@ private:
|
||||
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void newTurn(IGameEventCallback & gameEvents) const override;
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
std::vector<Component> getPopupComponents(PlayerColor player) const override;
|
||||
|
||||
void updateGuards() const;
|
||||
void heroAcceptsCreatures(const CGHeroInstance *h) const;
|
||||
void updateGuards(IGameEventCallback & gameEvents) const;
|
||||
void heroAcceptsCreatures(IGameEventCallback & gameEvents, const CGHeroInstance *h) const;
|
||||
|
||||
public:
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
|
@@ -15,7 +15,8 @@
|
||||
#include <vcmi/spells/Spell.h>
|
||||
#include <vstd/RNG.h>
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../texts/CGeneralTextHandler.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../RoadHandler.h"
|
||||
@@ -253,7 +254,7 @@ int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti)
|
||||
return ti->getMovePointsLimitWater();
|
||||
}
|
||||
|
||||
CGHeroInstance::CGHeroInstance(IGameCallback * cb)
|
||||
CGHeroInstance::CGHeroInstance(IGameInfoCallback * cb)
|
||||
: CArmedInstance(cb),
|
||||
CArtifactSet(cb),
|
||||
tacticFormationEnabled(false),
|
||||
@@ -554,7 +555,7 @@ bool CGHeroInstance::needsLastStack() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGHeroInstance::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(h == this) return; //exclude potential self-visiting
|
||||
|
||||
@@ -563,14 +564,14 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
if( cb->gameState().getPlayerRelations(tempOwner, h->tempOwner) != PlayerRelations::ENEMIES)
|
||||
{
|
||||
//exchange
|
||||
cb->heroExchange(h->id, id);
|
||||
gameEvents.heroExchange(h->id, id);
|
||||
}
|
||||
else //battle
|
||||
{
|
||||
if(getVisitedTown()) //we're in town
|
||||
getVisitedTown()->onHeroVisit(h); //town will handle attacking
|
||||
getVisitedTown()->onHeroVisit(gameEvents, h); //town will handle attacking
|
||||
else
|
||||
cb->startBattle(h, this);
|
||||
gameEvents.startBattle(h, this);
|
||||
}
|
||||
}
|
||||
else if(ID == Obj::PRISON)
|
||||
@@ -581,7 +582,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
SetMovePoints smp;
|
||||
smp.hid = id;
|
||||
|
||||
cb->setManaPoints (id, manaLimit());
|
||||
gameEvents.setManaPoints(id, manaLimit());
|
||||
|
||||
ObjectInstanceID boatId;
|
||||
const auto boatPos = visitablePos();
|
||||
@@ -591,7 +592,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
if (!inBoat())
|
||||
{
|
||||
//Create a new boat for hero
|
||||
cb->createBoat(boatPos, getBoatType(), h->getOwner());
|
||||
gameEvents.createBoat(boatPos, getBoatType(), h->getOwner());
|
||||
boatId = cb->getTopObj(boatPos)->id;
|
||||
}
|
||||
}
|
||||
@@ -599,15 +600,15 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
{
|
||||
smp.val = movementPointsLimit(true);
|
||||
}
|
||||
cb->giveHero(id, h->tempOwner, boatId); //recreates def and adds hero to player
|
||||
cb->setObjPropertyID(id, ObjProperty::ID, Obj(Obj::HERO)); //set ID to 34 AFTER hero gets correct flag color
|
||||
cb->setMovePoints (&smp);
|
||||
gameEvents.giveHero(id, h->tempOwner, boatId); //recreates def and adds hero to player
|
||||
gameEvents.setObjPropertyID(id, ObjProperty::ID, Obj(Obj::HERO)); //set ID to 34 AFTER hero gets correct flag color
|
||||
gameEvents.setMovePoints (&smp);
|
||||
|
||||
h->showInfoDialog(102);
|
||||
h->showInfoDialog(gameEvents, 102);
|
||||
}
|
||||
else //already 8 wandering heroes
|
||||
{
|
||||
h->showInfoDialog(103);
|
||||
h->showInfoDialog(gameEvents, 103);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -667,13 +668,13 @@ void CGHeroInstance::SecondarySkillsInfo::resetWisdomCounter()
|
||||
wisdomCounter = 0;
|
||||
}
|
||||
|
||||
void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
|
||||
void CGHeroInstance::pickRandomObject(vstd::RNG & randomGenerator)
|
||||
{
|
||||
assert(ID == Obj::HERO || ID == Obj::PRISON || ID == Obj::RANDOM_HERO);
|
||||
|
||||
if (ID == Obj::RANDOM_HERO)
|
||||
{
|
||||
auto selectedHero = cb->gameState().pickNextHeroType(getOwner());
|
||||
auto selectedHero = cb->gameState().pickNextHeroType(randomGenerator, getOwner());
|
||||
|
||||
ID = Obj::HERO;
|
||||
subID = selectedHero;
|
||||
|
@@ -72,7 +72,7 @@ class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator,
|
||||
ui32 movement; //remaining movement points
|
||||
bool inTownGarrison; // if hero is in town garrison
|
||||
|
||||
IGameCallback * getCallback() const final { return cb; }
|
||||
IGameInfoCallback * getCallback() const final { return cb; }
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -281,7 +281,7 @@ public:
|
||||
/// If this hero perishes, the scenario is failed
|
||||
bool isMissionCritical() const;
|
||||
|
||||
CGHeroInstance(IGameCallback *cb);
|
||||
CGHeroInstance(IGameInfoCallback *cb);
|
||||
virtual ~CGHeroInstance();
|
||||
|
||||
PlayerColor getOwner() const override;
|
||||
@@ -321,7 +321,7 @@ public:
|
||||
void updateAppearance();
|
||||
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
std::string getObjectName() const override;
|
||||
std::string getHoverText(PlayerColor player) const override;
|
||||
std::string getMovementPointsTextIfOwner(PlayerColor player) const;
|
||||
|
@@ -11,7 +11,8 @@
|
||||
#include "StdInc.h"
|
||||
#include "CGMarket.h"
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../texts/CGeneralTextHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "CGTownInstance.h"
|
||||
@@ -34,9 +35,9 @@ void CGMarket::initObj(vstd::RNG & rand)
|
||||
getObjectHandler()->configureObject(this, rand);
|
||||
}
|
||||
|
||||
void CGMarket::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGMarket::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::MARKET_WINDOW, h, true);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::MARKET_WINDOW, h, true);
|
||||
}
|
||||
|
||||
std::string CGMarket::getPopupText(PlayerColor player) const
|
||||
@@ -77,7 +78,7 @@ std::set<EMarketMode> CGMarket::availableModes() const
|
||||
return getMarketHandler()->availableModes();
|
||||
}
|
||||
|
||||
CGMarket::CGMarket(IGameCallback *cb)
|
||||
CGMarket::CGMarket(IGameInfoCallback *cb)
|
||||
: CGObjectInstance(cb)
|
||||
, IMarket(cb)
|
||||
{}
|
||||
@@ -98,7 +99,7 @@ std::vector<TradeItemBuy> CGBlackMarket::availableItemsIds(EMarketMode mode) con
|
||||
}
|
||||
}
|
||||
|
||||
void CGBlackMarket::newTurn(vstd::RNG & rand) const
|
||||
void CGBlackMarket::newTurn(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
int resetPeriod = cb->getSettings().getInteger(EGameSettings::MARKETS_BLACK_MARKET_RESTOCK_PERIOD);
|
||||
|
||||
@@ -110,8 +111,8 @@ void CGBlackMarket::newTurn(vstd::RNG & rand) const
|
||||
|
||||
SetAvailableArtifacts saa;
|
||||
saa.id = id;
|
||||
cb->pickAllowedArtsSet(saa.arts, rand);
|
||||
cb->sendAndApply(saa);
|
||||
cb->pickAllowedArtsSet(saa.arts, gameEvents.getRandomGenerator());
|
||||
gameEvents.sendAndApply(saa);
|
||||
}
|
||||
|
||||
std::vector<TradeItemBuy> CGUniversity::availableItemsIds(EMarketMode mode) const
|
||||
@@ -131,9 +132,9 @@ std::string CGUniversity::getSpeechTranslated() const
|
||||
return getMarketHandler()->getSpeechTranslated();
|
||||
}
|
||||
|
||||
void CGUniversity::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGUniversity::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::UNIVERSITY_WINDOW, h, true);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::UNIVERSITY_WINDOW, h, true);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -22,9 +22,9 @@ protected:
|
||||
std::shared_ptr<MarketInstanceConstructor> getMarketHandler() const;
|
||||
|
||||
public:
|
||||
CGMarket(IGameCallback *cb);
|
||||
CGMarket(IGameInfoCallback *cb);
|
||||
///IObjectInterface
|
||||
void onHeroVisit(const CGHeroInstance * h) const override; //open trading window
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override; //open trading window
|
||||
void initObj(vstd::RNG & rand) override;//set skills for trade
|
||||
|
||||
std::string getPopupText(PlayerColor player) const override;
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
std::vector<ArtifactID> artifacts; //available artifacts
|
||||
|
||||
void newTurn(vstd::RNG & rand) const override; //reset artifacts for black market every month
|
||||
void newTurn(IGameEventCallback & gameEvents) const override; //reset artifacts for black market every month
|
||||
std::vector<TradeItemBuy> availableItemsIds(EMarketMode mode) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
std::vector<TradeItemBuy> skills; //available skills
|
||||
|
||||
std::vector<TradeItemBuy> availableItemsIds(EMarketMode mode) const override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override; //open window
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override; //open window
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
|
@@ -14,7 +14,8 @@
|
||||
#include "CGHeroInstance.h"
|
||||
#include "ObjectTemplate.h"
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../texts/CGeneralTextHandler.h"
|
||||
#include "../constants/StringConstants.h"
|
||||
@@ -30,7 +31,7 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
//TODO: remove constructor
|
||||
CGObjectInstance::CGObjectInstance(IGameCallback *cb):
|
||||
CGObjectInstance::CGObjectInstance(IGameInfoCallback *cb):
|
||||
IObjectInterface(cb),
|
||||
pos(-1,-1,-1),
|
||||
ID(Obj::NO_OBJ),
|
||||
@@ -223,7 +224,7 @@ int3 CGObjectInstance::getVisitableOffset() const
|
||||
return appearance->getVisitableOffset();
|
||||
}
|
||||
|
||||
void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration) const
|
||||
void CGObjectInstance::giveDummyBonus(IGameEventCallback & gameEvents, const ObjectInstanceID & heroID, BonusDuration::Type duration) const
|
||||
{
|
||||
GiveBonus gbonus;
|
||||
gbonus.bonus.type = BonusType::NONE;
|
||||
@@ -231,7 +232,7 @@ void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDura
|
||||
gbonus.bonus.duration = duration;
|
||||
gbonus.bonus.source = BonusSource::OBJECT_TYPE;
|
||||
gbonus.bonus.sid = BonusSourceID(ID);
|
||||
cb->giveHeroBonus(&gbonus);
|
||||
gameEvents.giveHeroBonus(&gbonus);
|
||||
}
|
||||
|
||||
std::string CGObjectInstance::getObjectName() const
|
||||
@@ -298,19 +299,19 @@ std::vector<Component> CGObjectInstance::getPopupComponents(const CGHeroInstance
|
||||
return getPopupComponents(hero->getOwner());
|
||||
}
|
||||
|
||||
void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGObjectInstance::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
switch(ID.toEnum())
|
||||
{
|
||||
case Obj::SANCTUARY:
|
||||
{
|
||||
//You enter the sanctuary and immediately feel as if a great weight has been lifted off your shoulders. You feel safe here.
|
||||
h->showInfoDialog(114);
|
||||
h->showInfoDialog(gameEvents, 114);
|
||||
}
|
||||
break;
|
||||
case Obj::TAVERN:
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::TAVERN_WINDOW, h, true);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::TAVERN_WINDOW, h, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
std::string instanceName;
|
||||
|
||||
CGObjectInstance(IGameCallback *cb);
|
||||
CGObjectInstance(IGameInfoCallback *cb);
|
||||
~CGObjectInstance() override;
|
||||
|
||||
MapObjectID getObjGroupIndex() const override;
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
|
||||
void setProperty(ObjProperty what, ObjPropertyID identifier) final;
|
||||
|
||||
@@ -170,7 +170,7 @@ protected:
|
||||
void setType(MapObjectID ID, MapObjectSubID subID);
|
||||
|
||||
/// Gives dummy bonus from this object to hero. Can be used to track visited state
|
||||
void giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration = BonusDuration::ONE_DAY) const;
|
||||
void giveDummyBonus(IGameEventCallback & gameEvents, const ObjectInstanceID & heroID, BonusDuration::Type duration = BonusDuration::ONE_DAY) const;
|
||||
|
||||
///Serialize object-type specific options
|
||||
virtual void serializeJsonOptions(JsonSerializeFormat & handler);
|
||||
|
@@ -18,7 +18,8 @@
|
||||
|
||||
#include "../CSkillHandler.h"
|
||||
#include "../StartInfo.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../constants/StringConstants.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
#include "../networkPacks/PacksForClientBattle.h"
|
||||
@@ -48,12 +49,12 @@ void CGPandoraBox::initObj(vstd::RNG & rand)
|
||||
CRewardableObject::initObj(rand);
|
||||
}
|
||||
|
||||
void CGPandoraBox::grantRewardWithMessage(const CGHeroInstance * h, int index, bool markAsVisit) const
|
||||
void CGPandoraBox::grantRewardWithMessage(IGameEventCallback & gameEvents, const CGHeroInstance * h, int index, bool markAsVisit) const
|
||||
{
|
||||
auto vi = configuration.info.at(index);
|
||||
if(!vi.message.empty())
|
||||
{
|
||||
CRewardableObject::grantRewardWithMessage(h, index, markAsVisit);
|
||||
CRewardableObject::grantRewardWithMessage(gameEvents, h, index, markAsVisit);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,7 +75,7 @@ void CGPandoraBox::grantRewardWithMessage(const CGHeroInstance * h, int index, b
|
||||
reward.loadComponents(iw.components, h);
|
||||
iw.type = EInfoWindowMode::MODAL;
|
||||
if(!iw.components.empty())
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
};
|
||||
|
||||
Rewardable::Reward temp;
|
||||
@@ -166,43 +167,43 @@ void CGPandoraBox::grantRewardWithMessage(const CGHeroInstance * h, int index, b
|
||||
|
||||
// grant reward afterwards. Note that it may remove object
|
||||
if(markAsVisit)
|
||||
markAsVisited(h);
|
||||
grantReward(index, h);
|
||||
markAsVisited(gameEvents, h);
|
||||
grantReward(gameEvents, index, h);
|
||||
}
|
||||
|
||||
void CGPandoraBox::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGPandoraBox::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
BlockingDialog bd (true, false);
|
||||
bd.player = h->getOwner();
|
||||
bd.text.appendLocalString(EMetaText::ADVOB_TXT, 14);
|
||||
cb->showBlockingDialog(this, &bd);
|
||||
gameEvents.showBlockingDialog(this, &bd);
|
||||
}
|
||||
|
||||
void CGPandoraBox::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGPandoraBox::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if(result.winner == BattleSide::ATTACKER)
|
||||
{
|
||||
CRewardableObject::onHeroVisit(hero);
|
||||
CRewardableObject::onHeroVisit(gameEvents, hero);
|
||||
}
|
||||
}
|
||||
|
||||
void CGPandoraBox::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGPandoraBox::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
if(answer)
|
||||
{
|
||||
if(stacksCount() > 0) //if pandora's box is protected by army
|
||||
{
|
||||
hero->showInfoDialog(16, 0, EInfoWindowMode::MODAL);
|
||||
cb->startBattle(hero, this); //grants things after battle
|
||||
hero->showInfoDialog(gameEvents, 16, 0, EInfoWindowMode::MODAL);
|
||||
gameEvents.startBattle(hero, this); //grants things after battle
|
||||
}
|
||||
else if(getAvailableRewards(hero, Rewardable::EEventType::EVENT_FIRST_VISIT).empty())
|
||||
{
|
||||
hero->showInfoDialog(15);
|
||||
cb->removeObject(this, hero->getOwner());
|
||||
hero->showInfoDialog(gameEvents, 15);
|
||||
gameEvents.removeObject(this, hero->getOwner());
|
||||
}
|
||||
else //if it gives something without battle
|
||||
{
|
||||
CRewardableObject::onHeroVisit(hero);
|
||||
CRewardableObject::onHeroVisit(gameEvents, hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,12 +288,12 @@ void CGEvent::init()
|
||||
}
|
||||
}
|
||||
|
||||
void CGEvent::grantRewardWithMessage(const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const
|
||||
void CGEvent::grantRewardWithMessage(IGameEventCallback & gameEvents, const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const
|
||||
{
|
||||
CRewardableObject::grantRewardWithMessage(contextHero, rewardIndex, markAsVisit);
|
||||
CRewardableObject::grantRewardWithMessage(gameEvents, contextHero, rewardIndex, markAsVisit);
|
||||
}
|
||||
|
||||
void CGEvent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGEvent::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(availableFor.count(h->tempOwner) == 0)
|
||||
return;
|
||||
@@ -300,13 +301,13 @@ void CGEvent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
if(cb->getPlayerSettings(h->tempOwner)->isControlledByHuman())
|
||||
{
|
||||
if(humanActivate)
|
||||
activated(h);
|
||||
activated(gameEvents, h);
|
||||
}
|
||||
else if(computerActivate)
|
||||
activated(h);
|
||||
activated(gameEvents, h);
|
||||
}
|
||||
|
||||
void CGEvent::activated( const CGHeroInstance * h ) const
|
||||
void CGEvent::activated(IGameEventCallback & gameEvents, const CGHeroInstance * h ) const
|
||||
{
|
||||
if(stacksCount() > 0)
|
||||
{
|
||||
@@ -316,12 +317,12 @@ void CGEvent::activated( const CGHeroInstance * h ) const
|
||||
iw.text = message;
|
||||
else
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 16);
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->startBattle(h, this);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
gameEvents.startBattle(h, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
CRewardableObject::onHeroVisit(h);
|
||||
CRewardableObject::onHeroVisit(gameEvents, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,9 +24,9 @@ public:
|
||||
MetaString message;
|
||||
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
h & message;
|
||||
}
|
||||
protected:
|
||||
void grantRewardWithMessage(const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const override;
|
||||
void grantRewardWithMessage(IGameEventCallback & gameEvents, const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const override;
|
||||
|
||||
virtual void init();
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
@@ -59,14 +59,14 @@ public:
|
||||
h & humanActivate;
|
||||
}
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
protected:
|
||||
void grantRewardWithMessage(const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const override;
|
||||
void grantRewardWithMessage(IGameEventCallback & gameEvents, const CGHeroInstance * contextHero, int rewardIndex, bool markAsVisit) const override;
|
||||
|
||||
void init() override;
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
private:
|
||||
void activated(const CGHeroInstance * h) const;
|
||||
void activated(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -11,7 +11,8 @@
|
||||
#include "StdInc.h"
|
||||
#include "CGResource.h"
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../mapObjectConstructors/CommonConstructors.h"
|
||||
#include "../texts/CGeneralTextHandler.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
@@ -71,7 +72,7 @@ void CGResource::initObj(vstd::RNG & rand)
|
||||
getResourceHandler()->randomizeObject(this, rand);
|
||||
}
|
||||
|
||||
void CGResource::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGResource::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(stacksCount())
|
||||
{
|
||||
@@ -80,20 +81,20 @@ void CGResource::onHeroVisit( const CGHeroInstance * h ) const
|
||||
BlockingDialog ynd(true,false);
|
||||
ynd.player = h->getOwner();
|
||||
ynd.text = message;
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
}
|
||||
else
|
||||
{
|
||||
blockingDialogAnswered(h, true); //behave as if player accepted battle
|
||||
blockingDialogAnswered(gameEvents, h, true); //behave as if player accepted battle
|
||||
}
|
||||
}
|
||||
else
|
||||
collectRes(h->getOwner());
|
||||
collectRes(gameEvents, h->getOwner());
|
||||
}
|
||||
|
||||
void CGResource::collectRes(const PlayerColor & player) const
|
||||
void CGResource::collectRes(IGameEventCallback & gameEvents, const PlayerColor & player) const
|
||||
{
|
||||
cb->giveResource(player, resourceID(), amount);
|
||||
gameEvents.giveResource(player, resourceID(), amount);
|
||||
InfoWindow sii;
|
||||
sii.player = player;
|
||||
if(!message.empty())
|
||||
@@ -108,21 +109,21 @@ void CGResource::collectRes(const PlayerColor & player) const
|
||||
sii.text.replaceName(resourceID());
|
||||
}
|
||||
sii.components.emplace_back(ComponentType::RESOURCE, resourceID(), amount);
|
||||
sii.soundID = soundBase::pickup01 + cb->gameState().getRandomGenerator().nextInt(6);
|
||||
cb->showInfoDialog(&sii);
|
||||
cb->removeObject(this, player);
|
||||
sii.soundID = soundBase::pickup01 + gameEvents.getRandomGenerator().nextInt(6);
|
||||
gameEvents.showInfoDialog(&sii);
|
||||
gameEvents.removeObject(this, player);
|
||||
}
|
||||
|
||||
void CGResource::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGResource::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if(result.winner == BattleSide::ATTACKER) //attacker won
|
||||
collectRes(hero->getOwner());
|
||||
collectRes(gameEvents, hero->getOwner());
|
||||
}
|
||||
|
||||
void CGResource::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGResource::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
if(answer)
|
||||
cb->startBattle(hero, this);
|
||||
gameEvents.startBattle(hero, this);
|
||||
}
|
||||
|
||||
void CGResource::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
|
@@ -28,17 +28,17 @@ class DLL_LINKAGE CGResource : public CArmedInstance
|
||||
|
||||
std::shared_ptr<ResourceInstanceConstructor> getResourceHandler() const;
|
||||
int getAmountMultiplier() const;
|
||||
void collectRes(const PlayerColor & player) const;
|
||||
void collectRes(IGameEventCallback & gameEvents, const PlayerColor & player) const;
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
|
||||
public:
|
||||
using CArmedInstance::CArmedInstance;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
std::string getHoverText(PlayerColor player) const override;
|
||||
|
||||
GameResID resourceID() const;
|
||||
|
@@ -24,7 +24,8 @@
|
||||
#include "../CPlayerState.h"
|
||||
#include "../StartInfo.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../entities/building/CBuilding.h"
|
||||
#include "../entities/faction/CTownHandler.h"
|
||||
#include "../mapObjectConstructors/AObjectTypeHandler.h"
|
||||
@@ -263,7 +264,7 @@ TownFortifications CGTownInstance::fortificationsLevel() const
|
||||
return result;
|
||||
}
|
||||
|
||||
CGTownInstance::CGTownInstance(IGameCallback *cb):
|
||||
CGTownInstance::CGTownInstance(IGameInfoCallback *cb):
|
||||
CGDwelling(cb),
|
||||
IMarket(cb),
|
||||
built(0),
|
||||
@@ -297,13 +298,13 @@ bool CGTownInstance::needsLastStack() const
|
||||
return getGarrisonHero() != nullptr;
|
||||
}
|
||||
|
||||
void CGTownInstance::setOwner(const PlayerColor & player) const
|
||||
void CGTownInstance::setOwner(IGameEventCallback & gameEvents, const PlayerColor & player) const
|
||||
{
|
||||
removeCapitols(player);
|
||||
cb->setOwner(this, player);
|
||||
removeCapitols(gameEvents, player);
|
||||
gameEvents.setOwner(this, player);
|
||||
}
|
||||
|
||||
void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGTownInstance::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(cb->gameState().getPlayerRelations( getOwner(), h->getOwner() ) == PlayerRelations::ENEMIES)
|
||||
{
|
||||
@@ -319,23 +320,23 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
auto * nodeSiege = defendingHero->whereShouldBeAttachedOnSiege(isBattleOutside);
|
||||
|
||||
if(nodeSiege == (CBonusSystemNode *)this)
|
||||
cb->swapGarrisonOnSiege(this->id);
|
||||
gameEvents.swapGarrisonOnSiege(this->id);
|
||||
|
||||
const_cast<CGHeroInstance *>(defendingHero)->setVisitedTown(this, false); //hack to return visitor from garrison after battle
|
||||
}
|
||||
cb->startBattle(h, defendingArmy, getSightCenter(), h, defendingHero, BattleLayout::createDefaultLayout(cb, h, defendingArmy), (isBattleOutside ? nullptr : this));
|
||||
gameEvents.startBattle(h, defendingArmy, getSightCenter(), h, defendingHero, BattleLayout::createDefaultLayout(cb, h, defendingArmy), (isBattleOutside ? nullptr : this));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto heroColor = h->getOwner();
|
||||
onTownCaptured(heroColor);
|
||||
onTownCaptured(gameEvents, heroColor);
|
||||
|
||||
if(cb->gameState().getPlayerStatus(heroColor) == EPlayerStatus::WINNER)
|
||||
{
|
||||
return; //we just won game, we do not need to perform any extra actions
|
||||
//TODO: check how does H3 behave, visiting town on victory can affect campaigns (spells learned, +1 stat building visited)
|
||||
}
|
||||
cb->heroVisitCastle(this, h);
|
||||
gameEvents.heroVisitCastle(this, h);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -348,9 +349,9 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
scp.heroid = h->id;
|
||||
scp.which = SetCommanderProperty::ALIVE;
|
||||
scp.amount = 1;
|
||||
cb->sendAndApply(scp);
|
||||
gameEvents.sendAndApply(scp);
|
||||
}
|
||||
cb->heroVisitCastle(this, h);
|
||||
gameEvents.heroVisitCastle(this, h);
|
||||
// TODO(vmarkovtsev): implement payment for rising the commander
|
||||
if (commander_recover) // info window about commander
|
||||
{
|
||||
@@ -358,17 +359,17 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendRawString(h->getCommander()->getName());
|
||||
iw.components.emplace_back(ComponentType::CREATURE, h->getCommander()->getId(), h->getCommander()->getCount());
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
|
||||
void CGTownInstance::onHeroLeave(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
//FIXME: find out why this issue appears on random maps
|
||||
if(getVisitingHero() == h)
|
||||
{
|
||||
cb->stopHeroVisitCastle(this, h);
|
||||
gameEvents.stopHeroVisitCastle(this, h);
|
||||
logGlobal->trace("%s correctly left town %s", h->getNameTranslated(), getNameTranslated());
|
||||
}
|
||||
else
|
||||
@@ -535,17 +536,17 @@ void CGTownInstance::initializeNeutralTownGarrison(vstd::RNG & rand)
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::newTurn(vstd::RNG & rand) const
|
||||
void CGTownInstance::newTurn(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
for(const auto & building : rewardableBuildings)
|
||||
building.second->newTurn(rand);
|
||||
building.second->newTurn(gameEvents);
|
||||
|
||||
if(hasBuilt(BuildingSubID::BANK) && bonusValue.second > 0)
|
||||
{
|
||||
TResources res;
|
||||
res[EGameResID::GOLD] = -500;
|
||||
cb->giveResources(getOwner(), res);
|
||||
cb->setObjPropertyValue(id, ObjProperty::BONUS_VALUE_SECOND, bonusValue.second - 500);
|
||||
gameEvents.giveResources(getOwner(), res);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::BONUS_VALUE_SECOND, bonusValue.second - 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +578,7 @@ const IObjectInterface * CGTownInstance::getObject() const
|
||||
return this;
|
||||
}
|
||||
|
||||
void CGTownInstance::mergeGarrisonOnSiege() const
|
||||
void CGTownInstance::mergeGarrisonOnSiege(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
auto getWeakestStackSlot = [&](ui64 powerLimit)
|
||||
{
|
||||
@@ -610,17 +611,17 @@ void CGTownInstance::mergeGarrisonOnSiege() const
|
||||
});
|
||||
auto dst = getVisitingHero()->getSlotFor(pair.second->getCreatureID());
|
||||
if(dst.validSlot())
|
||||
cb->moveStack(StackLocation(id, pair.first), StackLocation(getVisitingHero()->id, dst), -1);
|
||||
gameEvents.moveStack(StackLocation(id, pair.first), StackLocation(getVisitingHero()->id, dst), -1);
|
||||
else
|
||||
{
|
||||
dst = getWeakestStackSlot(static_cast<int>(pair.second->getPower()));
|
||||
if(dst.validSlot())
|
||||
cb->swapStacks(StackLocation(id, pair.first), StackLocation(getVisitingHero()->id, dst));
|
||||
gameEvents.swapStacks(StackLocation(id, pair.first), StackLocation(getVisitingHero()->id, dst));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::removeCapitols(const PlayerColor & owner) const
|
||||
void CGTownInstance::removeCapitols(IGameEventCallback & gameEvents, const PlayerColor & owner) const
|
||||
{
|
||||
if (hasCapitol()) // search if there's an older capitol
|
||||
{
|
||||
@@ -633,18 +634,18 @@ void CGTownInstance::removeCapitols(const PlayerColor & owner) const
|
||||
rs.tid = id;
|
||||
rs.bid.insert(BuildingID::CAPITOL);
|
||||
rs.destroyed = destroyed;
|
||||
cb->sendAndApply(rs);
|
||||
gameEvents.sendAndApply(rs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::clearArmy() const
|
||||
void CGTownInstance::clearArmy(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
while(!stacks.empty())
|
||||
{
|
||||
cb->eraseStack(StackLocation(id, stacks.begin()->first), true);
|
||||
gameEvents.eraseStack(StackLocation(id, stacks.begin()->first), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,12 +1000,12 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGTownInstance::addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID ) const
|
||||
void CGTownInstance::addHeroToStructureVisitors(IGameEventCallback & gameEvents, const CGHeroInstance *h, si64 structureInstanceID ) const
|
||||
{
|
||||
if(getVisitingHero() == h)
|
||||
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_VISITING_HERO, structureInstanceID); //add to visitors
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_VISITING_HERO, structureInstanceID); //add to visitors
|
||||
else if(getGarrisonHero() == h)
|
||||
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_GARRISONED_HERO, structureInstanceID); //then it must be garrisoned hero
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_GARRISONED_HERO, structureInstanceID); //then it must be garrisoned hero
|
||||
else
|
||||
{
|
||||
//should never ever happen
|
||||
@@ -1013,19 +1014,19 @@ void CGTownInstance::addHeroToStructureVisitors(const CGHeroInstance *h, si64 st
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::battleFinished(const CGHeroInstance * hero, const BattleResult & result) const
|
||||
void CGTownInstance::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance * hero, const BattleResult & result) const
|
||||
{
|
||||
if(result.winner == BattleSide::ATTACKER)
|
||||
{
|
||||
clearArmy();
|
||||
onTownCaptured(hero->getOwner());
|
||||
clearArmy(gameEvents);
|
||||
onTownCaptured(gameEvents, hero->getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::onTownCaptured(const PlayerColor & winner) const
|
||||
void CGTownInstance::onTownCaptured(IGameEventCallback & gameEvents, const PlayerColor & winner) const
|
||||
{
|
||||
setOwner(winner);
|
||||
cb->changeFogOfWar(getSightCenter(), getSightRadius(), winner, ETileVisibility::REVEALED);
|
||||
setOwner(gameEvents, winner);
|
||||
gameEvents.changeFogOfWar(getSightCenter(), getSightRadius(), winner, ETileVisibility::REVEALED);
|
||||
}
|
||||
|
||||
void CGTownInstance::afterAddToMap(CMap * map)
|
||||
|
@@ -183,10 +183,10 @@ public:
|
||||
|
||||
LogicalExpression<BuildingID> genBuildingRequirements(const BuildingID & build, bool deep = false) const;
|
||||
|
||||
void mergeGarrisonOnSiege() const; // merge garrison into army of visiting hero
|
||||
void removeCapitols(const PlayerColor & owner) const;
|
||||
void clearArmy() const;
|
||||
void addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID) const; //hero must be visiting or garrisoned in town
|
||||
void mergeGarrisonOnSiege(IGameEventCallback & gameEvents) const; // merge garrison into army of visiting hero
|
||||
void removeCapitols(IGameEventCallback & gameEvents, const PlayerColor & owner) const;
|
||||
void clearArmy(IGameEventCallback & gameEvents) const;
|
||||
void addHeroToStructureVisitors(IGameEventCallback & gameEvents, const CGHeroInstance *h, si64 structureInstanceID) const; //hero must be visiting or garrisoned in town
|
||||
void deleteTownBonus(BuildingID bid);
|
||||
|
||||
/// Returns damage range for secondary towers of this town
|
||||
@@ -207,16 +207,16 @@ public:
|
||||
/// Returns true if provided war machine is available in any of built buildings of this town
|
||||
bool isWarMachineAvailable(ArtifactID) const;
|
||||
|
||||
CGTownInstance(IGameCallback *cb);
|
||||
CGTownInstance(IGameInfoCallback *cb);
|
||||
virtual ~CGTownInstance();
|
||||
|
||||
///IObjectInterface overrides
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroLeave(const CGHeroInstance * h) const override;
|
||||
void newTurn(IGameEventCallback & gameEvents) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void onHeroLeave(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
void battleFinished(const CGHeroInstance * hero, const BattleResult & result) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance * hero, const BattleResult & result) const override;
|
||||
std::string getObjectName() const override;
|
||||
|
||||
void fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const override;
|
||||
@@ -234,8 +234,8 @@ protected:
|
||||
|
||||
private:
|
||||
FactionID randomizeFaction(vstd::RNG & rand);
|
||||
void setOwner(const PlayerColor & owner) const;
|
||||
void onTownCaptured(const PlayerColor & winner) const;
|
||||
void setOwner(IGameEventCallback & gameEvents, const PlayerColor & owner) const;
|
||||
void onTownCaptured(IGameEventCallback & gameEvents, const PlayerColor & winner) const;
|
||||
int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<const CGObjectInstance* >& dwellings) const;
|
||||
bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
|
||||
void initializeConfigurableBuildings(vstd::RNG & rand);
|
||||
|
@@ -17,7 +17,8 @@
|
||||
#include "../texts/CGeneralTextHandler.h"
|
||||
#include "CGCreature.h"
|
||||
#include "../IGameSettings.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../entities/artifact/CArtifact.h"
|
||||
#include "../entities/hero/CHeroHandler.h"
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
@@ -119,7 +120,7 @@ bool CQuest::checkQuest(const CGHeroInstance * h) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h, bool allowFullArmyRemoval) const
|
||||
void CQuest::completeQuest(IGameEventCallback & gameEvents, const CGHeroInstance *h, bool allowFullArmyRemoval) const
|
||||
{
|
||||
// FIXME: this should be part of 'reward', and not hacking into limiter state that should only limit access to such reward
|
||||
|
||||
@@ -127,7 +128,7 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h, bool all
|
||||
{
|
||||
if(h->hasArt(elem))
|
||||
{
|
||||
cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(elem, false)));
|
||||
gameEvents.removeArtifact(ArtifactLocation(h->id, h->getArtPos(elem, false)));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -138,13 +139,13 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h, bool all
|
||||
auto parts = assembly->getPartsInfo();
|
||||
|
||||
// Remove the assembly
|
||||
cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(assembly)));
|
||||
gameEvents.removeArtifact(ArtifactLocation(h->id, h->getArtPos(assembly)));
|
||||
|
||||
// Disassemble this backpack artifact
|
||||
for(const auto & ci : parts)
|
||||
{
|
||||
if(ci.getArtifact()->getTypeId() != elem)
|
||||
cb->giveHeroNewArtifact(h, ci.getArtifact()->getTypeId(), ArtifactPosition::BACKPACK_START);
|
||||
gameEvents.giveHeroNewArtifact(h, ci.getArtifact()->getTypeId(), ArtifactPosition::BACKPACK_START);
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -153,11 +154,11 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h, bool all
|
||||
logGlobal->error("Failed to find artifact %s in inventory of hero %s", elem.toEntity(LIBRARY)->getJsonKey(), h->getHeroTypeID());
|
||||
}
|
||||
|
||||
cb->takeCreatures(h->id, mission.creatures, allowFullArmyRemoval);
|
||||
cb->giveResources(h->getOwner(), -mission.resources);
|
||||
gameEvents.takeCreatures(h->id, mission.creatures, allowFullArmyRemoval);
|
||||
gameEvents.giveResources(h->getOwner(), -mission.resources);
|
||||
}
|
||||
|
||||
void CQuest::addTextReplacements(const CGameInfoCallback * cb, MetaString & text, std::vector<Component> & components) const
|
||||
void CQuest::addTextReplacements(const IGameInfoCallback * cb, MetaString & text, std::vector<Component> & components) const
|
||||
{
|
||||
if(mission.heroLevel > 0)
|
||||
text.replaceNumber(mission.heroLevel);
|
||||
@@ -256,7 +257,7 @@ void CQuest::addTextReplacements(const CGameInfoCallback * cb, MetaString & text
|
||||
text.replaceNumber(lastDay - cb->getDate(Date::DAY));
|
||||
}
|
||||
|
||||
void CQuest::getVisitText(const CGameInfoCallback * cb, MetaString &iwText, std::vector<Component> &components, bool firstVisit, const CGHeroInstance * h) const
|
||||
void CQuest::getVisitText(const IGameInfoCallback * cb, MetaString &iwText, std::vector<Component> &components, bool firstVisit, const CGHeroInstance * h) const
|
||||
{
|
||||
bool failRequirements = (h ? !checkQuest(h) : true);
|
||||
mission.loadComponents(components, h);
|
||||
@@ -272,7 +273,7 @@ void CQuest::getVisitText(const CGameInfoCallback * cb, MetaString &iwText, std:
|
||||
addTextReplacements(cb, iwText, components);
|
||||
}
|
||||
|
||||
void CQuest::getRolloverText(const CGameInfoCallback * cb, MetaString &ms, bool onHover) const
|
||||
void CQuest::getRolloverText(const IGameInfoCallback * cb, MetaString &ms, bool onHover) const
|
||||
{
|
||||
if(onHover)
|
||||
ms.appendRawString("\n\n");
|
||||
@@ -285,7 +286,7 @@ void CQuest::getRolloverText(const CGameInfoCallback * cb, MetaString &ms, bool
|
||||
addTextReplacements(cb, ms, components);
|
||||
}
|
||||
|
||||
void CQuest::getCompletionText(const CGameInfoCallback * cb, MetaString &iwText) const
|
||||
void CQuest::getCompletionText(const IGameInfoCallback * cb, MetaString &iwText) const
|
||||
{
|
||||
iwText.appendRawString(completedText.toString());
|
||||
|
||||
@@ -550,16 +551,16 @@ void CGSeerHut::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
}
|
||||
}
|
||||
|
||||
void CGSeerHut::newTurn(vstd::RNG & rand) const
|
||||
void CGSeerHut::newTurn(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
CRewardableObject::newTurn(rand);
|
||||
CRewardableObject::newTurn(gameEvents);
|
||||
if(getQuest().lastDay >= 0 && getQuest().lastDay <= cb->getDate() - 1) //time is up
|
||||
{
|
||||
cb->setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, true);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGSeerHut::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
@@ -570,23 +571,23 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
if(firstVisit)
|
||||
{
|
||||
cb->setObjPropertyID(id, ObjProperty::SEERHUT_VISITED, h->getOwner());
|
||||
gameEvents.setObjPropertyID(id, ObjProperty::SEERHUT_VISITED, h->getOwner());
|
||||
|
||||
AddQuest aq;
|
||||
aq.quest = QuestInfo(id);
|
||||
aq.player = h->tempOwner;
|
||||
cb->sendAndApply(aq); //TODO: merge with setObjProperty?
|
||||
gameEvents.sendAndApply(aq); //TODO: merge with setObjProperty?
|
||||
}
|
||||
|
||||
if(firstVisit || failRequirements)
|
||||
{
|
||||
getVisitText (iw.text, iw.components, firstVisit, h);
|
||||
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
if(!failRequirements) // propose completion, also on first visit
|
||||
{
|
||||
CRewardableObject::onHeroVisit(h);
|
||||
CRewardableObject::onHeroVisit(gameEvents, h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -595,7 +596,7 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
||||
iw.text.appendRawString(LIBRARY->generaltexth->seerEmpty[getQuest().completedOption]);
|
||||
if (ID == Obj::SEER_HUT)
|
||||
iw.text.replaceRawString(seerName);
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,14 +655,14 @@ bool CGSeerHut::allowsFullArmyRemoval() const
|
||||
return seerGivesUnits || h3BugSettingEnabled;
|
||||
}
|
||||
|
||||
void CGSeerHut::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGSeerHut::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
if(answer)
|
||||
{
|
||||
getQuest().completeQuest(cb, hero, allowsFullArmyRemoval());
|
||||
cb->setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, !getQuest().repeatedQuest); //mission complete
|
||||
getQuest().completeQuest(gameEvents, hero, allowsFullArmyRemoval());
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, !getQuest().repeatedQuest); //mission complete
|
||||
}
|
||||
CRewardableObject::blockingDialogAnswered(hero, answer);
|
||||
CRewardableObject::blockingDialogAnswered(gameEvents, hero, answer);
|
||||
}
|
||||
|
||||
void CGSeerHut::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
@@ -753,12 +754,12 @@ void CGQuestGuard::init(vstd::RNG & rand)
|
||||
configuration.canRefuse = true;
|
||||
}
|
||||
|
||||
void CGQuestGuard::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGQuestGuard::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(!getQuest().isCompleted)
|
||||
CGSeerHut::onHeroVisit(h);
|
||||
CGSeerHut::onHeroVisit(gameEvents, h);
|
||||
else
|
||||
cb->setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, false);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::SEERHUT_COMPLETE, false);
|
||||
}
|
||||
|
||||
bool CGQuestGuard::passableFor(PlayerColor color) const
|
||||
@@ -797,7 +798,7 @@ bool CGKeymasterTent::wasVisited (PlayerColor player) const
|
||||
return wasMyColorVisited (player);
|
||||
}
|
||||
|
||||
void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGKeymasterTent::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
int txt_id;
|
||||
if (!wasMyColorVisited (h->getOwner()) )
|
||||
@@ -806,12 +807,12 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
cow.mode = ChangeObjectVisitors::VISITOR_ADD_PLAYER;
|
||||
cow.hero = h->id;
|
||||
cow.object = id;
|
||||
cb->sendAndApply(cow);
|
||||
gameEvents.sendAndApply(cow);
|
||||
txt_id=19;
|
||||
}
|
||||
else
|
||||
txt_id=20;
|
||||
h->showInfoDialog(txt_id);
|
||||
h->showInfoDialog(gameEvents, txt_id);
|
||||
}
|
||||
|
||||
void CGBorderGuard::initObj(vstd::RNG & rand)
|
||||
@@ -839,43 +840,43 @@ bool CGBorderGuard::checkQuest(const CGHeroInstance * h) const
|
||||
return wasMyColorVisited (h->tempOwner);
|
||||
}
|
||||
|
||||
void CGBorderGuard::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGBorderGuard::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if (wasMyColorVisited (h->getOwner()) )
|
||||
{
|
||||
BlockingDialog bd (true, false);
|
||||
bd.player = h->getOwner();
|
||||
bd.text.appendLocalString (EMetaText::ADVOB_TXT, 17);
|
||||
cb->showBlockingDialog (this, &bd);
|
||||
gameEvents.showBlockingDialog (this, &bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
h->showInfoDialog(18);
|
||||
h->showInfoDialog(gameEvents, 18);
|
||||
|
||||
AddQuest aq;
|
||||
aq.quest = QuestInfo(id);
|
||||
aq.player = h->tempOwner;
|
||||
cb->sendAndApply(aq);
|
||||
gameEvents.sendAndApply(aq);
|
||||
//TODO: add this quest only once OR check for multiple instances later
|
||||
}
|
||||
}
|
||||
|
||||
void CGBorderGuard::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGBorderGuard::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
if (answer)
|
||||
cb->removeObject(this, hero->getOwner());
|
||||
gameEvents.removeObject(this, hero->getOwner());
|
||||
}
|
||||
|
||||
void CGBorderGate::onHeroVisit(const CGHeroInstance * h) const //TODO: passability
|
||||
void CGBorderGate::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const //TODO: passability
|
||||
{
|
||||
if (!wasMyColorVisited (h->getOwner()) )
|
||||
{
|
||||
h->showInfoDialog(18);
|
||||
h->showInfoDialog(gameEvents, 18);
|
||||
|
||||
AddQuest aq;
|
||||
aq.quest = QuestInfo(id);
|
||||
aq.player = h->tempOwner;
|
||||
cb->sendAndApply(aq);
|
||||
gameEvents.sendAndApply(aq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -77,11 +77,11 @@ public:
|
||||
|
||||
static bool checkMissionArmy(const CQuest * q, const CCreatureSet * army);
|
||||
bool checkQuest(const CGHeroInstance * h) const; //determines whether the quest is complete or not
|
||||
void getVisitText(const CGameInfoCallback * cb, MetaString &text, std::vector<Component> & components, bool FirstVisit, const CGHeroInstance * h = nullptr) const;
|
||||
void getCompletionText(const CGameInfoCallback * cb, MetaString &text) const;
|
||||
void getRolloverText (const CGameInfoCallback * cb, MetaString &text, bool onHover) const; //hover or quest log entry
|
||||
void completeQuest(IGameCallback *, const CGHeroInstance * h, bool allowFullArmyRemoval) const;
|
||||
void addTextReplacements(const CGameInfoCallback * cb, MetaString &out, std::vector<Component> & components) const;
|
||||
void getVisitText(const IGameInfoCallback * cb, MetaString &text, std::vector<Component> & components, bool FirstVisit, const CGHeroInstance * h = nullptr) const;
|
||||
void getCompletionText(const IGameInfoCallback * cb, MetaString &text) const;
|
||||
void getRolloverText (const IGameInfoCallback * cb, MetaString &text, bool onHover) const; //hover or quest log entry
|
||||
void completeQuest(IGameEventCallback & gameEvents, const CGHeroInstance * h, bool allowFullArmyRemoval) const;
|
||||
void addTextReplacements(const IGameInfoCallback * cb, MetaString &out, std::vector<Component> & components) const;
|
||||
void addKillTargetReplacements(MetaString &out) const;
|
||||
void defineQuestName();
|
||||
|
||||
@@ -147,9 +147,9 @@ public:
|
||||
std::string getPopupText(const CGHeroInstance * hero) const override;
|
||||
std::vector<Component> getPopupComponents(PlayerColor player) const override;
|
||||
std::vector<Component> getPopupComponents(const CGHeroInstance * hero) const override;
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void newTurn(IGameEventCallback & gameEvents) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void getVisitText (MetaString &text, std::vector<Component> &components, bool FirstVisit, const CGHeroInstance * h = nullptr) const override;
|
||||
|
||||
virtual void init(vstd::RNG & rand);
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
|
||||
void init(vstd::RNG & rand) override;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
bool passableFor(PlayerColor color) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
using CGKeys::CGKeys;
|
||||
|
||||
bool wasVisited (PlayerColor player) const override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
@@ -228,8 +228,8 @@ public:
|
||||
using CGKeys::CGKeys;
|
||||
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
|
||||
void getVisitText (MetaString &text, std::vector<Component> &components, bool FirstVisit, const CGHeroInstance * h = nullptr) const override;
|
||||
void getRolloverText (MetaString &text, bool onHover) const;
|
||||
@@ -247,7 +247,7 @@ class DLL_LINKAGE CGBorderGate : public CGBorderGuard
|
||||
public:
|
||||
using CGBorderGuard::CGBorderGuard;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
|
||||
bool passableFor(PlayerColor color) const override;
|
||||
};
|
||||
|
@@ -14,7 +14,8 @@
|
||||
#include "../CPlayerState.h"
|
||||
#include "../IGameSettings.h"
|
||||
#include "../battle/BattleLayout.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "../mapObjectConstructors/CRewardableConstructor.h"
|
||||
@@ -33,10 +34,10 @@ const IObjectInterface * CRewardableObject::getObject() const
|
||||
return this;
|
||||
}
|
||||
|
||||
void CRewardableObject::markAsScouted(const CGHeroInstance * hero) const
|
||||
void CRewardableObject::markAsScouted(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, hero->id);
|
||||
cb->sendAndApply(cov);
|
||||
gameEvents.sendAndApply(cov);
|
||||
}
|
||||
|
||||
bool CRewardableObject::isGuarded() const
|
||||
@@ -44,21 +45,21 @@ bool CRewardableObject::isGuarded() const
|
||||
return stacksCount() > 0;
|
||||
}
|
||||
|
||||
void CRewardableObject::onHeroVisit(const CGHeroInstance *hero) const
|
||||
void CRewardableObject::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const
|
||||
{
|
||||
if(!wasScouted(hero->getOwner()))
|
||||
{
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_SCOUTED, id, hero->id);
|
||||
cb->sendAndApply(cov);
|
||||
gameEvents.sendAndApply(cov);
|
||||
}
|
||||
|
||||
if (!isGuarded())
|
||||
{
|
||||
doHeroVisit(hero);
|
||||
doHeroVisit(gameEvents, hero);
|
||||
}
|
||||
else if (configuration.forceCombat)
|
||||
{
|
||||
doStartBattle(hero);
|
||||
doStartBattle(gameEvents, hero);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -71,67 +72,67 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *hero) const
|
||||
bd.text = guardedReward.message;
|
||||
bd.components = getPopupComponents(hero->getOwner());
|
||||
|
||||
cb->showBlockingDialog(this, &bd);
|
||||
gameEvents.showBlockingDialog(this, &bd);
|
||||
}
|
||||
}
|
||||
|
||||
void CRewardableObject::heroLevelUpDone(const CGHeroInstance *hero) const
|
||||
void CRewardableObject::heroLevelUpDone(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const
|
||||
{
|
||||
grantRewardAfterLevelup(configuration.info.at(selectedReward), this, hero);
|
||||
grantRewardAfterLevelup(gameEvents, configuration.info.at(selectedReward), this, hero);
|
||||
}
|
||||
|
||||
void CRewardableObject::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CRewardableObject::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if (result.winner == BattleSide::ATTACKER)
|
||||
{
|
||||
doHeroVisit(hero);
|
||||
doHeroVisit(gameEvents, hero);
|
||||
}
|
||||
}
|
||||
|
||||
void CRewardableObject::garrisonDialogClosed(const CGHeroInstance *hero) const
|
||||
void CRewardableObject::garrisonDialogClosed(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const
|
||||
{
|
||||
// if visitor received creatures as rewards, but does not have free slots, he will leave some units
|
||||
// inside rewardable object, which might get treated as guards later
|
||||
while(!stacks.empty())
|
||||
cb->eraseStack(StackLocation(id, stacks.begin()->first));
|
||||
gameEvents.eraseStack(StackLocation(id, stacks.begin()->first));
|
||||
}
|
||||
|
||||
void CRewardableObject::doStartBattle(const CGHeroInstance * hero) const
|
||||
void CRewardableObject::doStartBattle(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const
|
||||
{
|
||||
auto layout = BattleLayout::createLayout(cb, configuration.guardsLayout, hero, this);
|
||||
cb->startBattle(hero, this, visitablePos(), hero, nullptr, layout, nullptr);
|
||||
gameEvents.startBattle(hero, this, visitablePos(), hero, nullptr, layout, nullptr);
|
||||
}
|
||||
|
||||
void CRewardableObject::blockingDialogAnswered(const CGHeroInstance * hero, int32_t answer) const
|
||||
void CRewardableObject::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance * hero, int32_t answer) const
|
||||
{
|
||||
if(isGuarded())
|
||||
{
|
||||
if (answer)
|
||||
doStartBattle(hero);
|
||||
doStartBattle(gameEvents, hero);
|
||||
}
|
||||
else
|
||||
{
|
||||
onBlockingDialogAnswered(hero, answer);
|
||||
onBlockingDialogAnswered(gameEvents, hero, answer);
|
||||
}
|
||||
}
|
||||
|
||||
void CRewardableObject::markAsVisited(const CGHeroInstance * hero) const
|
||||
void CRewardableObject::markAsVisited(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const
|
||||
{
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, true);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, true);
|
||||
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_HERO, id, hero->id);
|
||||
cb->sendAndApply(cov);
|
||||
gameEvents.sendAndApply(cov);
|
||||
}
|
||||
|
||||
void CRewardableObject::grantReward(ui32 rewardID, const CGHeroInstance * hero) const
|
||||
void CRewardableObject::grantReward(IGameEventCallback & gameEvents, ui32 rewardID, const CGHeroInstance * hero) const
|
||||
{
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_SELECT, rewardID);
|
||||
grantRewardBeforeLevelup(configuration.info.at(rewardID), hero);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::REWARD_SELECT, rewardID);
|
||||
grantRewardBeforeLevelup(gameEvents, configuration.info.at(rewardID), hero);
|
||||
|
||||
// hero is not blocked by levelup dialog - grant remainder immediately
|
||||
if(!cb->isVisitCoveredByAnotherQuery(this, hero))
|
||||
if(!gameEvents.isVisitCoveredByAnotherQuery(this, hero))
|
||||
{
|
||||
grantRewardAfterLevelup(configuration.info.at(rewardID), this, hero);
|
||||
grantRewardAfterLevelup(gameEvents, configuration.info.at(rewardID), this, hero);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,21 +331,21 @@ void CRewardableObject::setPropertyDer(ObjProperty what, ObjPropertyID identifie
|
||||
}
|
||||
}
|
||||
|
||||
void CRewardableObject::newTurn(vstd::RNG & rand) const
|
||||
void CRewardableObject::newTurn(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
if (configuration.resetParameters.period != 0 && cb->getDate(Date::DAY) > 1 && ((cb->getDate(Date::DAY)-1) % configuration.resetParameters.period) == 0)
|
||||
{
|
||||
if (configuration.resetParameters.rewards)
|
||||
{
|
||||
auto handler = std::dynamic_pointer_cast<const CRewardableConstructor>(getObjectHandler());
|
||||
auto newConfiguration = handler->generateConfiguration(cb, rand, ID, configuration.variables.preset);
|
||||
cb->setRewardableObjectConfiguration(id, newConfiguration);
|
||||
auto newConfiguration = handler->generateConfiguration(cb, gameEvents.getRandomGenerator(), ID, configuration.variables.preset);
|
||||
gameEvents.setRewardableObjectConfiguration(id, newConfiguration);
|
||||
}
|
||||
if (configuration.resetParameters.visitors)
|
||||
{
|
||||
cb->setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, false);
|
||||
gameEvents.setObjPropertyValue(id, ObjProperty::REWARD_CLEARED, false);
|
||||
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_CLEAR, id);
|
||||
cb->sendAndApply(cov);
|
||||
gameEvents.sendAndApply(cov);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +355,7 @@ void CRewardableObject::initObj(vstd::RNG & rand)
|
||||
getObjectHandler()->configureObject(this, rand);
|
||||
}
|
||||
|
||||
CRewardableObject::CRewardableObject(IGameCallback *cb)
|
||||
CRewardableObject::CRewardableObject(IGameInfoCallback *cb)
|
||||
:CArmedInstance(cb)
|
||||
{}
|
||||
|
||||
|
@@ -25,13 +25,13 @@ protected:
|
||||
/// reward selected by player, no serialize
|
||||
ui16 selectedReward = 0;
|
||||
|
||||
void doStartBattle(const CGHeroInstance * hero) const;
|
||||
void doStartBattle(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const;
|
||||
|
||||
void grantReward(ui32 rewardID, const CGHeroInstance * hero) const override;
|
||||
void markAsVisited(const CGHeroInstance * hero) const override;
|
||||
void grantReward(IGameEventCallback & gameEvents, ui32 rewardID, const CGHeroInstance * hero) const override;
|
||||
void markAsVisited(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const override;
|
||||
|
||||
const IObjectInterface * getObject() const override;
|
||||
void markAsScouted(const CGHeroInstance * hero) const override;
|
||||
void markAsScouted(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const override;
|
||||
|
||||
/// return true if this object was "cleared" before and no longer has rewards applicable to selected hero
|
||||
/// unlike wasVisited, this method uses information not available to player owner, for example, if object was cleared by another player before
|
||||
@@ -55,19 +55,19 @@ public:
|
||||
bool wasScouted(PlayerColor player) const;
|
||||
|
||||
/// gives reward to player or ask for choice in case of multiple rewards
|
||||
void onHeroVisit(const CGHeroInstance *h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance *h) const override;
|
||||
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void garrisonDialogClosed(const CGHeroInstance *hero) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void garrisonDialogClosed(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const override;
|
||||
|
||||
///possibly resets object state
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void newTurn(IGameEventCallback & gameEvents) const override;
|
||||
|
||||
/// gives second part of reward after hero level-ups for proper granting of spells/mana
|
||||
void heroLevelUpDone(const CGHeroInstance *hero) const override;
|
||||
void heroLevelUpDone(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const override;
|
||||
|
||||
/// applies player selection of reward
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
|
||||
CRewardableObject(IGameCallback *cb);
|
||||
CRewardableObject(IGameInfoCallback *cb);
|
||||
|
||||
std::string getHoverText(PlayerColor player) const override;
|
||||
std::string getHoverText(const CGHeroInstance * hero) const override;
|
||||
|
@@ -12,10 +12,13 @@
|
||||
#include "FlaggableMapObject.h"
|
||||
|
||||
#include "CGHeroInstance.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
|
||||
#include "../CPlayerState.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
#include "../mapObjectConstructors/FlaggableInstanceConstructor.h"
|
||||
#include "../gameState/GameStatePackVisitor.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@@ -34,37 +37,22 @@ std::vector<CreatureID> FlaggableMapObject::providedCreatures() const
|
||||
return {};
|
||||
}
|
||||
|
||||
void FlaggableMapObject::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void FlaggableMapObject::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if (cb->getPlayerRelations(h->getOwner(), getOwner()) != PlayerRelations::ENEMIES)
|
||||
return; // H3 behavior - revisiting owned Lighthouse is a no-op
|
||||
|
||||
if (getOwner().isValidPlayer())
|
||||
takeBonusFrom(getOwner());
|
||||
|
||||
cb->setOwner(this, h->getOwner()); //not ours? flag it!
|
||||
gameEvents.setOwner(this, h->getOwner()); //not ours? flag it!
|
||||
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
iw.text.appendTextID(getFlaggableHandler()->getVisitMessageTextID());
|
||||
cb->showInfoDialog(&iw);
|
||||
|
||||
giveBonusTo(h->getOwner());
|
||||
}
|
||||
|
||||
void FlaggableMapObject::markAsDeleted() const
|
||||
{
|
||||
if(getOwner().isValidPlayer())
|
||||
takeBonusFrom(getOwner());
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
void FlaggableMapObject::initObj(vstd::RNG & rand)
|
||||
{
|
||||
if(getOwner().isValidPlayer())
|
||||
{
|
||||
// FIXME: This is dirty hack
|
||||
giveBonusTo(getOwner(), true);
|
||||
}
|
||||
initBonuses();
|
||||
}
|
||||
|
||||
std::shared_ptr<FlaggableInstanceConstructor> FlaggableMapObject::getFlaggableHandler() const
|
||||
@@ -72,39 +60,10 @@ std::shared_ptr<FlaggableInstanceConstructor> FlaggableMapObject::getFlaggableHa
|
||||
return std::dynamic_pointer_cast<FlaggableInstanceConstructor>(getObjectHandler());
|
||||
}
|
||||
|
||||
void FlaggableMapObject::giveBonusTo(const PlayerColor & player, bool onInit) const
|
||||
void FlaggableMapObject::initBonuses()
|
||||
{
|
||||
for (auto const & bonus : getFlaggableHandler()->getProvidedBonuses())
|
||||
{
|
||||
GiveBonus gb(GiveBonus::ETarget::PLAYER);
|
||||
gb.id = player;
|
||||
gb.bonus = *bonus;
|
||||
|
||||
// FIXME: better place for this code?
|
||||
gb.bonus.duration = BonusDuration::PERMANENT;
|
||||
gb.bonus.source = BonusSource::OBJECT_INSTANCE;
|
||||
gb.bonus.sid = BonusSourceID(id);
|
||||
|
||||
// FIXME: This is really dirty hack
|
||||
// Proper fix would be to make FlaggableMapObject into bonus system node
|
||||
// Unfortunately this will cause saves breakage
|
||||
if(onInit)
|
||||
{
|
||||
GameStatePackVisitor visitor(cb->gameState());
|
||||
gb.visit(visitor);
|
||||
}
|
||||
else
|
||||
cb->sendAndApply(gb);
|
||||
}
|
||||
}
|
||||
|
||||
void FlaggableMapObject::takeBonusFrom(const PlayerColor & player) const
|
||||
{
|
||||
RemoveBonus rb(GiveBonus::ETarget::PLAYER);
|
||||
rb.whoID = player;
|
||||
rb.source = BonusSource::OBJECT_INSTANCE;
|
||||
rb.id = BonusSourceID(id);
|
||||
cb->sendAndApply(rb);
|
||||
addNewBonus(bonus);
|
||||
}
|
||||
|
||||
void FlaggableMapObject::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
@@ -112,4 +71,21 @@ void FlaggableMapObject::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
serializeJsonOwner(handler);
|
||||
}
|
||||
|
||||
void FlaggableMapObject::attachToBonusSystem(CGameState & gs)
|
||||
{
|
||||
if (getOwner().isValidPlayer())
|
||||
attachTo(*gs.getPlayerState(getOwner()));
|
||||
}
|
||||
|
||||
void FlaggableMapObject::detachFromBonusSystem(CGameState & gs)
|
||||
{
|
||||
if (getOwner().isValidPlayer())
|
||||
detachFrom(*gs.getPlayerState(getOwner()));
|
||||
}
|
||||
|
||||
void FlaggableMapObject::restoreBonusSystem(CGameState & gs)
|
||||
{
|
||||
attachToBonusSystem(gs);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -11,32 +11,49 @@
|
||||
|
||||
#include "CGObjectInstance.h"
|
||||
#include "IOwnableObject.h"
|
||||
#include "../bonuses/CBonusSystemNode.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct Bonus;
|
||||
class FlaggableInstanceConstructor;
|
||||
|
||||
class DLL_LINKAGE FlaggableMapObject : public CGObjectInstance, public IOwnableObject
|
||||
class DLL_LINKAGE FlaggableMapObject final : public CGObjectInstance, public IOwnableObject, public CBonusSystemNode
|
||||
{
|
||||
std::shared_ptr<FlaggableInstanceConstructor> getFlaggableHandler() const;
|
||||
|
||||
void giveBonusTo(const PlayerColor & player, bool onInit = false) const;
|
||||
void takeBonusFrom(const PlayerColor & player) const;
|
||||
void initBonuses();
|
||||
|
||||
public:
|
||||
using CGObjectInstance::CGObjectInstance;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void markAsDeleted() const;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
ResourceSet dailyIncome() const override;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
|
||||
protected:
|
||||
void attachToBonusSystem(CGameState & gs) override;
|
||||
void detachFromBonusSystem(CGameState & gs) override;
|
||||
void restoreBonusSystem(CGameState & gs) override;
|
||||
|
||||
PlayerColor getOwner() const override
|
||||
{
|
||||
return CGObjectInstance::getOwner();
|
||||
}
|
||||
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
|
||||
if (h.version >= Handler::Version::FLAGGABLE_BONUS_SYSTEM_NODE)
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
else
|
||||
initBonuses();
|
||||
}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@@ -140,7 +140,7 @@ int IMarket::availableUnits(const EMarketMode mode, const int marketItemSerial)
|
||||
}
|
||||
}
|
||||
|
||||
IMarket::IMarket(IGameCallback *cb)
|
||||
IMarket::IMarket(IGameInfoCallback *cb)
|
||||
:altarArtifactsStorage(std::make_unique<CArtifactSetAltar>(cb))
|
||||
{
|
||||
}
|
||||
|
@@ -18,19 +18,19 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class DLL_LINKAGE IMarket : public virtual Serializeable, boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit IMarket(IGameCallback *cb);
|
||||
explicit IMarket(IGameInfoCallback *cb);
|
||||
~IMarket();
|
||||
|
||||
class CArtifactSetAltar : public CArtifactSet
|
||||
{
|
||||
IGameCallback *cb;
|
||||
IGameInfoCallback *cb;
|
||||
public:
|
||||
CArtifactSetAltar(IGameCallback *cb)
|
||||
CArtifactSetAltar(IGameInfoCallback *cb)
|
||||
: CArtifactSet(cb)
|
||||
, cb(cb)
|
||||
{}
|
||||
|
||||
IGameCallback * getCallback() const override {return cb;};
|
||||
IGameInfoCallback * getCallback() const override {return cb;};
|
||||
ArtBearer bearerType() const override {return ArtBearer::ALTAR;};
|
||||
};
|
||||
|
||||
|
@@ -15,30 +15,31 @@
|
||||
#include "MiscObjects.h"
|
||||
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../networkPacks/PacksForClient.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
void IObjectInterface::showInfoDialog(const ui32 txtID, const ui16 soundID, EInfoWindowMode mode) const
|
||||
void IObjectInterface::showInfoDialog(IGameEventCallback & gameEvents, const ui32 txtID, const ui16 soundID, EInfoWindowMode mode) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.soundID = soundID;
|
||||
iw.player = getOwner();
|
||||
iw.type = mode;
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT,txtID);
|
||||
cb->sendAndApply(iw);
|
||||
gameEvents.sendAndApply(iw);
|
||||
}
|
||||
|
||||
///IObjectInterface
|
||||
void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
|
||||
void IObjectInterface::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{}
|
||||
|
||||
void IObjectInterface::onHeroLeave(const CGHeroInstance * h) const
|
||||
void IObjectInterface::onHeroLeave(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{}
|
||||
|
||||
void IObjectInterface::newTurn(vstd::RNG & rand) const
|
||||
void IObjectInterface::newTurn(IGameEventCallback & gameEvents) const
|
||||
{}
|
||||
|
||||
void IObjectInterface::initObj(vstd::RNG & rand)
|
||||
@@ -65,16 +66,16 @@ void IObjectInterface::postInit()
|
||||
void IObjectInterface::preInit()
|
||||
{}
|
||||
|
||||
void IObjectInterface::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void IObjectInterface::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{}
|
||||
|
||||
void IObjectInterface::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void IObjectInterface::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{}
|
||||
|
||||
void IObjectInterface::garrisonDialogClosed(const CGHeroInstance *hero) const
|
||||
void IObjectInterface::garrisonDialogClosed(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const
|
||||
{}
|
||||
|
||||
void IObjectInterface::heroLevelUpDone(const CGHeroInstance *hero) const
|
||||
void IObjectInterface::heroLevelUpDone(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const
|
||||
{}
|
||||
|
||||
int3 IBoatGenerator::bestLocation() const
|
||||
|
@@ -28,7 +28,8 @@ class BoatId;
|
||||
class CGObjectInstance;
|
||||
class CStackInstance;
|
||||
class CGHeroInstance;
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
class IGameEventCallback;
|
||||
class ResourceSet;
|
||||
class int3;
|
||||
class MetaString;
|
||||
@@ -49,25 +50,25 @@ public:
|
||||
virtual int3 visitablePos() const = 0;
|
||||
virtual int3 anchorPos() const = 0;
|
||||
|
||||
virtual void onHeroVisit(const CGHeroInstance * h) const;
|
||||
virtual void onHeroLeave(const CGHeroInstance * h) const;
|
||||
virtual void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
virtual void onHeroLeave(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
|
||||
/// Called on new turn by server. This method can not modify object state on its own
|
||||
/// Instead all changes must be propagated via netpacks
|
||||
virtual void newTurn(vstd::RNG & rand) const;
|
||||
virtual void newTurn(IGameEventCallback & gameEvents) const;
|
||||
virtual void initObj(vstd::RNG & rand); //synchr
|
||||
virtual void pickRandomObject(vstd::RNG & rand);
|
||||
virtual void setProperty(ObjProperty what, ObjPropertyID identifier);//synchr
|
||||
|
||||
//Called when queries created DURING HERO VISIT are resolved
|
||||
//First parameter is always hero that visited object and triggered the query
|
||||
virtual void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const;
|
||||
virtual void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const;
|
||||
virtual void garrisonDialogClosed(const CGHeroInstance *hero) const;
|
||||
virtual void heroLevelUpDone(const CGHeroInstance *hero) const;
|
||||
virtual void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const;
|
||||
virtual void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const;
|
||||
virtual void garrisonDialogClosed(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const;
|
||||
virtual void heroLevelUpDone(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const;
|
||||
|
||||
//unified helper to show info dialog for object owner
|
||||
virtual void showInfoDialog(const ui32 txtID, const ui16 soundID = 0, EInfoWindowMode mode = EInfoWindowMode::AUTO) const;
|
||||
virtual void showInfoDialog(IGameEventCallback & gameEvents, const ui32 txtID, const ui16 soundID = 0, EInfoWindowMode mode = EInfoWindowMode::AUTO) const;
|
||||
|
||||
virtual const IOwnableObject * asOwnable() const = 0;
|
||||
|
||||
|
@@ -12,7 +12,8 @@
|
||||
#include "MiscObjects.h"
|
||||
|
||||
#include "../bonuses/Propagators.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../constants/StringConstants.h"
|
||||
#include "../entities/artifact/ArtifactUtils.h"
|
||||
#include "../entities/artifact/CArtifact.h"
|
||||
@@ -73,13 +74,13 @@ bool CTeamVisited::wasVisited(const TeamID & team) const
|
||||
}
|
||||
|
||||
//CGMine
|
||||
void CGMine::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGMine::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
auto relations = cb->gameState().getPlayerRelations(h->tempOwner, tempOwner);
|
||||
|
||||
if(relations == PlayerRelations::SAME_PLAYER) //we're visiting our mine
|
||||
{
|
||||
cb->showGarrisonDialog(id,h->id,true);
|
||||
gameEvents.showGarrisonDialog(id,h->id,true);
|
||||
return;
|
||||
}
|
||||
else if (relations == PlayerRelations::ALLIES)//ally
|
||||
@@ -90,11 +91,11 @@ void CGMine::onHeroVisit( const CGHeroInstance * h ) const
|
||||
BlockingDialog ynd(true,false);
|
||||
ynd.player = h->tempOwner;
|
||||
ynd.text.appendLocalString(EMetaText::ADVOB_TXT, isAbandoned() ? 84 : 187);
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
return;
|
||||
}
|
||||
|
||||
flagMine(h->tempOwner);
|
||||
flagMine(gameEvents, h->tempOwner);
|
||||
}
|
||||
|
||||
void CGMine::initObj(vstd::RNG & rand)
|
||||
@@ -172,17 +173,17 @@ std::string CGMine::getHoverText(PlayerColor player) const
|
||||
return hoverName;
|
||||
}
|
||||
|
||||
void CGMine::flagMine(const PlayerColor & player) const
|
||||
void CGMine::flagMine(IGameEventCallback & gameEvents, const PlayerColor & player) const
|
||||
{
|
||||
assert(tempOwner != player);
|
||||
cb->setOwner(this, player); //not ours? flag it!
|
||||
gameEvents.setOwner(this, player); //not ours? flag it!
|
||||
|
||||
InfoWindow iw;
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.text.appendTextID(TextIdentifier("core.mineevnt", producedResource.getNum()).get()); //not use subID, abandoned mines uses default mine texts
|
||||
iw.player = player;
|
||||
iw.components.emplace_back(ComponentType::RESOURCE_PER_DAY, producedResource, getProducedQuantity());
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
ui32 CGMine::defaultResProduction() const
|
||||
@@ -206,22 +207,22 @@ ui32 CGMine::getProducedQuantity() const
|
||||
return vstd::divideAndCeil(producedQuantity * playerSettings->handicap.percentIncome, 100);
|
||||
}
|
||||
|
||||
void CGMine::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGMine::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if(result.winner == BattleSide::ATTACKER) //attacker won
|
||||
{
|
||||
if(isAbandoned())
|
||||
{
|
||||
hero->showInfoDialog(85);
|
||||
hero->showInfoDialog(gameEvents, 85);
|
||||
}
|
||||
flagMine(hero->tempOwner);
|
||||
flagMine(gameEvents, hero->tempOwner);
|
||||
}
|
||||
}
|
||||
|
||||
void CGMine::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGMine::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
if(answer)
|
||||
cb->startBattle(hero, this);
|
||||
gameEvents.startBattle(hero, this);
|
||||
}
|
||||
|
||||
void CGMine::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
@@ -295,11 +296,11 @@ std::vector<ObjectInstanceID> CGTeleport::getAllExits(bool excludeCurrent) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObjectInstanceID CGTeleport::getRandomExit(const CGHeroInstance * h) const
|
||||
ObjectInstanceID CGTeleport::getRandomExit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
auto passableExits = getPassableExits(cb->gameState(), h, getAllExits(true));
|
||||
if(!passableExits.empty())
|
||||
return *RandomGeneratorUtil::nextItem(passableExits, cb->gameState().getRandomGenerator());
|
||||
return *RandomGeneratorUtil::nextItem(passableExits, gameEvents.getRandomGenerator());
|
||||
|
||||
return ObjectInstanceID();
|
||||
}
|
||||
@@ -385,7 +386,7 @@ TeleportChannelID CGMonolith::findMeChannel(const std::vector<Obj> & IDs, MapObj
|
||||
return TeleportChannelID();
|
||||
}
|
||||
|
||||
void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGMonolith::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
TeleportDialog td(h->id, channel);
|
||||
if(isEntrance())
|
||||
@@ -404,19 +405,19 @@ void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
|
||||
logGlobal->debug("Cannot find corresponding exit monolith for %d at %s", id.getNum(), anchorPos().toString());
|
||||
td.impassable = true;
|
||||
}
|
||||
else if(getRandomExit(h) == ObjectInstanceID())
|
||||
else if(getRandomExit(gameEvents, h) == ObjectInstanceID())
|
||||
logGlobal->debug("All exits blocked for monolith %d at %s", id.getNum(), anchorPos().toString());
|
||||
}
|
||||
else
|
||||
h->showInfoDialog(70);
|
||||
h->showInfoDialog(gameEvents, 70);
|
||||
|
||||
cb->showTeleportDialog(&td);
|
||||
gameEvents.showTeleportDialog(&td);
|
||||
}
|
||||
|
||||
void CGMonolith::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const
|
||||
void CGMonolith::teleportDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const
|
||||
{
|
||||
int3 dPos;
|
||||
auto randomExit = getRandomExit(hero);
|
||||
auto randomExit = getRandomExit(gameEvents, hero);
|
||||
auto realExits = getAllExits(true);
|
||||
if(!isEntrance() // Do nothing if hero visited exit only object
|
||||
|| (exits.empty() && realExits.empty()) // Do nothing if there no exits on this channel
|
||||
@@ -429,7 +430,7 @@ void CGMonolith::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer,
|
||||
else
|
||||
dPos = cb->getObj(randomExit)->visitablePos();
|
||||
|
||||
cb->moveHero(hero->id, hero->convertFromVisitablePos(dPos), EMovementMode::MONOLITH);
|
||||
gameEvents.moveHero(hero->id, hero->convertFromVisitablePos(dPos), EMovementMode::MONOLITH);
|
||||
}
|
||||
|
||||
void CGMonolith::initObj(vstd::RNG & rand)
|
||||
@@ -459,22 +460,22 @@ void CGMonolith::initObj(vstd::RNG & rand)
|
||||
addToChannel(cb->gameState().getMap().teleportChannels, this);
|
||||
}
|
||||
|
||||
void CGSubterraneanGate::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGSubterraneanGate::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
TeleportDialog td(h->id, channel);
|
||||
if(cb->isTeleportChannelImpassable(channel))
|
||||
{
|
||||
h->showInfoDialog(153);//Just inside the entrance you find a large pile of rubble blocking the tunnel. You leave discouraged.
|
||||
h->showInfoDialog(gameEvents, 153);//Just inside the entrance you find a large pile of rubble blocking the tunnel. You leave discouraged.
|
||||
logGlobal->debug("Cannot find exit subterranean gate for %d at %s", id.getNum(), anchorPos().toString());
|
||||
td.impassable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto exit = getRandomExit(h);
|
||||
auto exit = getRandomExit(gameEvents, h);
|
||||
td.exits.push_back(std::make_pair(exit, cb->getObj(exit)->visitablePos()));
|
||||
}
|
||||
|
||||
cb->showTeleportDialog(&td);
|
||||
gameEvents.showTeleportDialog(&td);
|
||||
}
|
||||
|
||||
void CGSubterraneanGate::initObj(vstd::RNG & rand)
|
||||
@@ -482,7 +483,7 @@ void CGSubterraneanGate::initObj(vstd::RNG & rand)
|
||||
type = BOTH;
|
||||
}
|
||||
|
||||
void CGSubterraneanGate::postInit(IGameCallback * cb) //matches subterranean gates into pairs
|
||||
void CGSubterraneanGate::postInit(IGameInfoCallback * cb) //matches subterranean gates into pairs
|
||||
{
|
||||
//split on underground and surface gates
|
||||
std::vector<CGSubterraneanGate *> gatesSplit[2]; //surface and underground gates
|
||||
@@ -538,7 +539,7 @@ void CGSubterraneanGate::postInit(IGameCallback * cb) //matches subterranean gat
|
||||
assignToChannel(i);
|
||||
}
|
||||
|
||||
void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGWhirlpool::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
TeleportDialog td(h->id, channel);
|
||||
if(cb->isTeleportChannelImpassable(channel))
|
||||
@@ -546,7 +547,7 @@ void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
logGlobal->debug("Cannot find exit whirlpool for %d at %s", id.getNum(), anchorPos().toString());
|
||||
td.impassable = true;
|
||||
}
|
||||
else if(getRandomExit(h) == ObjectInstanceID())
|
||||
else if(getRandomExit(gameEvents, h) == ObjectInstanceID())
|
||||
logGlobal->debug("All exits are blocked for whirlpool %d at %s", id.getNum(), anchorPos().toString());
|
||||
|
||||
if(!isProtected(h))
|
||||
@@ -566,8 +567,8 @@ void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 168);
|
||||
iw.components.emplace_back(ComponentType::CREATURE, h->getCreature(targetstack)->getId(), -countToTake);
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->changeStackCount(StackLocation(h->id, targetstack), -countToTake);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
gameEvents.changeStackCount(StackLocation(h->id, targetstack), -countToTake);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -580,10 +581,10 @@ void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
}
|
||||
}
|
||||
|
||||
cb->showTeleportDialog(&td);
|
||||
gameEvents.showTeleportDialog(&td);
|
||||
}
|
||||
|
||||
void CGWhirlpool::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const
|
||||
void CGWhirlpool::teleportDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const
|
||||
{
|
||||
int3 dPos;
|
||||
auto realExits = getAllExits();
|
||||
@@ -593,17 +594,17 @@ void CGWhirlpool::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer
|
||||
dPos = exits[answer].second;
|
||||
else
|
||||
{
|
||||
auto exit = getRandomExit(hero);
|
||||
auto exit = getRandomExit(gameEvents, hero);
|
||||
|
||||
if(exit == ObjectInstanceID())
|
||||
return;
|
||||
|
||||
const auto * obj = cb->getObj(exit);
|
||||
std::set<int3> tiles = obj->getBlockedPos();
|
||||
dPos = *RandomGeneratorUtil::nextItem(tiles, cb->gameState().getRandomGenerator());
|
||||
dPos = *RandomGeneratorUtil::nextItem(tiles, gameEvents.getRandomGenerator());
|
||||
}
|
||||
|
||||
cb->moveHero(hero->id, hero->convertFromVisitablePos(dPos), EMovementMode::MONOLITH);
|
||||
gameEvents.moveHero(hero->id, hero->convertFromVisitablePos(dPos), EMovementMode::MONOLITH);
|
||||
}
|
||||
|
||||
bool CGWhirlpool::isProtected(const CGHeroInstance * h)
|
||||
@@ -708,7 +709,7 @@ std::vector<Component> CGArtifact::getPopupComponents(PlayerColor player) const
|
||||
};
|
||||
}
|
||||
|
||||
void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGArtifact::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(!stacksCount())
|
||||
{
|
||||
@@ -748,8 +749,8 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
{
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 2);
|
||||
}
|
||||
cb->showInfoDialog(&iw);
|
||||
pick(h);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
pick(gameEvents, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -769,7 +770,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
ynd.text.replaceRawString(getArmyDescription());
|
||||
ynd.text.replaceLocalString(EMetaText::GENERAL_TXT, 43); // creatures
|
||||
}
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
}
|
||||
break;
|
||||
case Obj::SPELL_SCROLL:
|
||||
@@ -779,20 +780,20 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
BlockingDialog ynd(true,false);
|
||||
ynd.player = h->getOwner();
|
||||
ynd.text = message;
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
gameEvents.showBlockingDialog(this, &ynd);
|
||||
}
|
||||
else
|
||||
blockingDialogAnswered(h, true);
|
||||
blockingDialogAnswered(gameEvents, h, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGArtifact::pick(const CGHeroInstance * h) const
|
||||
void CGArtifact::pick(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(cb->putArtifact(ArtifactLocation(h->id, ArtifactPosition::FIRST_AVAILABLE), getArtifactInstance()->getId()))
|
||||
cb->removeObject(this, h->getOwner());
|
||||
if(gameEvents.putArtifact(ArtifactLocation(h->id, ArtifactPosition::FIRST_AVAILABLE), getArtifactInstance()->getId()))
|
||||
gameEvents.removeObject(this, h->getOwner());
|
||||
}
|
||||
|
||||
BattleField CGArtifact::getBattlefield() const
|
||||
@@ -800,16 +801,16 @@ BattleField CGArtifact::getBattlefield() const
|
||||
return BattleField::NONE;
|
||||
}
|
||||
|
||||
void CGArtifact::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGArtifact::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if(result.winner == BattleSide::ATTACKER) //attacker won
|
||||
pick(hero);
|
||||
pick(gameEvents, hero);
|
||||
}
|
||||
|
||||
void CGArtifact::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void CGArtifact::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
if(answer)
|
||||
cb->startBattle(hero, this);
|
||||
gameEvents.startBattle(hero, this);
|
||||
}
|
||||
|
||||
void CGArtifact::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
@@ -844,15 +845,15 @@ void CGSignBottle::initObj(vstd::RNG & rand)
|
||||
}
|
||||
}
|
||||
|
||||
void CGSignBottle::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGSignBottle::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->getOwner();
|
||||
iw.text = message;
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
|
||||
if(ID == Obj::OCEAN_BOTTLE)
|
||||
cb->removeObject(this, h->getOwner());
|
||||
gameEvents.removeObject(this, h->getOwner());
|
||||
}
|
||||
|
||||
void CGSignBottle::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
@@ -875,20 +876,20 @@ std::vector<CreatureID> CGGarrison::providedCreatures() const
|
||||
return {};
|
||||
}
|
||||
|
||||
void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
|
||||
void CGGarrison::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
auto relations = cb->gameState().getPlayerRelations(h->tempOwner, tempOwner);
|
||||
if (relations == PlayerRelations::ENEMIES && stacksCount() > 0) {
|
||||
//TODO: Find a way to apply magic garrison effects in battle.
|
||||
cb->startBattle(h, this);
|
||||
gameEvents.startBattle(h, this);
|
||||
return;
|
||||
}
|
||||
|
||||
//New owner.
|
||||
if (relations == PlayerRelations::ENEMIES)
|
||||
cb->setOwner(this, h->tempOwner);
|
||||
gameEvents.setOwner(this, h->tempOwner);
|
||||
|
||||
cb->showGarrisonDialog(id, h->id, removableUnits);
|
||||
gameEvents.showGarrisonDialog(id, h->id, removableUnits);
|
||||
}
|
||||
|
||||
bool CGGarrison::passableFor(PlayerColor player) const
|
||||
@@ -905,10 +906,10 @@ bool CGGarrison::passableFor(PlayerColor player) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGGarrison::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const
|
||||
void CGGarrison::battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const
|
||||
{
|
||||
if (result.winner == BattleSide::ATTACKER)
|
||||
onHeroVisit(hero);
|
||||
onHeroVisit(gameEvents, hero);
|
||||
}
|
||||
|
||||
void CGGarrison::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
@@ -941,11 +942,11 @@ void CGMagi::initObj(vstd::RNG & rand)
|
||||
blockVisit = true;
|
||||
}
|
||||
|
||||
void CGMagi::onHeroVisit(const CGHeroInstance * h) const
|
||||
void CGMagi::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if (ID == Obj::HUT_OF_MAGI)
|
||||
{
|
||||
h->showInfoDialog(61);
|
||||
h->showInfoDialog(gameEvents, 61);
|
||||
|
||||
std::vector<const CGObjectInstance *> eyes;
|
||||
|
||||
@@ -969,23 +970,23 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const
|
||||
for(const auto & eye : eyes)
|
||||
{
|
||||
cb->getTilesInRange (fw.tiles, eye->visitablePos(), 10, ETileVisibility::HIDDEN, h->tempOwner);
|
||||
cb->sendAndApply(fw);
|
||||
gameEvents.sendAndApply(fw);
|
||||
cv.pos = eye->visitablePos();
|
||||
|
||||
cb->sendAndApply(cv);
|
||||
gameEvents.sendAndApply(cv);
|
||||
}
|
||||
cv.pos = h->visitablePos();
|
||||
cv.focusTime = 0;
|
||||
cb->sendAndApply(cv);
|
||||
gameEvents.sendAndApply(cv);
|
||||
}
|
||||
}
|
||||
else if (ID == Obj::EYE_OF_MAGI)
|
||||
{
|
||||
h->showInfoDialog(48);
|
||||
h->showInfoDialog(gameEvents, 48);
|
||||
}
|
||||
}
|
||||
|
||||
CGBoat::CGBoat(IGameCallback * cb)
|
||||
CGBoat::CGBoat(IGameInfoCallback * cb)
|
||||
: CGObjectInstance(cb)
|
||||
{
|
||||
direction = 4;
|
||||
@@ -1023,7 +1024,7 @@ std::string CGSirens::getHoverText(const CGHeroInstance * hero) const
|
||||
return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(ID)));
|
||||
}
|
||||
|
||||
void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGSirens::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
@@ -1034,7 +1035,7 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
||||
}
|
||||
else
|
||||
{
|
||||
giveDummyBonus(h->id, BonusDuration::ONE_BATTLE);
|
||||
giveDummyBonus(gameEvents, h->id, BonusDuration::ONE_BATTLE);
|
||||
TExpType xp = 0;
|
||||
|
||||
for (auto i = h->Slots().begin(); i != h->Slots().end(); i++)
|
||||
@@ -1048,7 +1049,7 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
if(drown)
|
||||
{
|
||||
cb->changeStackCount(StackLocation(h->id, i->first), -drown);
|
||||
gameEvents.changeStackCount(StackLocation(h->id, i->first), -drown);
|
||||
xp += drown * i->second->getType()->getMaxHealth();
|
||||
}
|
||||
}
|
||||
@@ -1058,14 +1059,14 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
||||
xp = h->calculateXp(static_cast<int>(xp));
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT,132);
|
||||
iw.text.replaceNumber(static_cast<int>(xp));
|
||||
cb->giveExperience(h, xp);
|
||||
gameEvents.giveExperience(h, xp);
|
||||
}
|
||||
else
|
||||
{
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT,134);
|
||||
}
|
||||
}
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
|
||||
void CGShipyard::getOutOffsets( std::vector<int3> &offsets ) const
|
||||
@@ -1094,10 +1095,10 @@ const IObjectInterface * CGShipyard::getObject() const
|
||||
return this;
|
||||
}
|
||||
|
||||
void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGShipyard::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
if(cb->gameState().getPlayerRelations(tempOwner, h->tempOwner) == PlayerRelations::ENEMIES)
|
||||
cb->setOwner(this, h->tempOwner);
|
||||
gameEvents.setOwner(this, h->tempOwner);
|
||||
|
||||
if(shipyardStatus() != IBoatGenerator::GOOD)
|
||||
{
|
||||
@@ -1105,11 +1106,11 @@ void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.player = tempOwner;
|
||||
getProblemText(iw.text, h);
|
||||
cb->showInfoDialog(&iw);
|
||||
gameEvents.showInfoDialog(&iw);
|
||||
}
|
||||
else
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::SHIPYARD_WINDOW, h, false);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::SHIPYARD_WINDOW, h, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1138,12 +1139,12 @@ std::vector<CreatureID> CGShipyard::providedCreatures() const
|
||||
return {};
|
||||
}
|
||||
|
||||
void CGDenOfthieves::onHeroVisit (const CGHeroInstance * h) const
|
||||
void CGDenOfthieves::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::THIEVES_GUILD, h, false);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::THIEVES_GUILD, h, false);
|
||||
}
|
||||
|
||||
void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
|
||||
void CGObelisk::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
@@ -1155,22 +1156,22 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
|
||||
if(!wasVisited(team))
|
||||
{
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 96);
|
||||
cb->sendAndApply(iw);
|
||||
gameEvents.sendAndApply(iw);
|
||||
|
||||
// increment general visited obelisks counter
|
||||
cb->setObjPropertyID(id, ObjProperty::OBELISK_VISITED, team);
|
||||
cb->showObjectWindow(this, EOpenWindowMode::PUZZLE_MAP, h, false);
|
||||
gameEvents.setObjPropertyID(id, ObjProperty::OBELISK_VISITED, team);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::PUZZLE_MAP, h, false);
|
||||
|
||||
// mark that particular obelisk as visited for all players in the team
|
||||
for(const auto & color : ts->players)
|
||||
{
|
||||
cb->setObjPropertyID(id, ObjProperty::VISITED, color);
|
||||
gameEvents.setObjPropertyID(id, ObjProperty::VISITED, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 97);
|
||||
cb->sendAndApply(iw);
|
||||
gameEvents.sendAndApply(iw);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1213,9 +1214,9 @@ void CGObelisk::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
}
|
||||
}
|
||||
|
||||
void HillFort::onHeroVisit(const CGHeroInstance * h) const
|
||||
void HillFort::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
cb->showObjectWindow(this, EOpenWindowMode::HILL_FORT_WINDOW, h, false);
|
||||
gameEvents.showObjectWindow(this, EOpenWindowMode::HILL_FORT_WINDOW, h, false);
|
||||
}
|
||||
|
||||
void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const
|
||||
|
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
MetaString message;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
@@ -70,8 +70,8 @@ public:
|
||||
|
||||
void initObj(vstd::RNG &rand) override;
|
||||
bool passableFor(PlayerColor color) const override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
ResourceSet dailyIncome() const override;
|
||||
@@ -96,16 +96,16 @@ public:
|
||||
|
||||
MetaString message;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
|
||||
std::string getObjectName() const override;
|
||||
std::string getPopupText(PlayerColor player) const override;
|
||||
std::string getPopupText(const CGHeroInstance * hero) const override;
|
||||
std::vector<Component> getPopupComponents(PlayerColor player) const override;
|
||||
|
||||
void pick( const CGHeroInstance * h ) const;
|
||||
void pick(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
|
||||
@@ -146,11 +146,11 @@ public:
|
||||
private:
|
||||
using CArmedInstance::CArmedInstance;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void battleFinished(IGameEventCallback & gameEvents, const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
|
||||
void flagMine(const PlayerColor & player) const;
|
||||
void flagMine(IGameEventCallback & gameEvents, const PlayerColor & player) const;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
std::string getObjectName() const override;
|
||||
@@ -200,7 +200,7 @@ protected:
|
||||
enum EType {UNKNOWN, ENTRANCE, EXIT, BOTH};
|
||||
EType type = EType::UNKNOWN;
|
||||
|
||||
ObjectInstanceID getRandomExit(const CGHeroInstance * h) const;
|
||||
ObjectInstanceID getRandomExit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const;
|
||||
|
||||
|
||||
public:
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
std::vector<ObjectInstanceID> getAllEntrances(bool excludeCurrent = false) const;
|
||||
std::vector<ObjectInstanceID> getAllExits(bool excludeCurrent = false) const;
|
||||
|
||||
virtual void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const = 0;
|
||||
virtual void teleportDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const = 0;
|
||||
|
||||
static bool isTeleport(const CGObjectInstance * dst);
|
||||
static bool isConnected(const CGTeleport * src, const CGTeleport * dst);
|
||||
@@ -236,8 +236,8 @@ class DLL_LINKAGE CGMonolith : public CGTeleport
|
||||
TeleportChannelID findMeChannel(const std::vector<Obj> & IDs, MapObjectSubID SubID) const;
|
||||
|
||||
protected:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void teleportDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
public:
|
||||
@@ -251,13 +251,13 @@ public:
|
||||
|
||||
class DLL_LINKAGE CGSubterraneanGate : public CGMonolith
|
||||
{
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
public:
|
||||
using CGMonolith::CGMonolith;
|
||||
|
||||
static void postInit(IGameCallback * cb);
|
||||
static void postInit(IGameInfoCallback * cb);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
@@ -267,8 +267,8 @@ public:
|
||||
|
||||
class DLL_LINKAGE CGWhirlpool : public CGMonolith
|
||||
{
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void teleportDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override;
|
||||
static bool isProtected( const CGHeroInstance * h );
|
||||
|
||||
public:
|
||||
@@ -285,7 +285,7 @@ class DLL_LINKAGE CGSirens : public CGObjectInstance
|
||||
public:
|
||||
using CGObjectInstance::CGObjectInstance;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
std::string getHoverText(const CGHeroInstance * hero) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
@@ -312,7 +312,7 @@ public:
|
||||
AnimationPath overlayAnimation; //waves animations
|
||||
std::array<AnimationPath, PlayerColor::PLAYER_LIMIT_I> flagAnimations;
|
||||
|
||||
CGBoat(IGameCallback * cb);
|
||||
CGBoat(IGameInfoCallback * cb);
|
||||
bool isCoastVisitable() const override;
|
||||
|
||||
void setBoardedHero(const CGHeroInstance * hero);
|
||||
@@ -351,7 +351,7 @@ class DLL_LINKAGE CGShipyard : public CGObjectInstance, public IShipyard, public
|
||||
|
||||
protected:
|
||||
void getOutOffsets(std::vector<int3> & offsets) const override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
const IObjectInterface * getObject() const override;
|
||||
BoatId getBoatType() const override;
|
||||
|
||||
@@ -378,7 +378,7 @@ public:
|
||||
using CGObjectInstance::CGObjectInstance;
|
||||
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
@@ -388,7 +388,7 @@ public:
|
||||
|
||||
class DLL_LINKAGE CGDenOfthieves : public CGObjectInstance
|
||||
{
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
public:
|
||||
using CGObjectInstance::CGObjectInstance;
|
||||
};
|
||||
@@ -398,7 +398,7 @@ class DLL_LINKAGE CGObelisk : public CTeamVisited
|
||||
public:
|
||||
using CTeamVisited::CTeamVisited;
|
||||
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
std::string getHoverText(PlayerColor player) const override;
|
||||
std::string getObjectDescription(PlayerColor player) const;
|
||||
@@ -429,7 +429,7 @@ class DLL_LINKAGE HillFort : public CGObjectInstance, public ICreatureUpgrader
|
||||
std::vector<int> upgradeCostPercentage;
|
||||
|
||||
protected:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
void fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const override;
|
||||
|
||||
public:
|
||||
|
@@ -12,7 +12,8 @@
|
||||
#include "TownBuildingInstance.h"
|
||||
|
||||
#include "CGTownInstance.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../callback/IGameEventCallback.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../entities/building/CBuilding.h"
|
||||
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
TownBuildingInstance::TownBuildingInstance(IGameCallback * cb)
|
||||
TownBuildingInstance::TownBuildingInstance(IGameInfoCallback * cb)
|
||||
: IObjectInterface(cb)
|
||||
, town(nullptr)
|
||||
{}
|
||||
@@ -61,7 +62,7 @@ int3 TownBuildingInstance::anchorPos() const
|
||||
return town->anchorPos();
|
||||
}
|
||||
|
||||
TownRewardableBuildingInstance::TownRewardableBuildingInstance(IGameCallback *cb)
|
||||
TownRewardableBuildingInstance::TownRewardableBuildingInstance(IGameInfoCallback *cb)
|
||||
: TownBuildingInstance(cb)
|
||||
{}
|
||||
|
||||
@@ -108,16 +109,16 @@ Rewardable::Configuration TownRewardableBuildingInstance::generateConfiguration(
|
||||
return result;
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::newTurn(vstd::RNG & rand) const
|
||||
void TownRewardableBuildingInstance::newTurn(IGameEventCallback & gameEvents) const
|
||||
{
|
||||
if (configuration.resetParameters.period != 0 && cb->getDate(Date::DAY) > 1 && ((cb->getDate(Date::DAY)-1) % configuration.resetParameters.period) == 0)
|
||||
{
|
||||
auto newConfiguration = generateConfiguration(rand);
|
||||
cb->setRewardableObjectConfiguration(town->id, getBuildingType(), newConfiguration);
|
||||
auto newConfiguration = generateConfiguration(gameEvents.getRandomGenerator());
|
||||
gameEvents.setRewardableObjectConfiguration(town->id, getBuildingType(), newConfiguration);
|
||||
|
||||
if(configuration.resetParameters.visitors)
|
||||
{
|
||||
cb->setObjPropertyValue(town->id, ObjProperty::STRUCTURE_CLEAR_VISITORS, getBuildingType().getNum());
|
||||
gameEvents.setObjPropertyValue(town->id, ObjProperty::STRUCTURE_CLEAR_VISITORS, getBuildingType().getNum());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,24 +139,24 @@ void TownRewardableBuildingInstance::setProperty(ObjProperty what, ObjPropertyID
|
||||
}
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::heroLevelUpDone(const CGHeroInstance *hero) const
|
||||
void TownRewardableBuildingInstance::heroLevelUpDone(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const
|
||||
{
|
||||
grantRewardAfterLevelup(configuration.info.at(selectedReward), town, hero);
|
||||
grantRewardAfterLevelup(gameEvents, configuration.info.at(selectedReward), town, hero);
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const
|
||||
void TownRewardableBuildingInstance::blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const
|
||||
{
|
||||
onBlockingDialogAnswered(hero, answer);
|
||||
onBlockingDialogAnswered(gameEvents, hero, answer);
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::grantReward(ui32 rewardID, const CGHeroInstance * hero) const
|
||||
void TownRewardableBuildingInstance::grantReward(IGameEventCallback & gameEvents, ui32 rewardID, const CGHeroInstance * hero) const
|
||||
{
|
||||
grantRewardBeforeLevelup(configuration.info.at(rewardID), hero);
|
||||
grantRewardBeforeLevelup(gameEvents, configuration.info.at(rewardID), hero);
|
||||
|
||||
// hero is not blocked by levelup dialog - grant remainder immediately
|
||||
if(!cb->isVisitCoveredByAnotherQuery(town, hero))
|
||||
if(!gameEvents.isVisitCoveredByAnotherQuery(town, hero))
|
||||
{
|
||||
grantRewardAfterLevelup(configuration.info.at(rewardID), town, hero);
|
||||
grantRewardAfterLevelup(gameEvents, configuration.info.at(rewardID), town, hero);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,12 +193,12 @@ bool TownRewardableBuildingInstance::wasVisitedBefore(const CGHeroInstance * con
|
||||
}
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::onHeroVisit(const CGHeroInstance *h) const
|
||||
void TownRewardableBuildingInstance::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const
|
||||
{
|
||||
assert(town->hasBuilt(getBuildingType()));
|
||||
|
||||
if(town->hasBuilt(getBuildingType()))
|
||||
doHeroVisit(h);
|
||||
doHeroVisit(gameEvents, h);
|
||||
}
|
||||
|
||||
const IObjectInterface * TownRewardableBuildingInstance::getObject() const
|
||||
@@ -223,12 +224,12 @@ bool TownRewardableBuildingInstance::wasVisited(PlayerColor player) const
|
||||
}
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::markAsVisited(const CGHeroInstance * hero) const
|
||||
void TownRewardableBuildingInstance::markAsVisited(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const
|
||||
{
|
||||
town->addHeroToStructureVisitors(hero, getBuildingType().getNum());
|
||||
town->addHeroToStructureVisitors(gameEvents, hero, getBuildingType().getNum());
|
||||
}
|
||||
|
||||
void TownRewardableBuildingInstance::markAsScouted(const CGHeroInstance * hero) const
|
||||
void TownRewardableBuildingInstance::markAsScouted(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const
|
||||
{
|
||||
// no-op - town building is always 'scouted' by owner
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ class DLL_LINKAGE TownBuildingInstance : public IObjectInterface
|
||||
///basic class for town structures handled as map objects
|
||||
public:
|
||||
TownBuildingInstance(CGTownInstance * town, const BuildingID & index);
|
||||
TownBuildingInstance(IGameCallback *cb);
|
||||
TownBuildingInstance(IGameInfoCallback *cb);
|
||||
|
||||
CGTownInstance * town;
|
||||
|
||||
@@ -56,29 +56,29 @@ class DLL_LINKAGE TownRewardableBuildingInstance : public TownBuildingInstance,
|
||||
std::set<ObjectInstanceID> visitors;
|
||||
|
||||
bool wasVisitedBefore(const CGHeroInstance * contextHero) const override;
|
||||
void grantReward(ui32 rewardID, const CGHeroInstance * hero) const override;
|
||||
void grantReward(IGameEventCallback & gameEvents, ui32 rewardID, const CGHeroInstance * hero) const override;
|
||||
Rewardable::Configuration generateConfiguration(vstd::RNG & rand) const;
|
||||
void assignBonuses(std::vector<Bonus> & bonuses) const;
|
||||
|
||||
const IObjectInterface * getObject() const override;
|
||||
bool wasVisited(PlayerColor player) const override;
|
||||
void markAsVisited(const CGHeroInstance * hero) const override;
|
||||
void markAsScouted(const CGHeroInstance * hero) const override;
|
||||
void markAsVisited(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const override;
|
||||
void markAsScouted(IGameEventCallback & gameEvents, const CGHeroInstance * hero) const override;
|
||||
public:
|
||||
void setProperty(ObjProperty what, ObjPropertyID identifier) override;
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void onHeroVisit(IGameEventCallback & gameEvents, const CGHeroInstance * h) const override;
|
||||
bool wasVisited(const CGHeroInstance * contextHero) const override;
|
||||
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void newTurn(IGameEventCallback & gameEvents) const override;
|
||||
|
||||
/// gives second part of reward after hero level-ups for proper granting of spells/mana
|
||||
void heroLevelUpDone(const CGHeroInstance *hero) const override;
|
||||
void heroLevelUpDone(IGameEventCallback & gameEvents, const CGHeroInstance *hero) const override;
|
||||
|
||||
/// applies player selection of reward
|
||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||
void blockingDialogAnswered(IGameEventCallback & gameEvents, const CGHeroInstance *hero, int32_t answer) const override;
|
||||
|
||||
TownRewardableBuildingInstance(CGTownInstance * town, const BuildingID & index, vstd::RNG & rand);
|
||||
TownRewardableBuildingInstance(IGameCallback *cb);
|
||||
TownRewardableBuildingInstance(IGameInfoCallback *cb);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#include "../RoadHandler.h"
|
||||
#include "../TerrainHandler.h"
|
||||
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../entities/artifact/CArtHandler.h"
|
||||
#include "../entities/hero/CHeroHandler.h"
|
||||
#include "../gameState/CGameState.h"
|
||||
@@ -170,7 +170,7 @@ EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
|
||||
return EDiggingStatus::CAN_DIG;
|
||||
}
|
||||
|
||||
CMap::CMap(IGameCallback * cb)
|
||||
CMap::CMap(IGameInfoCallback * cb)
|
||||
: GameCallbackHolder(cb)
|
||||
, grailPos(-1, -1, -1)
|
||||
, grailRadius(0)
|
||||
|
@@ -80,7 +80,7 @@ public:
|
||||
/// TODO: make private
|
||||
std::vector<std::shared_ptr<CGObjectInstance>> objects;
|
||||
|
||||
explicit CMap(IGameCallback *cb);
|
||||
explicit CMap(IGameInfoCallback *cb);
|
||||
~CMap();
|
||||
void initTerrain();
|
||||
|
||||
|
@@ -30,7 +30,7 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
std::unique_ptr<CMap> CMapService::loadMap(const ResourcePath & name, IGameCallback * cb) const
|
||||
std::unique_ptr<CMap> CMapService::loadMap(const ResourcePath & name, IGameInfoCallback * cb) const
|
||||
{
|
||||
std::string modName = LIBRARY->modh->findResourceOrigin(name);
|
||||
std::string encoding = LIBRARY->modh->findResourceEncoding(name);
|
||||
@@ -48,7 +48,7 @@ std::unique_ptr<CMapHeader> CMapService::loadMapHeader(const ResourcePath & name
|
||||
return getMapLoader(stream, name.getName(), modName, encoding)->loadMapHeader();
|
||||
}
|
||||
|
||||
std::unique_ptr<CMap> CMapService::loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding, IGameCallback * cb) const
|
||||
std::unique_ptr<CMap> CMapService::loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding, IGameInfoCallback * cb) const
|
||||
{
|
||||
auto stream = getStreamFromMem(buffer, size);
|
||||
std::unique_ptr<CMap> map(getMapLoader(stream, name, modName, encoding)->loadMap(cb));
|
||||
|
@@ -22,7 +22,7 @@ class CInputStream;
|
||||
|
||||
class IMapLoader;
|
||||
class IMapPatcher;
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
|
||||
/**
|
||||
* The map service provides loading of VCMI/H3 map files. It can
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
* @param name the name of the map
|
||||
* @return a unique ptr to the loaded map class
|
||||
*/
|
||||
virtual std::unique_ptr<CMap> loadMap(const ResourcePath & name, IGameCallback * cb) const = 0;
|
||||
virtual std::unique_ptr<CMap> loadMap(const ResourcePath & name, IGameInfoCallback * cb) const = 0;
|
||||
|
||||
/**
|
||||
* Loads the VCMI/H3 map header specified by the name.
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
* @param name indicates name of file that will be used during map header patching
|
||||
* @return a unique ptr to the loaded map class
|
||||
*/
|
||||
virtual std::unique_ptr<CMap> loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding, IGameCallback * cb) const = 0;
|
||||
virtual std::unique_ptr<CMap> loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding, IGameInfoCallback * cb) const = 0;
|
||||
|
||||
/**
|
||||
* Loads the VCMI/H3 map header from a buffer. This method is temporarily
|
||||
@@ -81,9 +81,9 @@ public:
|
||||
CMapService() = default;
|
||||
virtual ~CMapService() = default;
|
||||
|
||||
std::unique_ptr<CMap> loadMap(const ResourcePath & name, IGameCallback * cb) const override;
|
||||
std::unique_ptr<CMap> loadMap(const ResourcePath & name, IGameInfoCallback * cb) const override;
|
||||
std::unique_ptr<CMapHeader> loadMapHeader(const ResourcePath & name) const override;
|
||||
std::unique_ptr<CMap> loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding, IGameCallback * cb) const override;
|
||||
std::unique_ptr<CMap> loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding, IGameInfoCallback * cb) const override;
|
||||
std::unique_ptr<CMapHeader> loadMapHeader(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding) const override;
|
||||
void saveMap(const std::unique_ptr<CMap> & map, boost::filesystem::path fullPath) const override;
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
*
|
||||
* @return a unique ptr of the loaded map class
|
||||
*/
|
||||
virtual std::unique_ptr<CMap> loadMap(IGameCallback * cb) = 0;
|
||||
virtual std::unique_ptr<CMap> loadMap(IGameInfoCallback * cb) = 0;
|
||||
|
||||
/**
|
||||
* Loads the VCMI/H3 map header.
|
||||
|
@@ -72,7 +72,7 @@ CMapLoaderH3M::CMapLoaderH3M(const std::string & mapName, const std::string & mo
|
||||
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||
CMapLoaderH3M::~CMapLoaderH3M() = default;
|
||||
|
||||
std::unique_ptr<CMap> CMapLoaderH3M::loadMap(IGameCallback * cb)
|
||||
std::unique_ptr<CMap> CMapLoaderH3M::loadMap(IGameInfoCallback * cb)
|
||||
{
|
||||
// Init map object by parsing the input buffer
|
||||
map = new CMap(cb);
|
||||
|
@@ -86,7 +86,7 @@ public:
|
||||
*
|
||||
* @return a unique ptr of the loaded map class
|
||||
*/
|
||||
std::unique_ptr<CMap> loadMap(IGameCallback * cb) override;
|
||||
std::unique_ptr<CMap> loadMap(IGameInfoCallback * cb) override;
|
||||
|
||||
/**
|
||||
* Loads the VCMI/H3 map header.
|
||||
|
@@ -767,7 +767,7 @@ CMapLoaderJson::CMapLoaderJson(CInputStream * stream)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<CMap> CMapLoaderJson::loadMap(IGameCallback * cb)
|
||||
std::unique_ptr<CMap> CMapLoaderJson::loadMap(IGameInfoCallback * cb)
|
||||
{
|
||||
LOG_TRACE(logGlobal);
|
||||
auto result = std::make_unique<CMap>(cb);
|
||||
|
@@ -167,7 +167,7 @@ public:
|
||||
*
|
||||
* @return a unique ptr of the loaded map class
|
||||
*/
|
||||
std::unique_ptr<CMap> loadMap(IGameCallback * cb) override;
|
||||
std::unique_ptr<CMap> loadMap(IGameInfoCallback * cb) override;
|
||||
|
||||
/**
|
||||
* Loads the VCMI/Json map header.
|
||||
|
@@ -230,7 +230,7 @@ bool ObstacleProxy::isProhibited(const rmg::Area& objArea) const
|
||||
return false;
|
||||
};
|
||||
|
||||
int ObstacleProxy::getWeightedObjects(const int3 & tile, vstd::RNG & rand, IGameCallback * cb, std::list<rmg::Object> & allObjects, std::vector<std::pair<rmg::Object*, int3>> & weightedObjects)
|
||||
int ObstacleProxy::getWeightedObjects(const int3 & tile, vstd::RNG & rand, IGameInfoCallback * cb, std::list<rmg::Object> & allObjects, std::vector<std::pair<rmg::Object*, int3>> & weightedObjects)
|
||||
{
|
||||
int maxWeight = std::numeric_limits<int>::min();
|
||||
for(auto & possibleObstacle : possibleObstacles)
|
||||
@@ -311,7 +311,7 @@ int ObstacleProxy::getWeightedObjects(const int3 & tile, vstd::RNG & rand, IGame
|
||||
return maxWeight;
|
||||
}
|
||||
|
||||
std::set<std::shared_ptr<CGObjectInstance>> ObstacleProxy::createObstacles(vstd::RNG & rand, IGameCallback * cb)
|
||||
std::set<std::shared_ptr<CGObjectInstance>> ObstacleProxy::createObstacles(vstd::RNG & rand, IGameInfoCallback * cb)
|
||||
{
|
||||
//reverse order, since obstacles begin in bottom-right corner, while the map coordinates begin in top-left
|
||||
auto blockedTiles = blockedArea.getTilesVector();
|
||||
|
@@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class CMapEditManager;
|
||||
class CGObjectInstance;
|
||||
class ObjectTemplate;
|
||||
class IGameCallback;
|
||||
class IGameInfoCallback;
|
||||
class ObstacleSetFilter;
|
||||
|
||||
class DLL_LINKAGE ObstacleProxy
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
virtual void placeObject(rmg::Object & object, std::set<std::shared_ptr<CGObjectInstance>> & instances);
|
||||
|
||||
virtual std::set<std::shared_ptr<CGObjectInstance>> createObstacles(vstd::RNG & rand, IGameCallback * cb);
|
||||
virtual std::set<std::shared_ptr<CGObjectInstance>> createObstacles(vstd::RNG & rand, IGameInfoCallback * cb);
|
||||
|
||||
virtual bool isInTheMap(const int3& tile) = 0;
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
virtual void postProcess(const rmg::Object& object) {};
|
||||
|
||||
protected:
|
||||
int getWeightedObjects(const int3& tile, vstd::RNG& rand, IGameCallback * cb, std::list<rmg::Object>& allObjects, std::vector<std::pair<rmg::Object*, int3>>& weightedObjects);
|
||||
int getWeightedObjects(const int3& tile, vstd::RNG& rand, IGameInfoCallback * cb, std::list<rmg::Object>& allObjects, std::vector<std::pair<rmg::Object*, int3>>& weightedObjects);
|
||||
void sortObstacles();
|
||||
|
||||
rmg::Area blockedArea;
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include "../CPlayerState.h"
|
||||
#include "../TerrainHandler.h"
|
||||
#include "../RoadHandler.h"
|
||||
#include "../callback/IGameCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
|
@@ -28,7 +28,7 @@ void NodeStorage::initialize(const PathfinderOptions & options, const CGameState
|
||||
int3 pos;
|
||||
const PlayerColor player = out.hero->tempOwner;
|
||||
const int3 sizes = gs->getMapSize();
|
||||
const auto & fow = static_cast<const CGameInfoCallback *>(gs)->getPlayerTeam(player)->fogOfWarMap;
|
||||
const auto & fow = static_cast<const IGameInfoCallback *>(gs)->getPlayerTeam(player)->fogOfWarMap;
|
||||
|
||||
//make 200% sure that these are loop invariants (also a bit shorter code), let compiler do the rest(loop unswitching)
|
||||
const bool useFlying = options.useFlying;
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#include "CGPathNode.h"
|
||||
#include "PathfinderOptions.h"
|
||||
|
||||
#include "../callback/CGameInfoCallback.h"
|
||||
#include "../callback/IGameInfoCallback.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@@ -35,7 +35,7 @@ std::shared_ptr<CPathsInfo> PathfinderCache::buildPaths(const CGHeroInstance * h
|
||||
return result;
|
||||
}
|
||||
|
||||
PathfinderCache::PathfinderCache(const CGameInfoCallback * cb, const PathfinderOptions & options)
|
||||
PathfinderCache::PathfinderCache(const IGameInfoCallback * cb, const PathfinderOptions & options)
|
||||
: cb(cb)
|
||||
, options(options)
|
||||
{
|
||||
|
@@ -13,14 +13,14 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGameInfoCallback;
|
||||
class IGameInfoCallback;
|
||||
class CGHeroInstance;
|
||||
class PathfinderConfig;
|
||||
struct CPathsInfo;
|
||||
|
||||
class DLL_LINKAGE PathfinderCache
|
||||
{
|
||||
const CGameInfoCallback * cb;
|
||||
const IGameInfoCallback * cb;
|
||||
std::mutex pathCacheMutex;
|
||||
std::map<const CGHeroInstance *, std::shared_ptr<CPathsInfo>> pathCache;
|
||||
PathfinderOptions options;
|
||||
@@ -28,7 +28,7 @@ class DLL_LINKAGE PathfinderCache
|
||||
std::shared_ptr<PathfinderConfig> createConfig(const CGHeroInstance *h, CPathsInfo &out);
|
||||
std::shared_ptr<CPathsInfo> buildPaths(const CGHeroInstance *h);
|
||||
public:
|
||||
PathfinderCache(const CGameInfoCallback * cb, const PathfinderOptions & options);
|
||||
PathfinderCache(const IGameInfoCallback * cb, const PathfinderOptions & options);
|
||||
|
||||
/// Invalidates and erases all existing paths from the cache
|
||||
void invalidatePaths();
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
PathfinderOptions::PathfinderOptions(const CGameInfoCallback & cb)
|
||||
PathfinderOptions::PathfinderOptions(const IGameInfoCallback & cb)
|
||||
: useFlying(true)
|
||||
, useWaterWalking(true)
|
||||
, ignoreGuards(cb.getSettings().getBoolean(EGameSettings::PATHFINDER_IGNORE_GUARDS))
|
||||
@@ -39,7 +39,7 @@ PathfinderOptions::PathfinderOptions(const CGameInfoCallback & cb)
|
||||
{
|
||||
}
|
||||
|
||||
PathfinderConfig::PathfinderConfig(std::shared_ptr<INodeStorage> nodeStorage, const CGameInfoCallback & callback, std::vector<std::shared_ptr<IPathfindingRule>> rules):
|
||||
PathfinderConfig::PathfinderConfig(std::shared_ptr<INodeStorage> nodeStorage, const IGameInfoCallback & callback, std::vector<std::shared_ptr<IPathfindingRule>> rules):
|
||||
nodeStorage(std::move(nodeStorage)),
|
||||
rules(std::move(rules)),
|
||||
options(callback)
|
||||
@@ -59,7 +59,7 @@ std::vector<std::shared_ptr<IPathfindingRule>> SingleHeroPathfinderConfig::build
|
||||
|
||||
SingleHeroPathfinderConfig::~SingleHeroPathfinderConfig() = default;
|
||||
|
||||
SingleHeroPathfinderConfig::SingleHeroPathfinderConfig(CPathsInfo & out, const CGameInfoCallback & gs, const CGHeroInstance * hero)
|
||||
SingleHeroPathfinderConfig::SingleHeroPathfinderConfig(CPathsInfo & out, const IGameInfoCallback & gs, const CGHeroInstance * hero)
|
||||
: PathfinderConfig(std::make_shared<NodeStorage>(out, hero), gs, buildRuleSet())
|
||||
, hero(hero)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user