| 1735 | |
| 1736 | |
| 1737 | void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlocksAffected) |
| 1738 | { |
| 1739 | // Don't explode if outside of Y range (prevents the following test running into unallocated memory): |
| 1740 | if ((a_BlockY < 0) || (a_BlockY > cChunkDef::Height - 1)) |
| 1741 | { |
| 1742 | return; |
| 1743 | } |
| 1744 | |
| 1745 | bool ShouldDestroyBlocks = true; |
| 1746 | |
| 1747 | // Don't explode if the explosion center is inside a liquid block: |
| 1748 | if (IsBlockLiquid(m_World->GetBlock((int)floor(a_BlockX), (int)floor(a_BlockY), (int)floor(a_BlockZ)))) |
| 1749 | { |
| 1750 | ShouldDestroyBlocks = false; |
| 1751 | } |
| 1752 | |
| 1753 | int ExplosionSizeInt = (int)ceil(a_ExplosionSize); |
| 1754 | int ExplosionSizeSq = ExplosionSizeInt * ExplosionSizeInt; |
| 1755 | |
| 1756 | int bx = (int)floor(a_BlockX); |
| 1757 | int by = (int)floor(a_BlockY); |
| 1758 | int bz = (int)floor(a_BlockZ); |
| 1759 | |
| 1760 | int MinY = std::max((int)floor(a_BlockY - ExplosionSizeInt), 0); |
| 1761 | int MaxY = std::min((int)ceil(a_BlockY + ExplosionSizeInt), cChunkDef::Height - 1); |
| 1762 | |
| 1763 | if (ShouldDestroyBlocks) |
| 1764 | { |
| 1765 | cBlockArea area; |
| 1766 | |
| 1767 | a_BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt); |
| 1768 | |
| 1769 | area.Read(m_World, bx - ExplosionSizeInt, (int)ceil(a_BlockX + ExplosionSizeInt), MinY, MaxY, bz - ExplosionSizeInt, (int)ceil(a_BlockZ + ExplosionSizeInt)); |
| 1770 | for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) |
| 1771 | { |
| 1772 | for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) |
| 1773 | { |
| 1774 | if ((by + y >= cChunkDef::Height) || (by + y < 0)) |
| 1775 | { |
| 1776 | // Outside of the world |
| 1777 | continue; |
| 1778 | } |
| 1779 | for (int z = -ExplosionSizeInt; z < ExplosionSizeInt; z++) |
| 1780 | { |
| 1781 | if ((x * x + y * y + z * z) > ExplosionSizeSq) |
| 1782 | { |
| 1783 | // Too far away |
| 1784 | continue; |
| 1785 | } |
| 1786 | |
| 1787 | BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); |
| 1788 | switch (Block) |
| 1789 | { |
| 1790 | case E_BLOCK_TNT: |
| 1791 | { |
| 1792 | // Activate the TNT, with a random fuse between 10 to 30 game ticks |
| 1793 | int FuseTime = 10 + m_World->GetTickRandomNumber(20); |
| 1794 | m_World->SpawnPrimedTNT(a_BlockX + x + 0.5, a_BlockY + y + 0.5, a_BlockZ + z + 0.5, FuseTime); |
nothing calls this directly
no test coverage detected