diff options
author | peterbell10 <peterbell10@live.co.uk> | 2018-01-17 22:40:59 +0100 |
---|---|---|
committer | Alexander Harkness <me@bearbin.net> | 2018-01-17 22:40:58 +0100 |
commit | e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04 (patch) | |
tree | 25a402caa79939db7758a28ea3a7895a88ea5463 /src/Mobs/Monster.cpp | |
parent | Calculate crit damage properly (#4154) (diff) | |
download | cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.tar cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.tar.gz cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.tar.bz2 cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.tar.lz cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.tar.xz cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.tar.zst cuberite-e88b3fa2fefa8c9a0383243bc455d9cbb27d8b04.zip |
Diffstat (limited to '')
-rw-r--r-- | src/Mobs/Monster.cpp | 80 |
1 files changed, 46 insertions, 34 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 }); } } |