summaryrefslogtreecommitdiffstats
path: root/src/Mobs/Monster.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs/Monster.cpp')
-rw-r--r--src/Mobs/Monster.cpp32
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
)
{