diff options
author | LogicParrot <LogicParrot@users.noreply.github.com> | 2016-03-29 15:34:41 +0200 |
---|---|---|
committer | LogicParrot <LogicParrot@users.noreply.github.com> | 2016-04-06 08:18:33 +0200 |
commit | 56a855d59952757ae0a8f675494076abd58e68c6 (patch) | |
tree | d086e85a69ea7fa9dcfd11b8e2e34f04fc1c0dc8 /src/Mobs/Monster.cpp | |
parent | Merge pull request #3125 from LogicParrot/noFall3 (diff) | |
download | cuberite-56a855d59952757ae0a8f675494076abd58e68c6.tar cuberite-56a855d59952757ae0a8f675494076abd58e68c6.tar.gz cuberite-56a855d59952757ae0a8f675494076abd58e68c6.tar.bz2 cuberite-56a855d59952757ae0a8f675494076abd58e68c6.tar.lz cuberite-56a855d59952757ae0a8f675494076abd58e68c6.tar.xz cuberite-56a855d59952757ae0a8f675494076abd58e68c6.tar.zst cuberite-56a855d59952757ae0a8f675494076abd58e68c6.zip |
Diffstat (limited to 'src/Mobs/Monster.cpp')
-rw-r--r-- | src/Mobs/Monster.cpp | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index fad54a00d..a4cb9e63f 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -1191,24 +1191,51 @@ bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk) // Always burn above the world return true; } - - cChunk * Chunk = a_Chunk.GetNeighborChunk(FloorC(a_Location.x), FloorC(a_Location.z)); - if ((Chunk == nullptr) || (!Chunk->IsValid())) + if (RelY <= 0) { + // The mob is about to die, no point in burning return false; } - int RelX = FloorC(a_Location.x) - Chunk->GetPosX() * cChunkDef::Width; - int RelZ = FloorC(a_Location.z) - Chunk->GetPosZ() * cChunkDef::Width; + PREPARE_REL_AND_CHUNK(a_Location, a_Chunk); + if (!RelSuccess) + { + return false; + } if ( - (Chunk->GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight - (Chunk->GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand + (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; } |