diff --git a/include/reone/game/object/creature.h b/include/reone/game/object/creature.h index 6051ab53b..0613541bb 100644 --- a/include/reone/game/object/creature.h +++ b/include/reone/game/object/creature.h @@ -203,6 +203,7 @@ class Creature : public Object, public scene::IAnimationEventListener { // END Equipment // Pathfinding + bool navigateToObject(const Object &object, bool run, float distance, float dt); bool navigateTo(const glm::vec3 &dest, bool run, float distance, float dt); void clearPath(); void advanceOnPath(const glm::vec3 &dest, const glm::vec3 &dir, bool run, float distance, float dt); diff --git a/src/libs/game/action/closedoor.cpp b/src/libs/game/action/closedoor.cpp index 2b24f7908..b719de436 100644 --- a/src/libs/game/action/closedoor.cpp +++ b/src/libs/game/action/closedoor.cpp @@ -28,7 +28,7 @@ namespace game { void CloseDoorAction::execute(std::shared_ptr self, Object &actor, float dt) { auto creatureActor = _game.getObjectById(actor.id()); - bool reached = !creatureActor || creatureActor->navigateTo(_door->position(), true, kDefaultMaxObjectDistance, dt); + bool reached = !creatureActor || creatureActor->navigateToObject(*_door, true, kDefaultMaxObjectDistance, dt); if (reached) { _door->close(); complete(); diff --git a/src/libs/game/action/commonactions.cpp b/src/libs/game/action/commonactions.cpp index c065cfec3..161688357 100644 --- a/src/libs/game/action/commonactions.cpp +++ b/src/libs/game/action/commonactions.cpp @@ -56,7 +56,7 @@ void tryUnlockDoorWithKey(Door &door, Object &actor, Party &party) { bool unlockDoor(Door &door, Object &actor, float distance, float dt) { if (actor.type() == ObjectType::Creature) { auto &creature = static_cast(actor); - bool reached = creature.navigateTo(door.position(), true, distance, dt); + bool reached = creature.navigateToObject(door, true, distance, dt); if (!reached) { return false; } @@ -80,7 +80,7 @@ bool unlockDoor(Door &door, Object &actor, float distance, float dt) { bool unlockPlaceable(Placeable &placeable, Object &actor, float distance, float dt) { if (auto *creature = dyn_cast(&actor)) { - bool reached = creature->navigateTo(placeable.position(), true, distance, dt); + bool reached = creature->navigateToObject(placeable, true, distance, dt); if (!reached) { return false; } diff --git a/src/libs/game/action/follow.cpp b/src/libs/game/action/follow.cpp index 0bf254a63..44eb050c0 100644 --- a/src/libs/game/action/follow.cpp +++ b/src/libs/game/action/follow.cpp @@ -35,7 +35,7 @@ void FollowAction::execute(std::shared_ptr self, Object &actor, float dt float distance2 = creatureActor->getSquareDistanceTo(glm::vec2(dest)); bool run = distance2 > kDistanceWalk * kDistanceWalk; - if (creatureActor->navigateTo(dest, run, _followDistance, dt)) { + if (creatureActor->navigateToObject(*_follow, run, _followDistance, dt)) { complete(); } } diff --git a/src/libs/game/action/followleader.cpp b/src/libs/game/action/followleader.cpp index de8b3726f..034de937a 100644 --- a/src/libs/game/action/followleader.cpp +++ b/src/libs/game/action/followleader.cpp @@ -47,7 +47,7 @@ void FollowLeaderAction::execute(std::shared_ptr self, Object &actor, fl float distance2 = creatureActor->getSquareDistanceTo(glm::vec2(destination)); bool run = distance2 > kDistanceWalk; - if (creatureActor->navigateTo(destination, run, kDefaultFollowDistance, dt)) { + if (creatureActor->navigateToObject(*leader, run, kDefaultFollowDistance, dt)) { complete(); } } diff --git a/src/libs/game/action/movetoobject.cpp b/src/libs/game/action/movetoobject.cpp index f474f113d..0c57097fd 100644 --- a/src/libs/game/action/movetoobject.cpp +++ b/src/libs/game/action/movetoobject.cpp @@ -93,7 +93,13 @@ void MoveToObjectAction::execute(std::shared_ptr self, Object &actor, fl } } - bool reached = creatureActor->navigateTo(dest, _run, _range, dt); + bool reached = false; + if (_moveTo) { + reached = creatureActor->navigateToObject(*_moveTo, _run, _range, dt); + } else { + reached = creatureActor->navigateTo(dest, _run, _range, dt); + } + if (reached) { complete(); } diff --git a/src/libs/game/action/opencontainer.cpp b/src/libs/game/action/opencontainer.cpp index 758282780..f04e7f72c 100644 --- a/src/libs/game/action/opencontainer.cpp +++ b/src/libs/game/action/opencontainer.cpp @@ -39,7 +39,7 @@ void OpenContainerAction::execute(std::shared_ptr self, Object &actor, f } auto &creatureActor = cast(actor); - bool reached = creatureActor.navigateTo(_object->position(), true, kDefaultMaxObjectDistance, dt); + bool reached = creatureActor.navigateToObject(*_object, true, kDefaultMaxObjectDistance, dt); if (reached) { _game.openContainer(_object); complete(); diff --git a/src/libs/game/action/opendoor.cpp b/src/libs/game/action/opendoor.cpp index 59697b4ae..d08bed80f 100644 --- a/src/libs/game/action/opendoor.cpp +++ b/src/libs/game/action/opendoor.cpp @@ -31,7 +31,7 @@ namespace game { void OpenDoorAction::execute(std::shared_ptr self, Object &actor, float dt) { if (actor.type() == ObjectType::Creature) { auto &creature = static_cast(actor); - bool reached = creature.navigateTo(_door->position(), true, kDefaultMaxObjectDistance, dt); + bool reached = creature.navigateToObject(*_door, true, kDefaultMaxObjectDistance, dt); if (!reached) { return; } diff --git a/src/libs/game/action/startconversation.cpp b/src/libs/game/action/startconversation.cpp index 706bee004..72e4a13c6 100644 --- a/src/libs/game/action/startconversation.cpp +++ b/src/libs/game/action/startconversation.cpp @@ -71,7 +71,7 @@ void StartConversationAction::execute(std::shared_ptr self, Object &acto } bool reached = _ignoreStartRange || - creatureActor->navigateTo(_objectToConverse->position(), true, kMaxConversationDistance, dt); + creatureActor->navigateToObject(*_objectToConverse, true, kMaxConversationDistance, dt); if (!reached) { return; diff --git a/src/libs/game/attack.cpp b/src/libs/game/attack.cpp index 8f1fc6606..f51d3e3e5 100644 --- a/src/libs/game/attack.cpp +++ b/src/libs/game/attack.cpp @@ -1149,7 +1149,7 @@ bool navigateToAttackTarget(Creature &attacker, Object &target, float dt, bool & return true; } - if (!attacker.navigateTo(target.position(), true, attacker.getAttackRange(), dt)) { + if (!attacker.navigateToObject(target, true, attacker.getAttackRange(), dt)) { return false; } diff --git a/src/libs/game/object/creature.cpp b/src/libs/game/object/creature.cpp index 621e45e3f..6c08af05e 100644 --- a/src/libs/game/object/creature.cpp +++ b/src/libs/game/object/creature.cpp @@ -2294,6 +2294,16 @@ glm::vec3 Creature::computeSteeringForce(const Uniwalk &uni, const glm::vec3 &ne return combinedForce; } +bool Creature::navigateToObject(const Object &object, bool run, float distance, float dt) { + float epsilon = 0.2f; + float minDistance = creaturePersonalSpace() + epsilon; + if (auto creature = dyn_cast(&object)) { + minDistance += creature->creaturePersonalSpace(); + } + glm::vec3 dest = object.position(); + return navigateTo(dest, run, std::max(minDistance, distance), dt); +} + bool Creature::navigateTo(const glm::vec3 &dest, bool run, float distance, float dt) { if (_movementRestricted) return false;