2021-05-15 19:59:43 +02:00
|
|
|
/*
|
|
|
|
* AINodeStorage.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 "../../../lib/mapObjects/CGHeroInstance.h"
|
|
|
|
#include "../AIUtility.h"
|
2021-05-16 13:38:53 +02:00
|
|
|
#include "Actions/SpecialAction.h"
|
2021-05-15 19:59:43 +02:00
|
|
|
|
2022-09-26 20:01:07 +02:00
|
|
|
namespace NKAI
|
|
|
|
{
|
|
|
|
|
2021-05-16 14:08:39 +02:00
|
|
|
extern const uint64_t MIN_ARMY_STRENGTH_FOR_CHAIN;
|
|
|
|
|
2021-05-16 14:08:49 +02:00
|
|
|
class ChainActor;
|
2021-05-15 19:59:43 +02:00
|
|
|
class HeroActor;
|
2020-05-04 17:58:43 +02:00
|
|
|
class Nullkiller;
|
2021-05-15 19:59:43 +02:00
|
|
|
|
2021-03-01 21:38:50 +02:00
|
|
|
class HeroExchangeArmy : public CArmedInstance
|
2021-05-15 20:56:08 +02:00
|
|
|
{
|
|
|
|
public:
|
2021-05-16 13:57:26 +02:00
|
|
|
TResources armyCost;
|
|
|
|
bool requireBuyArmy;
|
2024-02-10 21:22:08 +02:00
|
|
|
bool needsLastStack() const override;
|
2021-05-16 13:57:26 +02:00
|
|
|
std::shared_ptr<SpecialAction> getActorAction() const;
|
|
|
|
|
2024-01-01 16:37:48 +02:00
|
|
|
HeroExchangeArmy(): CArmedInstance(nullptr, true), requireBuyArmy(false) {}
|
2021-05-15 20:56:08 +02:00
|
|
|
};
|
|
|
|
|
2021-05-16 14:08:49 +02:00
|
|
|
struct ExchangeResult
|
|
|
|
{
|
|
|
|
bool lockAcquired;
|
|
|
|
ChainActor * actor;
|
|
|
|
|
|
|
|
ExchangeResult() : lockAcquired(true), actor(nullptr) {}
|
|
|
|
};
|
|
|
|
|
2021-05-15 19:59:43 +02:00
|
|
|
class ChainActor
|
|
|
|
{
|
|
|
|
protected:
|
2021-05-16 13:56:13 +02:00
|
|
|
ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t chainMask);
|
2021-05-15 19:59:43 +02:00
|
|
|
ChainActor(const ChainActor * carrier, const ChainActor * other, const CCreatureSet * heroArmy);
|
2019-03-17 23:27:09 +02:00
|
|
|
ChainActor(const CGObjectInstance * obj, const CCreatureSet * army, uint64_t chainMask, int initialTurn);
|
2021-05-15 19:59:43 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
uint64_t chainMask;
|
2024-02-12 12:31:27 +02:00
|
|
|
bool isMovable = false;
|
|
|
|
bool allowUseResources = false;
|
|
|
|
bool allowBattle = false;
|
|
|
|
bool allowSpellCast = false;
|
2021-05-16 13:57:26 +02:00
|
|
|
std::shared_ptr<SpecialAction> actorAction;
|
2021-05-15 19:59:43 +02:00
|
|
|
const CGHeroInstance * hero;
|
2021-05-16 13:56:13 +02:00
|
|
|
HeroRole heroRole;
|
2024-02-12 12:31:27 +02:00
|
|
|
const CCreatureSet * creatureSet = nullptr;
|
|
|
|
const ChainActor * battleActor = nullptr;
|
|
|
|
const ChainActor * castActor = nullptr;
|
|
|
|
const ChainActor * resourceActor = nullptr;
|
|
|
|
const ChainActor * carrierParent = nullptr;
|
|
|
|
const ChainActor * otherParent = nullptr;
|
|
|
|
const ChainActor * baseActor = nullptr;
|
2021-05-15 19:59:43 +02:00
|
|
|
int3 initialPosition;
|
|
|
|
EPathfindingLayer layer;
|
2024-02-12 12:31:27 +02:00
|
|
|
uint32_t initialMovement = 0;
|
|
|
|
uint32_t initialTurn = 0;
|
2021-05-15 19:59:43 +02:00
|
|
|
uint64_t armyValue;
|
2021-05-15 20:54:58 +02:00
|
|
|
float heroFightingStrength;
|
|
|
|
uint8_t actorExchangeCount;
|
2021-05-15 20:55:29 +02:00
|
|
|
TResources armyCost;
|
2022-05-15 10:39:06 +02:00
|
|
|
std::shared_ptr<TurnInfo> tiCache;
|
2021-05-15 19:59:43 +02:00
|
|
|
|
2022-09-22 10:02:16 +02:00
|
|
|
ChainActor() = default;
|
|
|
|
virtual ~ChainActor() = default;
|
2019-03-17 23:27:09 +02:00
|
|
|
|
2021-05-15 20:54:28 +02:00
|
|
|
virtual std::string toString() const;
|
2021-05-16 14:08:49 +02:00
|
|
|
ExchangeResult tryExchangeNoLock(const ChainActor * other) const { return tryExchangeNoLock(this, other); }
|
2021-05-15 19:59:43 +02:00
|
|
|
void setBaseActor(HeroActor * base);
|
2021-05-16 13:19:00 +02:00
|
|
|
virtual const CGObjectInstance * getActorObject() const { return hero; }
|
2023-06-21 12:46:09 +02:00
|
|
|
int maxMovePoints(EPathfindingLayer layer);
|
2021-05-15 19:59:43 +02:00
|
|
|
|
2019-03-17 23:27:09 +02:00
|
|
|
protected:
|
2021-05-16 14:08:49 +02:00
|
|
|
virtual ExchangeResult tryExchangeNoLock(const ChainActor * specialActor, const ChainActor * other) const;
|
2019-03-17 23:27:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class HeroExchangeMap
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
const HeroActor * actor;
|
|
|
|
std::map<const ChainActor *, HeroActor *> exchangeMap;
|
2020-05-04 17:58:43 +02:00
|
|
|
const Nullkiller * ai;
|
2020-09-02 19:16:24 +02:00
|
|
|
boost::shared_mutex sync;
|
2019-03-17 23:27:09 +02:00
|
|
|
|
|
|
|
public:
|
2021-05-16 13:59:32 +02:00
|
|
|
HeroExchangeMap(const HeroActor * actor, const Nullkiller * ai);
|
2021-05-15 20:56:08 +02:00
|
|
|
~HeroExchangeMap();
|
|
|
|
|
2021-05-16 14:08:49 +02:00
|
|
|
ExchangeResult tryExchangeNoLock(const ChainActor * other);
|
2019-03-17 23:27:09 +02:00
|
|
|
|
|
|
|
private:
|
2021-05-16 13:57:26 +02:00
|
|
|
HeroExchangeArmy * pickBestCreatures(const CCreatureSet * army1, const CCreatureSet * army2) const;
|
|
|
|
HeroExchangeArmy * tryUpgrade(const CCreatureSet * army, const CGObjectInstance * upgrader, TResources resources) const;
|
2021-05-15 19:59:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class HeroActor : public ChainActor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static const int SPECIAL_ACTORS_COUNT = 7;
|
|
|
|
|
|
|
|
private:
|
|
|
|
ChainActor specialActors[SPECIAL_ACTORS_COUNT];
|
2021-05-16 13:59:32 +02:00
|
|
|
std::unique_ptr<HeroExchangeMap> exchangeMap;
|
2021-05-15 19:59:43 +02:00
|
|
|
|
|
|
|
void setupSpecialActors();
|
|
|
|
|
|
|
|
public:
|
2021-05-16 13:38:53 +02:00
|
|
|
std::shared_ptr<SpecialAction> exchangeAction;
|
2021-05-15 19:59:43 +02:00
|
|
|
// chain flags, can be combined meaning hero exchange and so on
|
|
|
|
|
2021-05-16 13:56:13 +02:00
|
|
|
HeroActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t chainMask, const Nullkiller * ai);
|
2021-05-16 13:57:26 +02:00
|
|
|
HeroActor(const ChainActor * carrier, const ChainActor * other, const HeroExchangeArmy * army, const Nullkiller * ai);
|
2021-05-15 19:59:43 +02:00
|
|
|
|
2019-03-17 23:27:09 +02:00
|
|
|
protected:
|
2024-02-10 21:22:08 +02:00
|
|
|
ExchangeResult tryExchangeNoLock(const ChainActor * specialActor, const ChainActor * other) const override;
|
2021-05-15 19:59:43 +02:00
|
|
|
};
|
2019-03-17 23:27:09 +02:00
|
|
|
|
2021-05-16 13:19:00 +02:00
|
|
|
class ObjectActor : public ChainActor
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
const CGObjectInstance * object;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ObjectActor(const CGObjectInstance * obj, const CCreatureSet * army, uint64_t chainMask, int initialTurn);
|
2024-02-13 16:21:30 +02:00
|
|
|
std::string toString() const override;
|
2021-05-16 13:19:00 +02:00
|
|
|
const CGObjectInstance * getActorObject() const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class HillFortActor : public ObjectActor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
HillFortActor(const CGObjectInstance * hillFort, uint64_t chainMask);
|
|
|
|
};
|
|
|
|
|
|
|
|
class DwellingActor : public ObjectActor
|
2019-03-17 23:27:09 +02:00
|
|
|
{
|
2021-05-15 20:54:28 +02:00
|
|
|
private:
|
|
|
|
const CGDwelling * dwelling;
|
|
|
|
|
2019-03-17 23:27:09 +02:00
|
|
|
public:
|
|
|
|
DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bool waitForGrowth, int dayOfWeek);
|
|
|
|
~DwellingActor();
|
2024-02-13 16:21:30 +02:00
|
|
|
std::string toString() const override;
|
2019-03-17 23:27:09 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
int getInitialTurn(bool waitForGrowth, int dayOfWeek);
|
|
|
|
CCreatureSet * getDwellingCreatures(const CGDwelling * dwelling, bool waitForGrowth);
|
|
|
|
};
|
|
|
|
|
2021-05-16 13:19:00 +02:00
|
|
|
class TownGarrisonActor : public ObjectActor
|
2019-03-17 23:27:09 +02:00
|
|
|
{
|
2021-05-15 20:54:28 +02:00
|
|
|
private:
|
|
|
|
const CGTownInstance * town;
|
|
|
|
|
2019-03-17 23:27:09 +02:00
|
|
|
public:
|
|
|
|
TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask);
|
2024-02-13 16:21:30 +02:00
|
|
|
std::string toString() const override;
|
2022-09-22 10:02:16 +02:00
|
|
|
};
|
2022-09-26 20:01:07 +02:00
|
|
|
|
|
|
|
}
|