diff options
Diffstat (limited to 'src/include/tome/squelch/condition.hpp')
-rw-r--r-- | src/include/tome/squelch/condition.hpp | 632 |
1 files changed, 632 insertions, 0 deletions
diff --git a/src/include/tome/squelch/condition.hpp b/src/include/tome/squelch/condition.hpp new file mode 100644 index 00000000..584ecb0e --- /dev/null +++ b/src/include/tome/squelch/condition.hpp @@ -0,0 +1,632 @@ +#pragma once + +#include "tome/squelch/condition_fwd.hpp" + +#include <boost/noncopyable.hpp> +#include <cstdint> +#include <functional> +#include <memory> +#include <jsoncons/json.hpp> + +#include "tome/squelch/cursor_fwd.hpp" +#include "tome/squelch/tree_printer_fwd.hpp" +#include "tome/squelch/object_status_fwd.hpp" +#include "tome/enum_string_map.hpp" +#include "../object_type_fwd.hpp" + +namespace squelch { + +/** + * Types of matches used for conditions. + */ +enum class match_type { + AND , OR , NOT , NAME , CONTAIN , + INSCRIBED, DISCOUNT, SYMBOL , STATE , STATUS , + TVAL , SVAL , RACE , SUBRACE , CLASS , + LEVEL , SKILL , ABILITY, INVENTORY, EQUIPMENT }; + +/** + * Bidirectional map between enumeration values and strings. + */ +EnumStringMap<match_type> &match_mapping(); + +/** + * Identification states an object can have: identified or not + * identified. + */ +enum class identification_state { + IDENTIFIED, NOT_IDENTIFIED }; + +/** + * Biredectional map between identification_state values and strings. + */ +EnumStringMap<identification_state> &identification_state_mapping(); + +/** + * Condition represents a tree of checks which + * can be applied to objects, the player, etc. + */ +class Condition : public boost::noncopyable +{ +public: + Condition(match_type match_) : match(match_) { + } + + void display(TreePrinter *, Cursor *) const; + + virtual bool is_match(object_type *) const = 0; + + virtual ~Condition() { + } + +public: + jsoncons::json to_json() const; + + virtual void add_child(ConditionFactory const &factory) { + // Default is to not support children. + }; + + virtual void remove_child(Condition *c) { + // Nothing to do by default. + } + + virtual std::shared_ptr<Condition> first_child() { + // No children. + return nullptr; + } + + virtual std::shared_ptr<Condition> previous_child(Condition *) { + // Default no children, so no predecessor. + return nullptr; + } + + virtual std::shared_ptr<Condition> next_child(Condition *) { + // Default no children, so no successor. + return nullptr; + } + + /** + * Parse condition from JSON + */ + static std::shared_ptr<Condition> parse_condition(jsoncons::json const &); + + /** + * Convert an (optional) condition to JSON. + */ + static jsoncons::json optional_to_json(std::shared_ptr<Condition> condition); + +protected: + virtual void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const = 0; + virtual void to_json(jsoncons::json &) const = 0; + + // What do we want to match? + match_type match; +}; + +/** + * Check for a specific TVAL + */ +class TvalCondition : public Condition +{ +public: + TvalCondition(uint8_t tval) + : Condition(match_type::TVAL) + , m_tval(tval) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + uint8_t m_tval; +}; + +/** + * Check for object name + */ +class NameCondition : public Condition +{ +public: + NameCondition(std::string name) : + Condition(match_type::NAME), + m_name(name) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + std::string m_name; +}; + +/** + * Check for infix of object name + */ +class ContainCondition : public Condition +{ +public: + ContainCondition(std::string contain) : + Condition(match_type::CONTAIN), + m_contain(contain) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + std::string m_contain; +}; + +/** + * Check for specific SVAL + */ +class SvalCondition : public Condition +{ +public: + SvalCondition(uint8_t min, uint8_t max) + : Condition(match_type::SVAL) + , m_min(min) + , m_max(max) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + uint8_t m_min; + uint8_t m_max; +}; + +/** + * Groupings of subconditions + */ +class GroupingCondition : public Condition +{ +public: + GroupingCondition(match_type match, + std::vector< std::shared_ptr<Condition> > conditions = std::vector< std::shared_ptr<Condition> >()) + : Condition(match) + , m_conditions(conditions) { + } + + virtual void add_condition(std::shared_ptr<Condition> condition) { + if (condition) + { + m_conditions.push_back(condition); + } + } + + // Child manipulation + virtual void add_child(ConditionFactory const &factory) override; + virtual void remove_child(Condition *condition) override; + virtual std::shared_ptr<Condition> first_child() override; + virtual std::shared_ptr<Condition> previous_child(Condition *) override; + virtual std::shared_ptr<Condition> next_child(Condition *current) override; + + // Parse a list of conditions from JSON property + static std::vector< std::shared_ptr<Condition> > parse_conditions(jsoncons::json const &); + +protected: + void to_json(jsoncons::json &) const override; + +protected: + std::vector< std::shared_ptr<Condition> > m_conditions; +}; + +/** + * Conditions that are AND'ed together + */ +class AndCondition : public GroupingCondition +{ +public: + AndCondition() : GroupingCondition(match_type::AND) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; +}; + +/** + * Conditions that are OR'ed together + */ +class OrCondition : public GroupingCondition +{ +public: + OrCondition() : GroupingCondition(match_type::OR) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; +}; + +/** + * Check for object status + */ +class StatusCondition : public Condition +{ +public: + StatusCondition(status_type status) + : Condition(match_type::STATUS) + , m_status(status) { + } + +public: + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + status_type m_status; +}; + +/** + * Check for player race + */ +class RaceCondition : public Condition +{ +public: + RaceCondition(std::string race) + : Condition(match_type::RACE) + , m_race(race) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + std::string m_race; +}; + +/** + * Check player subrace + */ +class SubraceCondition : public Condition +{ +public: + SubraceCondition(std::string subrace) + : Condition(match_type::SUBRACE) + , m_subrace(subrace) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + std::string m_subrace; +}; + +/** + * Check player class + */ +class ClassCondition : public Condition +{ +public: + ClassCondition(std::string klass) + : Condition(match_type::CLASS) + , m_class(klass) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + std::string m_class; +}; + +/** + * Check object inscription + */ +class InscriptionCondition : public Condition +{ +public: + InscriptionCondition(std::string inscription) + : Condition(match_type::INSCRIBED) + , m_inscription(inscription) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + std::string m_inscription; +}; + +/** + * Check object discount + */ +class DiscountCondition : public Condition +{ +public: + DiscountCondition(int min, int max) + : Condition(match_type::DISCOUNT) + , m_min(min) + , m_max(max) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + int m_min; + int m_max; +}; + +/** + * Check player level + */ +class LevelCondition : public Condition +{ +public: + LevelCondition(int min, int max) + : Condition(match_type::LEVEL) + , m_min(min) + , m_max(max) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + int m_min; + int m_max; +}; + +/** + * Check player's skill level + */ +class SkillCondition : public Condition +{ +public: + SkillCondition(uint16_t skill_idx, uint16_t min, uint16_t max) + : Condition(match_type::SKILL) + , m_skill_idx(skill_idx) + , m_min(min) + , m_max(max) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + uint16_t m_skill_idx; + uint16_t m_min; + uint16_t m_max; +}; + +/** + * Check identification state + */ +class StateCondition : public Condition +{ +public: + StateCondition(identification_state state) + : Condition(match_type::STATE) + , m_state(state) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + identification_state m_state; +}; + +/** + * Check object symbol + */ +class SymbolCondition : public Condition +{ +public: + SymbolCondition(char symbol) + : Condition(match_type::SYMBOL) + , m_symbol(symbol) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + char m_symbol; +}; + +/** + * Check if player has a particular ability + */ +class AbilityCondition : public Condition +{ +public: + AbilityCondition(uint16_t ability_idx) + : Condition(match_type::ABILITY) + , m_ability_idx(ability_idx) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; + + void to_json(jsoncons::json &) const override; + +private: + uint16_t m_ability_idx; +}; + +/** + * Condition with a single subcondition + */ +class SingleSubconditionCondition : public Condition +{ +public: + SingleSubconditionCondition(match_type match, + std::shared_ptr<Condition> subcondition) + : Condition(match) + , m_subcondition(subcondition) { + } + + virtual void add_child(std::function< std::shared_ptr<Condition> () > const &factory) override; + + virtual void remove_child(Condition *c) override; + + virtual std::shared_ptr<Condition> first_child() override; + +protected: + void to_json(jsoncons::json &) const override; + + static std::shared_ptr<Condition> parse_single_subcondition( + jsoncons::json const &condition_json); + +protected: + std::shared_ptr<Condition> m_subcondition; +}; + +/** + * Condition which negates another condition + */ +class NotCondition : public SingleSubconditionCondition +{ +public: + NotCondition(std::shared_ptr<Condition> subcondition = nullptr) + : SingleSubconditionCondition(match_type::NOT, subcondition) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; +}; + +/** + * Condition which checks if player inventory contains object(s) + * satisfying another condition. + */ +class InventoryCondition : public SingleSubconditionCondition +{ +public: + InventoryCondition(std::shared_ptr<Condition> subcondition = nullptr) + : SingleSubconditionCondition(match_type::INVENTORY, subcondition) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; +}; + +/** + * Condition which checks if player equipment contains object(s) + * satisfying another condition. + */ +class EquipmentCondition : public SingleSubconditionCondition +{ +public: + EquipmentCondition(std::shared_ptr<Condition> subcondition = nullptr) + : SingleSubconditionCondition(match_type::EQUIPMENT, subcondition) { + } + + bool is_match(object_type *) const override; + + static std::shared_ptr<Condition> from_json(jsoncons::json const &); + +protected: + void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; +}; + +} // namespace |