#pragma once #include "CObjectHandler.h" #include "CArmedInstance.h" #include "../ResourceSet.h" /* * MiscObjects.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 * */ class CMap; class DLL_LINKAGE CPlayersVisited: public CGObjectInstance { public: std::set players; //players that visited this object bool wasVisited(PlayerColor player) const override; bool wasVisited(TeamID team) const; void setPropertyDer(ui8 what, ui32 val) override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & players; } static const int OBJPROP_VISITED = 10; }; class DLL_LINKAGE CGCreature : public CArmedInstance //creatures on map { public: enum Action { FIGHT = -2, FLEE = -1, JOIN_FOR_FREE = 0 //values > 0 mean gold price }; enum Character { COMPLIANT = 0, FRIENDLY = 1, AGRESSIVE = 2, HOSTILE = 3, SAVAGE = 4 }; ui32 identifier; //unique code for this monster (used in missions) si8 character; //character of this set of creatures (0 - the most friendly, 4 - the most hostile) => on init changed to -4 (compliant) ... 10 value (savage) std::string message; //message printed for attacking hero TResources resources; // resources given to hero that has won with monsters ArtifactID gainedArtifact; //ID of artifact gained to hero, -1 if none bool neverFlees; //if true, the troops will never flee bool notGrowingTeam; //if true, number of units won't grow ui64 temppower; //used to handle fractional stack growth for tiny stacks bool refusedJoining; void onHeroVisit(const CGHeroInstance * h) const override; std::string getHoverText(PlayerColor player) const override; std::string getHoverText(const CGHeroInstance * hero) const override; void initObj() override; void newTurn() const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; //stack formation depends on position, bool containsUpgradedStack() const; int getNumberOfStacks(const CGHeroInstance *hero) const; struct DLL_LINKAGE formationInfo // info about merging stacks after battle back into one { si32 basicType; ui8 upgrade; //random seed used to determine number of stacks and is there's upgraded stack template void serialize(Handler &h, const int version) { h & basicType & upgrade; } } formation; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & identifier & character & message & resources & gainedArtifact & neverFlees & notGrowingTeam & temppower; h & refusedJoining & formation; } protected: void setPropertyDer(ui8 what, ui32 val) override; void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) 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; 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; }; class DLL_LINKAGE CGSignBottle : public CGObjectInstance //signs and ocean bottles { public: std::string message; void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & message; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGWitchHut : public CPlayersVisited { public: std::vector allowedAbilities; ui32 ability; std::string getHoverText(PlayerColor player) const override; std::string getHoverText(const CGHeroInstance * hero) const override; void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & allowedAbilities & ability; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGScholar : public CGObjectInstance { public: enum EBonusType {PRIM_SKILL, SECONDARY_SKILL, SPELL, RANDOM = 255}; EBonusType bonusType; ui16 bonusID; //ID of skill/spell CGScholar() : bonusType(EBonusType::RANDOM){}; void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & bonusType & bonusID; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGGarrison : public CArmedInstance { public: bool removableUnits; bool passableFor(PlayerColor color) const override; void onHeroVisit(const CGHeroInstance * h) const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & removableUnits; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGArtifact : public CArmedInstance { public: CArtifactInstance *storedArtifact; std::string message; CGArtifact() : CArmedInstance() {storedArtifact = nullptr;}; void onHeroVisit(const CGHeroInstance * h) const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; std::string getObjectName() const override; void pick( const CGHeroInstance * h ) const; void initObj() override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & message & storedArtifact; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGResource : public CArmedInstance { public: ui32 amount; //0 if random std::string message; CGResource(); void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; std::string getHoverText(PlayerColor player) const override; void collectRes(PlayerColor player) const; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & amount & message; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGShrine : public CPlayersVisited { public: SpellID spell; //id of spell or NONE if random void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; std::string getHoverText(PlayerColor player) const override; std::string getHoverText(const CGHeroInstance * hero) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this);; h & spell; } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGMine : public CArmedInstance { public: Res::ERes producedResource; ui32 producedQuantity; private: void onHeroVisit(const CGHeroInstance * h) const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; void flagMine(PlayerColor player) const; void newTurn() const override; void initObj() override; std::string getObjectName() const override; std::string getHoverText(PlayerColor player) const override; bool isAbandoned() const; public: template void serialize(Handler &h, const int version) { h & static_cast(*this); h & producedResource & producedQuantity; } ui32 defaultResProduction(); protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; struct DLL_LINKAGE TeleportChannel { enum EPassability {UNKNOWN, IMPASSABLE, PASSABLE}; TeleportChannel() : passability(UNKNOWN) {} std::vector entrances; std::vector exits; EPassability passability; template void serialize(Handler &h, const int version) { h & entrances & exits & passability; } }; class DLL_LINKAGE CGTeleport : public CGObjectInstance { bool isChannelEntrance(ObjectInstanceID id) const; bool isChannelExit(ObjectInstanceID id) const; std::vector getAllEntrances(bool excludeCurrent = false) const; protected: enum EType {UNKNOWN, ENTRANCE, EXIT, BOTH}; EType type; CGTeleport(); ObjectInstanceID getRandomExit(const CGHeroInstance * h) const; std::vector getAllExits(bool excludeCurrent = false) const; public: TeleportChannelID channel; bool isEntrance() const; bool isExit() const; virtual void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const = 0; static bool isTeleport(const CGObjectInstance * dst); static bool isConnected(const CGTeleport * src, const CGTeleport * dst); static bool isConnected(const CGObjectInstance * src, const CGObjectInstance * dst); static void addToChannel(std::map > &channelsList, const CGTeleport * obj); static std::vector getPassableExits(CGameState * gs, const CGHeroInstance * h, std::vector exits); static bool isExitPassable(CGameState * gs, const CGHeroInstance * h, const CGObjectInstance * obj); template void serialize(Handler &h, const int version) { h & type & channel & static_cast(*this); } }; class DLL_LINKAGE CGMonolith : public CGTeleport { TeleportChannelID findMeChannel(std::vector IDs, int SubID) const; protected: void onHeroVisit(const CGHeroInstance * h) const override; void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override; void initObj() override; public: template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGSubterraneanGate : public CGMonolith { void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; public: static void postInit(); template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGWhirlpool : public CGMonolith { void onHeroVisit(const CGHeroInstance * h) const override; void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const override; static bool isProtected( const CGHeroInstance * h ); public: template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGMagicWell : public CGObjectInstance //objects giving bonuses to luck/morale/movement { public: void onHeroVisit(const CGHeroInstance * h) const override; std::string getHoverText(const CGHeroInstance * hero) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGSirens : public CGObjectInstance { public: void onHeroVisit(const CGHeroInstance * h) const override; std::string getHoverText(const CGHeroInstance * hero) const override; void initObj() override; template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGObservatory : public CGObjectInstance //Redwood observatory { public: void onHeroVisit(const CGHeroInstance * h) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGBoat : public CGObjectInstance { public: ui8 direction; const CGHeroInstance *hero; //hero on board void initObj() override; CGBoat() { hero = nullptr; direction = 4; } template void serialize(Handler &h, const int version) { h & static_cast(*this) & direction & hero; } }; class CGShipyard : public CGObjectInstance, public IShipyard { public: void getOutOffsets(std::vector &offsets) const override; //offsets to obj pos when we boat can be placed CGShipyard(); void onHeroVisit(const CGHeroInstance * h) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); h & static_cast(*this); } protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; }; class DLL_LINKAGE CGMagi : public CGObjectInstance { public: static std::map > eyelist; //[subID][id], supports multiple sets as in H5 void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CCartographer : public CPlayersVisited { ///behaviour varies depending on surface and floor public: void onHeroVisit(const CGHeroInstance * h) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); } }; class DLL_LINKAGE CGDenOfthieves : public CGObjectInstance { void onHeroVisit(const CGHeroInstance * h) const override; }; class DLL_LINKAGE CGObelisk : public CPlayersVisited { public: static const int OBJPROP_INC = 20; static ui8 obeliskCount; //how many obelisks are on map static std::map visited; //map: team_id => how many obelisks has been visited void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; std::string getHoverText(PlayerColor player) const override; static void reset(); template void serialize(Handler &h, const int version) { h & static_cast(*this); } protected: void setPropertyDer(ui8 what, ui32 val) override; }; class DLL_LINKAGE CGLighthouse : public CGObjectInstance { public: void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; std::string getHoverText(PlayerColor player) const override; template void serialize(Handler &h, const int version) { h & static_cast(*this); } void giveBonusTo( PlayerColor player ) const; protected: void writeJsonOptions(JsonNode & json) const override; void readJsonOptions(const JsonNode & json) override; };