// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 using System; using ClassicalSharp.Map; using OpenTK; #if USE16_BIT using BlockID = System.UInt16; #else using BlockID = System.Byte; #endif namespace ClassicalSharp.Singleplayer { public class TNTPhysics { Game game; World map; PhysicsBase physics; Random rnd = new Random(); public TNTPhysics(Game game, PhysicsBase physics) { this.game = game; map = game.World; this.physics = physics; physics.OnPlace[Block.TNT] = HandleTnt; } bool[] blocksTnt; void HandleTnt(int index, BlockID block) { int x = index % map.Width; int z = (index / map.Width) % map.Length; int y = (index / map.Width) / map.Length; Explode(4, x, y, z); } public void Explode(int power, int x, int y, int z) { if (blocksTnt == null) InitExplosionCache(); game.UpdateBlock(x, y, z, Block.Air); int index = (y * map.Length + z) * map.Width + x; physics.ActivateNeighbours(x, y, z, index); int powerSquared = power * power; for (int dy = -power; dy <= power; dy++) for (int dz = -power; dz <= power; dz++) for (int dx = -power; dx <= power; dx++) { if (dx * dx + dy * dy + dz * dz > powerSquared) continue; int xx = x + dx, yy = y + dy, zz = z + dz; if (!map.IsValidPos(xx, yy, zz)) continue; index = (yy * map.Length + zz) * map.Width + xx; BlockID block = map.blocks[index]; if (block < Block.CpeCount && blocksTnt[block]) continue; game.UpdateBlock(xx, yy, zz, Block.Air); physics.ActivateNeighbours(xx, yy, zz, index); } } void InitExplosionCache() { blocksTnt = new bool[Block.CpeCount]; blocksTnt[Block.Stone] = true; blocksTnt[Block.Cobblestone] = true; blocksTnt[Block.Bedrock] = true; for (int i = Block.Water; i <= Block.StillLava; i++) blocksTnt[i] = true; blocksTnt[Block.GoldOre] = true; blocksTnt[Block.IronOre] = true; blocksTnt[Block.CoalOre] = true; blocksTnt[Block.Gold] = true; blocksTnt[Block.Iron] = true; blocksTnt[Block.DoubleSlab] = true; blocksTnt[Block.Slab] = true; blocksTnt[Block.Brick] = true; blocksTnt[Block.MossyRocks] = true; blocksTnt[Block.Obsidian] = true; // CPE guesses blocksTnt[Block.CobblestoneSlab] = true; blocksTnt[Block.Sandstone] = true; blocksTnt[Block.CeramicTile] = true; blocksTnt[Block.Magma] = true; blocksTnt[Block.Pillar] = true; blocksTnt[Block.Crate] = true; blocksTnt[Block.StoneBrick] = true; } } }