summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Mobs/Monster.cpp80
-rw-r--r--src/Mobs/Monster.h2
2 files changed, 47 insertions, 35 deletions
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index 9e9d51a78..0d6b8e777 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -22,10 +22,6 @@
-// Ticks to wait to do leash calculations
-#define LEASH_ACTIONS_TICK_STEP 10
-
-
/** Map for eType <-> string
Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType()
@@ -239,28 +235,12 @@ void cMonster::MoveToWayPoint(cChunk & a_Chunk)
AddSpeedX(Distance.x);
AddSpeedZ(Distance.z);
}
-
- // Speed up leashed mobs getting far from player
- if (IsLeashed() && GetLeashedTo()->IsPlayer())
- {
- Distance = GetLeashedTo()->GetPosition() - GetPosition();
- Distance.Normalize();
- AddSpeedX(Distance.x);
- AddSpeedZ(Distance.z);
- }
-
}
-
-
-
-
-
-
void cMonster::MoveToPosition(const Vector3d & a_Position)
{
m_FinalDestination = a_Position;
@@ -400,10 +380,7 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
} // switch (m_EMState)
// Leash calculations
- if ((m_TicksAlive % LEASH_ACTIONS_TICK_STEP) == 0)
- {
- CalcLeashActions();
- }
+ CalcLeashActions(a_Dt);
BroadcastMovementUpdate();
@@ -422,7 +399,7 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
-void cMonster::CalcLeashActions()
+void cMonster::CalcLeashActions(std::chrono::milliseconds a_Dt)
{
// This mob just spotted in the world and [m_LeashToPos not null] shows that should be leashed to a leash knot at m_LeashToPos.
// This keeps trying until knot is found. Leash knot may be in a different chunk that needn't or can't be loaded yet.
@@ -435,19 +412,54 @@ void cMonster::CalcLeashActions()
SetLeashToPos(nullptr);
}
}
- else if (IsLeashed()) // Mob is already leashed to an entity: follow it.
+
+ if (!IsLeashed())
+ {
+ return;
+ }
+
+ static const double CloseFollowDistance = 1.8; // The closest the mob will path towards the leashed to entity
+ static const double LeashNaturalLength = 5.0; // The closest the mob is actively pulled towards the entity
+ static const double LeashMaximumLength = 10.0; // Length where the leash breaks
+ static const double LeashSpringConstant = 20.0; // How stiff the leash is
+
+ const auto LeashedToPos = m_LeashedTo->GetPosition();
+ const auto Displacement = LeashedToPos - GetPosition();
+ const auto Distance = Displacement.Length();
+ const auto Direction = Displacement.NormalizeCopy();
+
+ // If the leash is over-extended, break the leash:
+ if (Distance > LeashMaximumLength)
+ {
+ LOGD("Leash broken (distance)");
+ Unleash(false);
+ return;
+ }
+
+ // If the mob isn't following close enough, pull the mob towards the leashed to entity:
+ if (Distance > LeashNaturalLength)
{
- // TODO: leashed mobs in vanilla can move around up to 5 blocks distance from leash origin
- MoveToPosition(m_LeashedTo->GetPosition());
+ // Accelerate monster towards the leashed to entity:
+ const auto Extension = Distance - LeashNaturalLength;
+ auto Acceleration = Direction * (Extension * LeashSpringConstant);
- // If distance to target > 10 break leash
- Vector3f a_Distance(m_LeashedTo->GetPosition() - GetPosition());
- double Distance(a_Distance.Length());
- if (Distance > 10.0)
+ // Stop mobs from floating up when on the ground
+ if (IsOnGround() && (Acceleration.y < std::abs(GetGravity())))
{
- LOGD("Leash broken (distance)");
- Unleash(false);
+ Acceleration.y = 0.0;
}
+
+ // Apply the acceleration
+ using namespace std::chrono;
+ AddSpeed(Acceleration * duration_cast<duration<double>>(a_Dt).count());
+ }
+
+ // Passively follow the leashed to entity:
+ if (Distance > CloseFollowDistance)
+ {
+ const Vector3d TargetBlock((LeashedToPos - Direction * CloseFollowDistance).Floor());
+ // Move to centre of target block face
+ MoveToPosition(TargetBlock + Vector3d{ 0.5, 0.0, 0.5 });
}
}
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index 1f6bd6011..d6b02caac 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -326,6 +326,6 @@ private:
cPawn * m_Target;
/** Leash calculations inside Tick function */
- void CalcLeashActions();
+ void CalcLeashActions(std::chrono::milliseconds a_Dt);
} ; // tolua_export