diff options
Diffstat (limited to 'src/Mobs/Monster.cpp')
-rw-r--r-- | src/Mobs/Monster.cpp | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index e225ff9b1..9b9bec51e 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -121,7 +121,7 @@ void cMonster::SpawnOn(cClientHandle & a_Client) -void cMonster::TickPathFinding() +void cMonster::TickPathFinding(cChunk & a_Chunk) { if (m_Path == nullptr) @@ -131,18 +131,18 @@ void cMonster::TickPathFinding() // Can someone explain why are these two NOT THE SAME??? // m_Path = new cPath(GetWorld(), GetPosition(), m_FinalDestination, 30); - m_Path = new cPath(GetWorld(), Vector3d(floor(position.x), floor(position.y), floor(position.z)), Vector3d(floor(Dest.x), floor(Dest.y), floor(Dest.z)), 20); + m_Path = new cPath(&a_Chunk, Vector3d(floor(position.x), floor(position.y), floor(position.z)), Vector3d(floor(Dest.x), floor(Dest.y), floor(Dest.z)), 20); m_IsFollowingPath = false; } - m_PathStatus = m_Path->Step(); + m_PathStatus = m_Path->Step(&a_Chunk); switch (m_PathStatus) { case ePathFinderStatus::PATH_NOT_FOUND: { - FinishPathFinding(); + ResetPathFinding(); break; } @@ -164,7 +164,7 @@ void cMonster::TickPathFinding() } if (m_Path->IsLastPoint()) { - FinishPathFinding(); + ResetPathFinding(); } break; @@ -191,7 +191,7 @@ void cMonster::MoveToPosition(const Vector3d & a_Position) void cMonster::StopMovingToPosition() { m_bMovingToDestination = false; - FinishPathFinding(); + ResetPathFinding(); } @@ -209,7 +209,7 @@ bool cMonster::IsCoordinateInTraversedList(Vector3i a_Coords) /* No one should call this except the pathfinder orthe monster tick or StopMovingToPosition. Resets the pathfinder, usually starting a brand new path, unless called from StopMovingToPosition. */ -void cMonster::FinishPathFinding(void) +void cMonster::ResetPathFinding(void) { if (m_Path != nullptr) { @@ -254,6 +254,7 @@ bool cMonster::ReachedFinalDestination() void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); + GET_AND_VERIFY_CURRENT_CHUNK(Chunk, POSX_TOINT, POSZ_TOINT); if (m_Health <= 0) { @@ -276,7 +277,8 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) } // Burning in daylight - HandleDaylightBurning(a_Chunk); + bool WouldBurnRightNow = WouldBurnAt(GetPosition(), *Chunk); // cached so that we use it twice, spares some cycles. + HandleDaylightBurning(*Chunk, WouldBurnRightNow); @@ -293,14 +295,19 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) } } - TickPathFinding(); + TickPathFinding(a_Chunk); Vector3d Distance = m_Destination - GetPosition(); if (!ReachedDestination() && !ReachedFinalDestination()) // If we haven't reached any sort of destination, move { if (--m_GiveUpCounter == 0) { - FinishPathFinding(); + ResetPathFinding(); // Not to be confused with StopMovingToPosition, this just discards the current path and calculates another. + } + else if (m_BurnsInDaylight && WouldBurnAt(m_Destination, *Chunk) && !WouldBurnRightNow && (m_TicksSinceLastDamaged == 100)) + { + // If we burn in daylight, and we would burn at the next step, and we won't burn where we are right now, and we weren't provoked recently: + StopMovingToPosition(); } else { @@ -1091,7 +1098,7 @@ void cMonster::AddRandomWeaponDropItem(cItems & a_Drops, short a_LootingLevel) -void cMonster::HandleDaylightBurning(cChunk & a_Chunk) +void cMonster::HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn) { if (!m_BurnsInDaylight) { @@ -1110,7 +1117,7 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk) return; } - if (WouldBurnAt(GetPosition(), a_Chunk)) + if (!IsOnFire() && WouldBurn) { // Burn for 100 ticks, then decide again StartBurning(100); @@ -1129,7 +1136,6 @@ bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk) (a_Chunk.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight (a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand (GetWorld()->GetTimeOfDay() < (12000 + 1000)) && // It is nighttime - !IsOnFire() && // Not already burning GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining ) { |