AI - Better daylight handling
This commit is contained in:
parent
aa142757db
commit
3586f25853
@ -142,7 +142,7 @@ void cMonster::TickPathFinding()
|
|||||||
|
|
||||||
case ePathFinderStatus::PATH_NOT_FOUND:
|
case ePathFinderStatus::PATH_NOT_FOUND:
|
||||||
{
|
{
|
||||||
FinishPathFinding();
|
ResetPathFinding();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ void cMonster::TickPathFinding()
|
|||||||
}
|
}
|
||||||
if (m_Path->IsLastPoint())
|
if (m_Path->IsLastPoint())
|
||||||
{
|
{
|
||||||
FinishPathFinding();
|
ResetPathFinding();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ void cMonster::MoveToPosition(const Vector3d & a_Position)
|
|||||||
void cMonster::StopMovingToPosition()
|
void cMonster::StopMovingToPosition()
|
||||||
{
|
{
|
||||||
m_bMovingToDestination = false;
|
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.
|
/* 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. */
|
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)
|
if (m_Path != nullptr)
|
||||||
{
|
{
|
||||||
@ -254,6 +254,7 @@ bool cMonster::ReachedFinalDestination()
|
|||||||
void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
super::Tick(a_Dt, a_Chunk);
|
super::Tick(a_Dt, a_Chunk);
|
||||||
|
GET_AND_VERIFY_CURRENT_CHUNK(Chunk, POSX_TOINT, POSZ_TOINT);
|
||||||
|
|
||||||
if (m_Health <= 0)
|
if (m_Health <= 0)
|
||||||
{
|
{
|
||||||
@ -276,7 +277,8 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Burning in daylight
|
// Burning in daylight
|
||||||
HandleDaylightBurning(a_Chunk);
|
bool WouldBurnRightNow = WouldBurnAt(GetPosition(), *Chunk); // cached so that we use it twice, spares some cycles.
|
||||||
|
HandleDaylightBurning(*Chunk, WouldBurnRightNow);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -300,7 +302,12 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
{
|
{
|
||||||
if (--m_GiveUpCounter == 0)
|
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
|
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)
|
if (!m_BurnsInDaylight)
|
||||||
{
|
{
|
||||||
@ -1110,7 +1117,7 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WouldBurnAt(GetPosition(), a_Chunk))
|
if (!IsOnFire() && WouldBurn)
|
||||||
{
|
{
|
||||||
// Burn for 100 ticks, then decide again
|
// Burn for 100 ticks, then decide again
|
||||||
StartBurning(100);
|
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.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight
|
||||||
(a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand
|
(a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand
|
||||||
(GetWorld()->GetTimeOfDay() < (12000 + 1000)) && // It is nighttime
|
(GetWorld()->GetTimeOfDay() < (12000 + 1000)) && // It is nighttime
|
||||||
!IsOnFire() && // Not already burning
|
|
||||||
GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining
|
GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -208,7 +208,7 @@ protected:
|
|||||||
This is based on the ultimate, final destination and the current position, as well as the traversed coordinates, and any environmental hazards */
|
This is based on the ultimate, final destination and the current position, as well as the traversed coordinates, and any environmental hazards */
|
||||||
void TickPathFinding(void);
|
void TickPathFinding(void);
|
||||||
/** Finishes a pathfinding task, be it due to failure or something else */
|
/** Finishes a pathfinding task, be it due to failure or something else */
|
||||||
void FinishPathFinding(void);
|
void ResetPathFinding(void);
|
||||||
/** Sets the body yaw and head yaw/pitch based on next/ultimate destinations */
|
/** Sets the body yaw and head yaw/pitch based on next/ultimate destinations */
|
||||||
void SetPitchAndYawFromDestination(void);
|
void SetPitchAndYawFromDestination(void);
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ protected:
|
|||||||
bool m_CanPickUpLoot;
|
bool m_CanPickUpLoot;
|
||||||
int m_TicksSinceLastDamaged; // How many ticks ago we were last damaged by a player?
|
int m_TicksSinceLastDamaged; // How many ticks ago we were last damaged by a player?
|
||||||
|
|
||||||
void HandleDaylightBurning(cChunk & a_Chunk);
|
void HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn);
|
||||||
bool WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk);
|
bool WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk);
|
||||||
bool m_BurnsInDaylight;
|
bool m_BurnsInDaylight;
|
||||||
double m_RelativeWalkSpeed;
|
double m_RelativeWalkSpeed;
|
||||||
|
@ -48,26 +48,6 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSkeleton::MoveToPosition(const Vector3d & a_Position)
|
|
||||||
{
|
|
||||||
// Todo use WouldBurnAt(), not sure how to obtain a chunk though...
|
|
||||||
super::MoveToPosition(a_Position); // Look at the player and update m_Destination to hit them if they're close
|
|
||||||
|
|
||||||
// If the destination is sufficiently skylight challenged AND the skeleton isn't on fire AND we weren't attacked recently then block the movement
|
|
||||||
if (
|
|
||||||
!IsOnFire() &&
|
|
||||||
(m_World->GetBlockSkyLight((int)floor(a_Position.x), (int)floor(a_Position.y), (int)floor(a_Position.z)) - m_World->GetSkyDarkness() > 8) &&
|
|
||||||
m_TicksSinceLastDamaged == 100
|
|
||||||
)
|
|
||||||
{
|
|
||||||
StopMovingToPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSkeleton::Attack(std::chrono::milliseconds a_Dt)
|
void cSkeleton::Attack(std::chrono::milliseconds a_Dt)
|
||||||
{
|
{
|
||||||
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate;
|
||||||
|
@ -11,19 +11,18 @@ class cSkeleton :
|
|||||||
public cAggressiveMonster
|
public cAggressiveMonster
|
||||||
{
|
{
|
||||||
typedef cAggressiveMonster super;
|
typedef cAggressiveMonster super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSkeleton(bool IsWither);
|
cSkeleton(bool IsWither);
|
||||||
|
|
||||||
CLASS_PROTODEF(cSkeleton)
|
CLASS_PROTODEF(cSkeleton)
|
||||||
|
|
||||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||||
virtual void MoveToPosition(const Vector3d & a_Position) override;
|
|
||||||
virtual void Attack(std::chrono::milliseconds a_Dt) override;
|
virtual void Attack(std::chrono::milliseconds a_Dt) override;
|
||||||
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
|
||||||
|
|
||||||
virtual bool IsUndead(void) override { return true; }
|
virtual bool IsUndead(void) override { return true; }
|
||||||
|
|
||||||
bool IsWither(void) const { return m_bIsWither; }
|
bool IsWither(void) const { return m_bIsWither; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -37,27 +37,3 @@ void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
|||||||
AddRandomArmorDropItem(a_Drops, LootingLevel);
|
AddRandomArmorDropItem(a_Drops, LootingLevel);
|
||||||
AddRandomWeaponDropItem(a_Drops, LootingLevel);
|
AddRandomWeaponDropItem(a_Drops, LootingLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cZombie::MoveToPosition(const Vector3d & a_Position)
|
|
||||||
{
|
|
||||||
// Todo use WouldBurnAt(), not sure how to obtain a chunk though...
|
|
||||||
super::MoveToPosition(a_Position); // Look at the player and update m_Destination to hit them if they're close
|
|
||||||
|
|
||||||
// If the destination is sufficiently skylight challenged AND the skeleton isn't on fire AND we weren't attacked recently then block the movement
|
|
||||||
if (
|
|
||||||
!IsOnFire() &&
|
|
||||||
(m_World->GetBlockSkyLight((int)floor(a_Position.x), (int)floor(a_Position.y), (int)floor(a_Position.z)) - m_World->GetSkyDarkness() > 8) &&
|
|
||||||
m_TicksSinceLastDamaged == 100
|
|
||||||
)
|
|
||||||
{
|
|
||||||
StopMovingToPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,17 +10,15 @@ class cZombie :
|
|||||||
public cAggressiveMonster
|
public cAggressiveMonster
|
||||||
{
|
{
|
||||||
typedef cAggressiveMonster super;
|
typedef cAggressiveMonster super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cZombie(bool a_IsVillagerZombie);
|
cZombie(bool a_IsVillagerZombie);
|
||||||
|
|
||||||
CLASS_PROTODEF(cZombie)
|
CLASS_PROTODEF(cZombie)
|
||||||
|
|
||||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
|
||||||
virtual void MoveToPosition(const Vector3d & a_Position) override;
|
|
||||||
|
|
||||||
|
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||||
virtual bool IsUndead(void) override { return true; }
|
virtual bool IsUndead(void) override { return true; }
|
||||||
|
|
||||||
bool IsVillagerZombie(void) const { return m_IsVillagerZombie; }
|
bool IsVillagerZombie(void) const { return m_IsVillagerZombie; }
|
||||||
bool IsConverting (void) const { return m_IsConverting; }
|
bool IsConverting (void) const { return m_IsConverting; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user