diff --git a/src/gamedata/CharacterAIModule.cpp b/src/gamedata/CharacterAIModule.cpp index edd6d66..4806c21 100644 --- a/src/gamedata/CharacterAIModule.cpp +++ b/src/gamedata/CharacterAIModule.cpp @@ -376,6 +376,129 @@ CharacterAIModule::CharacterAIModule(flecs::world &ecs) }); }); }); + struct ActionExec { + enum { OK = 0, BUSY, ERROR }; + TownNPCs::NPCData &npc; + Blackboard &bb; + nlohmann::json &memory; + bool complete; + bool active; + const goap::BaseAction *action; + ActionExec(TownNPCs::NPCData &npc, Blackboard &bb, + nlohmann::json &memory, + const goap::BaseAction *action) + : npc(npc) + , bb(bb) + , memory(memory) + , complete(false) + , active(false) + , action(action) + { + } + ActionExec(const ActionExec &other) + : npc(other.npc) + , bb(other.bb) + , memory(other.memory) + , complete(other.complete) + , active(other.active) + , action(other.action) + { + } + ActionExec &operator=(const ActionExec &other) + { + npc = other.npc; + bb = other.bb; + memory = other.memory; + complete = other.complete; + active = other.active; + action = other.action; + return *this; + } + + private: + int update(float delta) + { + return OK; + } + void finish(int result) + { + } + void activate() + { + std::cout << action->get_name(); + OgreAssert(false, "activate"); + } + + public: + int operator()(float delta) + { + if (!active) + activate(); + int ret = update(delta); + if (ret != BUSY) + finish(ret); + return ret; + } + }; + struct PlanExec { + enum { OK = 0, BUSY, ERROR }; + std::vector action_exec; + int index; + PlanExec() + : index(-1) + { + } + int operator()(float delta) + { + if (index == -1) + index = 0; + int rc = action_exec[index](delta); + if (rc == ActionExec::ERROR) + return ERROR; + if (action_exec[index].complete) + index++; + if (index >= action_exec.size()) + return OK; + return BUSY; + } + }; + static std::unordered_map plan_exec; + ecs.system("RunPLAN") + .kind(flecs::OnUpdate) + .each([&](flecs::entity town, const EngineData &eng, + TownNPCs &npcs, TownAI &ai) { + for (const auto &plans : ai.plans) { + if (plan_exec.find(plans.first) != + plan_exec.end()) { + plan_exec[plans.first](eng.delta); + continue; + } + std::cout << "NPC: " << plans.first; + std::cout << " Plans: " << plans.second.size(); + for (const auto &plan : plans.second) { + struct PlanExec pexec; + if (plan.plan.size() == 0) + continue; + std::cout << " Goal: "; + plan.goal->goal.dump_bits(); + for (const auto &action : plan.plan) { + pexec.action_exec.emplace_back( + npcs.npcs.at( + plans.first), + ai.blackboards.at( + plans.first), + ai.memory.at( + plans.first), + action); + std::cout << action->get_name() + << " "; + } + plan_exec[plans.first] = pexec; + break; + } + std::cout << std::endl; + } + }); } void CharacterAIModule::createAI(flecs::entity town) diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 8c94016..c6d5084 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -576,7 +576,10 @@ public: , object_vs_object_layer_filter{} , debugDraw(false) { - // Create a factory, this class is responsible for creating instances of classes based on their name or hash and is mainly used for deserialization of saved data. + static int instanceCount = 0; + OgreAssert(instanceCount == 0, "Bad initialisation"); + instanceCount++; + // Create a factory, this class is responsible for creating instances of classes based on their name or hash and is mainly used for deserialization of saved data. // It is not directly used in this example but still required. JPH::Factory::sInstance = new JPH::Factory();