#include "rituals.hpp" #include "ai_debug.hpp" #include "ai.hpp" namespace combat { RitualEngine::RitualEngine(std::string config_path) : $config(config_path) { $profile = $config["profile"]; auto& actions = $config["actions"]; for(auto& ac : actions) { auto action = ai::config_action($profile, ac); $actions.insert_or_assign(action.name, action); } for(auto& [name, sc] : $config["states"].items()) { auto state = ai::config_state($profile, sc); $states.insert_or_assign(name, state); } auto& scripts = $config["scripts"]; for(auto& [script_name, action_names] : scripts.items()) { std::vector the_script; for(auto name : action_names) { the_script.push_back($actions.at(name)); } $scripts.insert_or_assign(script_name, the_script); } } ai::State RitualEngine::load_state(std::string name) { return $states.at(name); } ai::Action RitualEngine::load_action(std::string name) { return $actions.at(name); } RitualAI RitualEngine::start() { auto start = load_state("initial"); auto goal = load_state("final"); return {"actions", start, goal}; } void RitualEngine::set_state(RitualAI& ritual, std::string name, bool setting) { ritual.start.set($profile.at(name), setting); } void RitualEngine::reset(RitualAI& ritual) { ritual.start = ritual.original; } void RitualEngine::plan(RitualAI& ritual) { ritual.plan = ai::plan_actions($scripts.at(ritual.script), ritual.start, ritual.goal); } bool RitualAI::will_do(std::string name) { if(plan.script.size() == 0) return false; return plan.script[0].name == name; } ai::Action RitualAI::pop() { auto result = plan.script.front(); plan.script.pop_front(); return result; } void RitualAI::dump() { ai::dump_script(script, start, plan.script); } RitualAction RitualEngine::finalize(RitualAI& ritual) { (void)ritual; RitualAction result; auto effects = $config["effects"]; for(auto action : ritual.plan.script) { if(effects.contains(action.name)) { auto& effect = effects[action.name]; result.damage += int(effect["damage"]); result.probability *= float(effect["probability"]); result.kind = RitualKind(int(effect["kind"])); result.element = RitualElement(int(effect["element"])); } } return result; } void RitualAction::dump() { fmt::print("ritual has damage {}, prob: {}, kind: {}, element: {}; named: ", damage, probability, int(kind), int(element)); for(auto& name : names) { fmt::print("{} ", name); } fmt::println("\n"); } }