From c860152f9bfe9036bcdcb294f0bcb96a323d71bf Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Fri, 30 Jan 2026 01:04:23 +0300 Subject: [PATCH] Using threads more --- src/gamedata/CharacterAIModule.cpp | 79 ++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/src/gamedata/CharacterAIModule.cpp b/src/gamedata/CharacterAIModule.cpp index 0fa3961..7c844cb 100644 --- a/src/gamedata/CharacterAIModule.cpp +++ b/src/gamedata/CharacterAIModule.cpp @@ -9,7 +9,6 @@ #include "CharacterAIModule.h" namespace ECS { -#if 1 class ActionNodeActions { struct WalkToAction : public goap::BaseAction { int node; @@ -24,6 +23,21 @@ class ActionNodeActions { , node(node) { } + bool can_run(const Blackboard &state, + bool debug = false) override + { + return (state.distance_to(prereq) == 0); + } + void _plan_effects(Blackboard &state) override + { + const ActionNodeList &alist = + ECS::get(); + state.apply(effects); + // node position can change in case of character + const Ogre::Vector3 &nodePosition = + alist.dynamicNodes[node].position; + state.setPosition(nodePosition); + } int get_cost(const Blackboard &bb) const override { int ret = m_cost; @@ -35,21 +49,16 @@ class ActionNodeActions { { const ActionNodeList &alist = ECS::get(); - const TownNPCs &npcs = bb.town.get(); - const TownAI &ai = bb.town.get(); + // const TownNPCs &npcs = bb.town.get(); + // const TownAI &ai = bb.town.get(); const Ogre::Vector3 &nodePosition = - alist.nodes[node].position; - flecs::entity e = npcs.npcs.at(bb.index).e; - bool validActive = e.is_valid() && - e.has(); + alist.dynamicNodes[node].position; + // flecs::entity e = npcs.npcs.at(bb.index).e; + // bool validActive = e.is_valid() && + // e.has(); const Ogre::Vector3 &npcPosition = - validActive ? - npcs.npcs.at(bb.index) - .e.get() - .mBodyNode - ->_getDerivedPosition() : - npcs.npcs.at(bb.index).position; - float dist = nodePosition.squaredDistance( + bb.getPosition(); + float dist = npcPosition.squaredDistance( nodePosition); ret += (int)Ogre::Math::Ceil(dist); } @@ -59,6 +68,7 @@ out: }; struct RunActionNode : public goap::BaseAction { int node; + float radius; Ogre::String action; RunActionNode(int node, const Ogre::String &action, const Blackboard &prereq, @@ -72,6 +82,23 @@ out: , node(node) , action(action) { + const ActionNodeList &alist = + ECS::get(); + radius = alist.dynamicNodes[node].radius; + } + bool can_run(const Blackboard &state, + bool debug = false) override + { + bool pre = (state.distance_to(prereq) == 0); + if (!pre) + return pre; + const ActionNodeList &alist = + ECS::get(); + const Ogre::Vector3 &nodePosition = + alist.dynamicNodes[node].position; + const Ogre::Vector3 &npcPosition = state.getPosition(); + return (npcPosition.squaredDistance(nodePosition) < + radius * radius); } }; std::vector *> m_actions; @@ -155,7 +182,6 @@ public: return m_actions; } }; -#endif CharacterAIModule::CharacterAIModule(flecs::world &ecs) { static std::mutex ecs_mutex; @@ -299,11 +325,34 @@ CharacterAIModule::CharacterAIModule(flecs::world &ecs) std::lock_guard lock(ecs_mutex); ECS::get_mut().updateDynamicNodes(); }); + ecs.system("UpdateNPCPositions") + .kind(flecs::OnUpdate) + .each([](flecs::entity e, TownNPCs &npcs) { + for (auto it = npcs.npcs.begin(); it != npcs.npcs.end(); + it++) { + auto &npc = npcs.npcs.at(it->first); + if (npc.e.is_valid() && + npc.e.has()) + npc.position = + npc.e.get() + .mBodyNode + ->_getDerivedPosition(); + } + }); ecs.system("UpdateBlackboards") .kind(flecs::OnUpdate) .interval(0.1f) .each([this](flecs::entity town, ActionNodeList &alist, TownAI &ai, const TownNPCs &npcs) { + for (auto it = npcs.npcs.begin(); it != npcs.npcs.end(); + it++) { + const auto &npc = npcs.npcs.at(it->first); + if (ai.blackboards.find(it->first) == + ai.blackboards.end()) + continue; + ai.blackboards.at(it->first).setPosition( + npc.position); + } Ogre::Root::getSingleton().getWorkQueue()->addTask( [this, town, &alist, npcs, &ai]() { {