From 0b288fefcccc8c228044ae8319f053f5408264a1 Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Thu, 31 Aug 2017 13:53:10 +0300 Subject: Pathfinder DontCare now a member variable --- src/Mobs/Behaviors/BehaviorAttacker.cpp | 1 - src/Mobs/Behaviors/BehaviorDayLightBurner.cpp | 5 +---- src/Mobs/Behaviors/BehaviorWanderer.cpp | 18 ++++++++++++++++++ src/Mobs/Behaviors/BehaviorWanderer.h | 4 +++- src/Mobs/Monster.cpp | 14 ++++++++++++-- src/Mobs/Monster.h | 13 ++++++++++++- src/Mobs/PathFinder.cpp | 27 +++++++++++++++++++++++---- src/Mobs/PathFinder.h | 18 ++++++++++++++---- 8 files changed, 83 insertions(+), 17 deletions(-) (limited to 'src/Mobs') diff --git a/src/Mobs/Behaviors/BehaviorAttacker.cpp b/src/Mobs/Behaviors/BehaviorAttacker.cpp index 67a27a277..031b5ddf9 100644 --- a/src/Mobs/Behaviors/BehaviorAttacker.cpp +++ b/src/Mobs/Behaviors/BehaviorAttacker.cpp @@ -2,7 +2,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BehaviorAttacker.h" -#include "BehaviorStriker.h" #include "../Monster.h" #include "../../Entities/Pawn.h" #include "../../Entities/Player.h" diff --git a/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp b/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp index ab234e56f..0b0faed08 100644 --- a/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp +++ b/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp @@ -23,9 +23,6 @@ void cBehaviorDayLightBurner::AttachToMonster(cMonster & a_Parent) void cBehaviorDayLightBurner::PostTick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { - // mobTodo WouldBurn - bool WouldBurn = false; // TEMP - int RelY = static_cast(m_Parent->GetPosY()); if ((RelY < 0) || (RelY >= cChunkDef::Height)) { @@ -38,7 +35,7 @@ void cBehaviorDayLightBurner::PostTick(std::chrono::milliseconds a_Dt, cChunk & return; } - if (!m_Parent->IsOnFire() && WouldBurn) + if (!m_Parent->IsOnFire() && WouldBurnAt(m_Parent->GetPosition(), a_Chunk)) { // Burn for 100 ticks, then decide again m_Parent->StartBurning(100); diff --git a/src/Mobs/Behaviors/BehaviorWanderer.cpp b/src/Mobs/Behaviors/BehaviorWanderer.cpp index b57d5f033..309883c01 100644 --- a/src/Mobs/Behaviors/BehaviorWanderer.cpp +++ b/src/Mobs/Behaviors/BehaviorWanderer.cpp @@ -35,6 +35,24 @@ bool cBehaviorWanderer::IsControlDesired(std::chrono::milliseconds a_Dt, cChunk +bool cBehaviorWanderer::ControlStarting(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + UNUSED(a_Chunk); + m_OldDontCare = m_Parent->GetPathFinder().getDontCare(true); + m_Parent->GetPathFinder().setDontCare(true); // We don't care we're we are going when + // wandering. If a path is not found, the pathfinder just modifies our destination. + return true; +} + + +bool cBehaviorWanderer::ControlEnding(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + UNUSED(a_Chunk); + m_Parent->GetPathFinder().setDontCare(m_OldDontCare); + return true; +} void cBehaviorWanderer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) diff --git a/src/Mobs/Behaviors/BehaviorWanderer.h b/src/Mobs/Behaviors/BehaviorWanderer.h index c694eb331..219ad32c3 100644 --- a/src/Mobs/Behaviors/BehaviorWanderer.h +++ b/src/Mobs/Behaviors/BehaviorWanderer.h @@ -13,11 +13,13 @@ public: // Functions our host Monster should invoke: bool IsControlDesired(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + bool ControlStarting(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; + bool ControlEnding(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; private: cMonster * m_Parent; // Our Parent - std::chrono::milliseconds m_IdleInterval; + bool m_OldDontCare; }; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index fc1c1678d..51bc0637b 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -433,7 +433,7 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { // mobToDo fix dont care // Note that m_NextWayPointPosition is actually returned by GetNextWayPoint) - switch (m_PathFinder.GetNextWayPoint(*Chunk, GetPosition(), &m_FinalDestination, &m_NextWayPointPosition, true)) + switch (m_PathFinder.GetNextWayPoint(*Chunk, GetPosition(), &m_FinalDestination, &m_NextWayPointPosition)) { case ePathFinderStatus::PATH_FOUND: { @@ -468,7 +468,8 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) } default: { - + // NEARBY_FOUND is handled internally by cPathFinder. + // Do nothing if CALCULATING. } } } @@ -1378,6 +1379,15 @@ void cMonster::UnpinBehavior(cBehavior * a_Behavior) +cPathFinder & cMonster::GetPathFinder() +{ + return m_PathFinder; +} + + + + + cMonster::eFamily cMonster::GetMobFamily(void) const { return FamilyFromType(m_MobType); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 1ed443aad..760edb0e9 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -221,9 +221,20 @@ public: void AttachRightClickBehavior(cBehavior * a_Behavior); void AttachDoTakeDamageBehavior(cBehavior * a_Behavior); + /** If a behavior calls this within its tick, it will be the only behavior + that gets to tick until UnpinBehavior is called. ControlDesired will no + longer be called for any tick until unpinning is done. MUST be called + from the tick function of a behavior. */ void PinBehavior(cBehavior * a_Behavior); + + /** Unpins the behavior and ticking goes back to normal. MUST be called + on the same behavior pointer that called PinBehavior. */ void UnpinBehavior(cBehavior * a_Behavior); - protected: + + /** Returns a reference to this mob's pathfinder. Typically used by behaviors + to tweak pathfinding behavior as they gain or release control of the mob. */ + cPathFinder & GetPathFinder(); +protected: /** Whether or not m_NearestPlayer is stale. Always true at the beginning of a tick. When true, GetNearestPlayer() actually searches for a player, updates m_NearestPlayer, and sets it to false. diff --git a/src/Mobs/PathFinder.cpp b/src/Mobs/PathFinder.cpp index 93664b596..ca5df2cd6 100644 --- a/src/Mobs/PathFinder.cpp +++ b/src/Mobs/PathFinder.cpp @@ -9,7 +9,8 @@ cPathFinder::cPathFinder(double a_MobWidth, double a_MobHeight) : m_Path(), m_GiveUpCounter(0), - m_NotFoundCooldown(0) + m_NotFoundCooldown(0), + m_DontCare(false) { m_Width = a_MobWidth; m_Height = a_MobHeight; @@ -19,7 +20,7 @@ cPathFinder::cPathFinder(double a_MobWidth, double a_MobHeight) : -ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d & a_Source, Vector3d * a_Destination, Vector3d * a_OutputWaypoint, bool a_DontCare) +ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d & a_Source, Vector3d * a_Destination, Vector3d * a_OutputWaypoint) { m_FinalDestination = *a_Destination; m_Source = a_Source; @@ -65,7 +66,7 @@ ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d { m_NoPathToTarget = true; m_PathDestination = m_Path->AcceptNearbyPath(); - if (a_DontCare) + if (m_DontCare) { m_FinalDestination = m_PathDestination; *a_Destination = m_FinalDestination; // Modify the mob's final destination because it doesn't care about reaching an exact spot @@ -93,7 +94,7 @@ ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d if (m_GiveUpCounter == 0) { - if (a_DontCare) + if (m_DontCare) { // We're having trouble reaching the next waypoint but the mob // Doesn't care where to go, just tell him we got there ;) @@ -166,6 +167,24 @@ ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d +void cPathFinder::setDontCare(bool a_DontCare) +{ + m_DontCare = a_DontCare; +} + + + + + +bool cPathFinder::getDontCare() +{ + return m_DontCare; +} + + + + + void cPathFinder::ResetPathFinding(cChunk &a_Chunk) { m_GiveUpCounter = 40; diff --git a/src/Mobs/PathFinder.h b/src/Mobs/PathFinder.h index 213530b11..19f1d0c14 100644 --- a/src/Mobs/PathFinder.h +++ b/src/Mobs/PathFinder.h @@ -25,8 +25,9 @@ public: @param a_Source The mob's position. a_Source's coordinates are expected to be within the chunk given in a_Chunk. @param a_Destination The position the mob would like to reach. If a_ExactPath is true, the PathFinder may modify this. @param a_OutputWaypoint An output parameter: The next waypoint to go to. - @param a_DontCare If true, the mob doesn't care where to go, and the Pathfinder may modify a_Destination. - This should usually be false. An exception is a wandering idle mob which doesn't care about its final destination. + + If m_DontCare is true, the mob doesn't care where to go, and the Pathfinder may modify a_Destination. + This should usually be false. One exception is a wandering idle mob which doesn't care about its final destination. In the future, idle mobs shouldn't use A* at all. Returns an ePathFinderStatus. @@ -36,8 +37,13 @@ public: ePathFinderStatus:PATH_NOT_FOUND - The PathFinder did not find a destination to the target. Nothing was written to a_OutputWaypoint. The mob should probably not move. Note: Once NEARBY_FOUND is returned once, subsequent calls return PATH_FOUND. */ - ePathFinderStatus GetNextWayPoint(cChunk & a_Chunk, const Vector3d & a_Source, Vector3d * a_Destination, Vector3d * a_OutputWaypoint, bool a_DontCare = false); + ePathFinderStatus GetNextWayPoint(cChunk & a_Chunk, const Vector3d & a_Source, Vector3d * a_Destination, Vector3d * a_OutputWaypoint); + + /** Sets the dontCare value. See the GetNextWayPoint documentation for details. */ + void setDontCare(bool a_DontCare); + /** Returns the current dontCare value. */ + bool getDontCare(); private: /** The width of the Mob which owns this PathFinder. */ @@ -55,7 +61,7 @@ private: /** Coordinates of the next position that should be reached. */ Vector3d m_WayPoint; - /** Coordinates for where we should go. This is out ultimate, final destination. */ + /** Coordinates for where we should go. This is our ultimate, final destination. */ Vector3d m_FinalDestination; /** Coordinates for where we are practically going. */ @@ -75,6 +81,10 @@ private: /** When a path is not found, this cooldown prevents any recalculations for several ticks. */ int m_NotFoundCooldown; + /** If true, the mob doesn't care where to go, and the Pathfinder may modify a_Destination + in an GetNextWayPoint call. */ + bool m_DontCare; + /** Ensures the location is not in the air or under water. May change the Y coordinate of the given vector. 1. If a_Vector is the position of water, a_Vector's Y will be modified to point to the first air block above it. -- cgit v1.2.3