summaryrefslogtreecommitdiffstats
path: root/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp
diff options
context:
space:
mode:
authorLogicParrot <LogicParrot@users.noreply.github.com>2017-08-22 12:23:03 +0200
committerLogicParrot <LogicParrot@users.noreply.github.com>2017-08-22 19:55:30 +0200
commit80d9c26c12a5be619a757d0251525664bf7065a6 (patch)
tree66d4f553ae12fd90dd94ffde9b85f595319ba5cb /src/Mobs/Behaviors/BehaviorDayLightBurner.cpp
parentAdded check in cEntity::TickBurning for whether the entity is planning to change worlds. (#3943) (diff)
downloadcuberite-80d9c26c12a5be619a757d0251525664bf7065a6.tar
cuberite-80d9c26c12a5be619a757d0251525664bf7065a6.tar.gz
cuberite-80d9c26c12a5be619a757d0251525664bf7065a6.tar.bz2
cuberite-80d9c26c12a5be619a757d0251525664bf7065a6.tar.lz
cuberite-80d9c26c12a5be619a757d0251525664bf7065a6.tar.xz
cuberite-80d9c26c12a5be619a757d0251525664bf7065a6.tar.zst
cuberite-80d9c26c12a5be619a757d0251525664bf7065a6.zip
Diffstat (limited to '')
-rw-r--r--src/Mobs/Behaviors/BehaviorDayLightBurner.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp b/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp
new file mode 100644
index 000000000..f15247071
--- /dev/null
+++ b/src/Mobs/Behaviors/BehaviorDayLightBurner.cpp
@@ -0,0 +1,85 @@
+void cMonster::HandleDaylightBurning(cChunk & a_Chunk, bool WouldBurn)
+{
+ if (!m_BurnsInDaylight)
+ {
+ return;
+ }
+
+ int RelY = POSY_TOINT;
+ if ((RelY < 0) || (RelY >= cChunkDef::Height))
+ {
+ // Outside the world
+ return;
+ }
+ if (!a_Chunk.IsLightValid())
+ {
+ m_World->QueueLightChunk(GetChunkX(), GetChunkZ());
+ return;
+ }
+
+ if (!IsOnFire() && WouldBurn)
+ {
+ // Burn for 100 ticks, then decide again
+ StartBurning(100);
+ }
+}
+
+
+
+
+bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk)
+{
+ int RelY = FloorC(a_Location.y);
+ if (RelY <= 0)
+ {
+ // The mob is about to die, no point in burning
+ return false;
+ }
+ if (RelY >= cChunkDef::Height)
+ {
+ // Always burn above the world
+ return true;
+ }
+
+ PREPARE_REL_AND_CHUNK(a_Location, a_Chunk);
+ if (!RelSuccess)
+ {
+ return false;
+ }
+
+ if (
+ (Chunk->GetBlock(Rel.x, Rel.y, Rel.z) != E_BLOCK_SOULSAND) && // Not on soulsand
+ (GetWorld()->GetTimeOfDay() < 12000 + 1000) && // Daytime
+ GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining
+ )
+ {
+ int MobHeight = static_cast<int>(a_Location.y) + round(GetHeight()) - 1; // The height of the mob head
+ if (MobHeight >= cChunkDef::Height)
+ {
+ return true;
+ }
+ // Start with the highest block and scan down to the mob's head.
+ // If a non transparent is found, return false (do not burn). Otherwise return true.
+ // Note that this loop is not a performance concern as transparent blocks are rare and the loop almost always bailes out
+ // instantly.(An exception is e.g. standing under a long column of glass).
+ int CurrentBlock = Chunk->GetHeight(Rel.x, Rel.z);
+ while (CurrentBlock >= MobHeight)
+ {
+ BLOCKTYPE Block = Chunk->GetBlock(Rel.x, CurrentBlock, Rel.z);
+ if (
+ // Do not burn if a block above us meets one of the following conditions:
+ (!cBlockInfo::IsTransparent(Block)) ||
+ (Block == E_BLOCK_LEAVES) ||
+ (Block == E_BLOCK_NEW_LEAVES) ||
+ (IsBlockWater(Block))
+ )
+ {
+ return false;
+ }
+ --CurrentBlock;
+ }
+ return true;
+
+ }
+ return false;
+}