1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-16 10:19:47 +02:00
vcmi/AI/Nullkiller/Goals/AbstractGoal.h

220 lines
4.5 KiB
C++
Raw Normal View History

2021-05-15 18:22:44 +02:00
/*
* AbstractGoal.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/VCMI_Lib.h"
#include "../../../lib/mapObjects/CGTownInstance.h"
#include "../../../lib/mapObjects/CGHeroInstance.h"
2021-05-15 18:22:44 +02:00
#include "../AIUtility.h"
2022-09-26 20:01:07 +02:00
namespace NKAI
{
2021-05-15 18:22:44 +02:00
struct HeroPtr;
2021-05-16 14:39:38 +02:00
class AIGateway;
2021-05-15 18:22:44 +02:00
class FuzzyHelper;
2024-03-31 17:39:00 +02:00
class Nullkiller;
2021-05-15 18:22:44 +02:00
namespace Goals
{
class AbstractGoal;
class ITask;
2021-05-15 18:22:44 +02:00
class RecruitHero;
class BuildThis;
class DigAtTile;
class CollectRes;
class BuyArmy;
class BuildBoat;
class Invalid;
class Trade;
class AdventureSpellCast;
enum EGoals
{
INVALID = -1,
WIN, CONQUER,
BUILD,
2021-05-15 18:22:44 +02:00
EXPLORE, GATHER_ARMY,
BOOST_HERO,
RECRUIT_HERO,
2021-05-16 13:38:53 +02:00
RECRUIT_HERO_BEHAVIOR,
2021-05-15 18:22:44 +02:00
BUILD_STRUCTURE, //if hero set, then in visited town
COLLECT_RES,
GATHER_TROOPS, // val of creatures with objid
2021-05-16 13:38:53 +02:00
CAPTURE_OBJECTS,
2021-05-15 18:22:44 +02:00
GET_ART_TYPE,
2021-05-16 13:38:53 +02:00
DEFENCE,
STARTUP,
2021-05-15 18:22:44 +02:00
DIG_AT_TILE,//elementar with hero on tile
BUY_ARMY, //at specific town
TRADE, //val resID at object objid
BUILD_BOAT,
COMPLETE_QUEST,
2021-05-15 20:56:31 +02:00
ADVENTURE_SPELL_CAST,
2021-05-15 21:02:52 +02:00
EXECUTE_HERO_CHAIN,
EXCHANGE_SWAP_TOWN_HEROES,
2021-05-16 13:38:53 +02:00
DISMISS_HERO,
2021-05-16 13:45:12 +02:00
COMPOSITION,
CLUSTER_BEHAVIOR,
UNLOCK_CLUSTER,
HERO_EXCHANGE,
2021-05-16 14:00:24 +02:00
ARMY_UPGRADE,
DEFEND_TOWN,
2021-05-16 14:39:38 +02:00
CAPTURE_OBJECT,
2023-09-24 12:07:42 +02:00
SAVE_RESOURCES,
STAY_AT_TOWN_BEHAVIOR,
2024-05-19 09:04:45 +02:00
STAY_AT_TOWN,
EXPLORATION_BEHAVIOR,
2024-05-22 21:49:11 +02:00
EXPLORATION_POINT,
EXPLORE_NEIGHBOUR_TILE
2021-05-15 18:22:44 +02:00
};
class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>
{
public:
bool operator==(const TSubgoal & rhs) const;
bool operator<(const TSubgoal & rhs) const;
};
2023-04-17 23:11:16 +02:00
using TTask = std::shared_ptr<ITask>;
using TTaskVec = std::vector<TTask>;
using TGoalVec = std::vector<TSubgoal>;
2021-05-15 18:22:44 +02:00
//method chaining + clone pattern
2021-05-16 14:10:35 +02:00
#define SETTER(type, field) AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
2021-05-15 18:22:44 +02:00
enum { LOW_PR = -1 };
DLL_EXPORT TSubgoal sptr(const AbstractGoal & tmp);
DLL_EXPORT TTask taskptr(const AbstractGoal & tmp);
2021-05-16 13:38:53 +02:00
2021-05-15 18:22:44 +02:00
class DLL_EXPORT AbstractGoal
{
public:
2021-05-16 14:10:35 +02:00
bool isAbstract; SETTER(bool, isAbstract)
int value; SETTER(int, value)
ui64 goldCost; SETTER(ui64, goldCost)
int resID; SETTER(int, resID)
int objid; SETTER(int, objid)
int aid; SETTER(int, aid)
int3 tile; SETTER(int3, tile)
const CGHeroInstance * hero; SETTER(CGHeroInstance *, hero)
2021-05-16 14:10:35 +02:00
const CGTownInstance *town; SETTER(CGTownInstance *, town)
int bid; SETTER(int, bid)
2023-04-17 23:11:16 +02:00
AbstractGoal(EGoals goal = EGoals::INVALID): goalType(goal)
2021-05-15 18:22:44 +02:00
{
isAbstract = false;
value = 0;
aid = -1;
resID = -1;
objid = -1;
tile = int3(-1, -1, -1);
town = nullptr;
hero = nullptr;
2021-05-15 18:22:44 +02:00
bid = -1;
2021-05-16 13:38:53 +02:00
goldCost = 0;
2021-05-15 18:22:44 +02:00
}
virtual ~AbstractGoal() {}
//FIXME: abstract goal should be abstract, but serializer fails to instantiate subgoals in such case
virtual AbstractGoal * clone() const
{
return const_cast<AbstractGoal *>(this);
}
2024-03-31 17:39:00 +02:00
virtual TGoalVec decompose(const Nullkiller * ai) const
2021-05-15 18:22:44 +02:00
{
return TGoalVec();
}
EGoals goalType;
virtual std::string toString() const;
2021-05-15 18:22:44 +02:00
bool invalid() const;
2021-05-15 18:22:44 +02:00
virtual bool operator==(const AbstractGoal & g) const;
2021-05-16 13:38:53 +02:00
virtual bool isElementar() const { return false; }
virtual bool hasHash() const { return false; }
virtual uint64_t getHash() const { return 0; }
virtual ITask * asTask()
{
throw std::runtime_error("Abstract goal is not a task");
}
2021-05-15 18:22:44 +02:00
bool operator!=(const AbstractGoal & g) const
{
return !(*this == g);
}
};
class DLL_EXPORT ITask
{
public:
float priority;
2021-05-16 13:38:53 +02:00
ITask() : priority(0) {}
///Visitor pattern
//TODO: make accept work for std::shared_ptr... somehow
2021-05-16 14:39:38 +02:00
virtual void accept(AIGateway * ai) = 0; //unhandled goal will report standard error
virtual std::string toString() const = 0;
virtual const CGHeroInstance * getHero() const = 0;
2021-05-16 13:38:53 +02:00
virtual ~ITask() {}
2022-09-06 20:14:22 +02:00
virtual int getHeroExchangeCount() const = 0;
virtual bool isObjectAffected(ObjectInstanceID h) const = 0;
virtual std::vector<ObjectInstanceID> getAffectedObjects() const = 0;
};
2021-05-15 18:22:44 +02:00
}
2021-05-16 13:55:47 +02:00
class cannotFulfillGoalException : public std::exception
{
std::string msg;
public:
2022-09-26 20:01:07 +02:00
explicit cannotFulfillGoalException(const std::string & message)
: msg(message)
2021-05-16 13:55:47 +02:00
{
}
2024-02-13 23:42:31 +02:00
const char * what() const noexcept override
2021-05-16 13:55:47 +02:00
{
return msg.c_str();
}
};
class goalFulfilledException : public std::exception
{
std::string msg;
public:
Goals::TSubgoal goal;
explicit goalFulfilledException(Goals::TSubgoal Goal)
: goal(Goal)
{
msg = goal->toString();
}
2024-02-13 23:42:31 +02:00
const char * what() const noexcept override
2021-05-16 13:55:47 +02:00
{
return msg.c_str();
}
};
2022-09-26 20:01:07 +02:00
}