public override void UseItem(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face, Vector3 faceCoords) { Log.Warn("Player " + player.Username + " should be banned for hacking!"); var block = world.GetBlock(blockCoordinates); if (block is Tnt) { world.SetBlock(new Air() {Coordinates = block.Coordinates}); new PrimedTnt(world) { KnownPosition = new PlayerLocation(blockCoordinates.X, blockCoordinates.Y, blockCoordinates.Z), Fuse = (byte) (new Random().Next(0, 20) + 10) }.SpawnEntity(); } else if (block.IsSolid) { var affectedBlock = world.GetBlock(GetNewCoordinatesFromFace(blockCoordinates, BlockFace.Up)); if (affectedBlock.Id == 0) { var fire = new Fire { Coordinates = affectedBlock.Coordinates }; world.SetBlock(fire); } } }
public override void UseItem(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face, Vector3 faceCoords) { // 8 = 1000 byte upperBit = 0x08; // 7 = 0111 byte materialMask = 0x07; Block existingBlock = world.GetBlock(blockCoordinates); var coordinates = GetNewCoordinatesFromFace(blockCoordinates, face); Block newBlock = world.GetBlock(coordinates); if (face == BlockFace.Up && faceCoords.Y == 0.5 && existingBlock.Id == Id && (existingBlock.Metadata & materialMask) == Metadata) { // Replace with double block SetDoubleSlab(world, blockCoordinates); return; } if (face == BlockFace.Down && faceCoords.Y == 0.5 && (existingBlock.Metadata & materialMask) == Metadata) { // Replace with double block SetDoubleSlab(world, blockCoordinates); return; } if (newBlock.Id != Id || (newBlock.Metadata & materialMask) != Metadata) { Block slab = BlockFactory.GetBlockById((byte) (Id)); slab.Coordinates = coordinates; slab.Metadata = (byte) Metadata; if (face != BlockFace.Up && faceCoords.Y > 0.5 || (face == BlockFace.Down && faceCoords.Y == 0.0)) { slab.Metadata |= upperBit; } world.SetBlock(slab); return; } // Same material in existing block, make double slab { // Create double slab, replace existing SetDoubleSlab(world, coordinates); } }
public override void DoPhysics(Level level) { CheckForHarden(level, Coordinates.X, Coordinates.Y, Coordinates.Z); if (level.GetBlock(Coordinates).Id == Id) { SetToFlowing(level); } }
public override void UseItem(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face, Vector3 faceCoords) { Block block = world.GetBlock(blockCoordinates); if (block is Grass) { GrassPath grassPath = new GrassPath { Coordinates = blockCoordinates, }; world.SetBlock(grassPath); } }
public override void UseItem(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face, Vector3 faceCoords) { Block block = world.GetBlock(blockCoordinates); if (block is Grass || block is Dirt || block is GrassPath) { Farmland farmland = new Farmland { Coordinates = blockCoordinates, Metadata = 0 }; world.SetBlock(farmland); } }
public override void UseItem(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face, Vector3 faceCoords) { byte direction = player.GetDirection(); var coordinates = GetNewCoordinatesFromFace(blockCoordinates, face); // Base block, meta sets orientation Block block = new WoodenDoor(); block.Coordinates = coordinates; block.Metadata = direction; int x = blockCoordinates.X; int y = blockCoordinates.Y; int z = blockCoordinates.Z; int xd = 0; int zd = 0; if (direction == 0) zd = 1; if (direction == 1) xd = -1; if (direction == 2) zd = -1; if (direction == 3) xd = 1; int i1 = (world.GetBlock(x - xd, y, z - zd).IsSolid ? 1 : 0) + (world.GetBlock(x - xd, y + 1, z - zd).IsSolid ? 1 : 0); int j1 = (world.GetBlock(x + xd, y, z + zd).IsSolid ? 1 : 0) + (world.GetBlock(x + xd, y + 1, z + zd).IsSolid ? 1 : 0); bool flag = world.GetBlock(x - xd, y, z - zd).Id == block.Id || world.GetBlock(x - xd, y + 1, z - zd).Id == block.Id; bool flag1 = world.GetBlock(x + xd, y, z + zd).Id == block.Id || world.GetBlock(x + xd, y + 1, z + zd).Id == block.Id; bool flag2 = false; if (flag && !flag1) { flag2 = true; } else if (j1 > i1) { flag2 = true; } if (!block.CanPlace(world, face)) return; // The upper doore block, meta marks upper and // sets orientation based on ajecent blocks Block blockUpper = new WoodenDoor(); blockUpper.Coordinates = coordinates + Level.Up; blockUpper.Metadata = (byte) (0x08 | (flag2 ? 1 : 0)); world.SetBlock(block); world.SetBlock(blockUpper); }
public override bool Interact(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face) { Block block = this; // Remove door if ((Metadata & 0x08) == 0x08) // Is Upper? { block = world.GetBlock(GetNewCoordinatesFromFace(blockCoordinates, BlockFace.Down)); } block.Metadata ^= 0x04; world.SetBlock(block); return true; }
public override void UseItem(Level world, Player player, BlockCoordinates blockCoordinates, BlockFace face, Vector3 faceCoords) { if (NeedBlockRevert) { var coord = GetNewCoordinatesFromFace(blockCoordinates, face); Log.Info("Reset block"); // Resend the block to removed the new one Block block = world.GetBlock(coord); world.SetBlock(block); } Action(this, world, player, blockCoordinates); }
private void CheckForHarden(Level world, int x, int y, int z) { Block block = world.GetBlock(x, y, z); { bool harden = false; if (block is FlowingLava || block is StationaryLava) { if (IsWater(world, x, y, z)) { harden = true; } if (harden || IsWater(world, x, y, z + 1)) { harden = true; } if (harden || IsWater(world, x - 1, y, z)) { harden = true; } if (harden || IsWater(world, x + 1, y, z)) { harden = true; } if (harden || IsWater(world, x, y + 1, z)) { harden = true; } if (harden) { int meta = block.Metadata; if (meta == 0) { world.SetBlock(new Obsidian {Coordinates = new BlockCoordinates(x, y, z)}); } else if (meta <= 4) { world.SetBlock(new Cobblestone {Coordinates = new BlockCoordinates(x, y, z)}); } } } } }
protected override bool CanPlace(Level world, BlockCoordinates blockCoordinates, BlockFace face) { Block block = world.GetBlock(blockCoordinates); if (block is Farmland || block is Ice /*|| block is Glowstone || block is Leaves */ || block is Tnt || block is BlockStairs || block is StoneSlab || block is WoodSlab) return true; //TODO: More checks here, but PE blocks it pretty good right now if (block is Glass && face == BlockFace.Up) return true; return !block.IsTransparent; }
private bool BlocksFluid(Level world, int x, int y, int z) { Block block = world.GetBlock(x, y, z); return BlocksFluid(block); }
protected override bool CanPlace(Level world, BlockCoordinates blockCoordinates) { return world.GetBlock(blockCoordinates).IsReplacible && world.GetBlock(blockCoordinates + Level.Up).IsReplacible; }
protected virtual bool CanPlace(Level world, BlockCoordinates blockCoordinates, BlockFace face) { return world.GetBlock(blockCoordinates).IsReplacible; }
public override void OnTick(Level level) { if (Inventory == null) return; Furnace furnace = level.GetBlock(Coordinates) as Furnace; if (furnace == null) return; if (!(furnace is LitFurnace)) { Item fuel = GetFuel(); Item ingredient = GetIngredient(); Item smelt = ingredient.GetSmelt(); // To light a furnace you need both fule and proper ingredient. if (fuel.Count > 0 && fuel.FuelEfficiency > 0 && smelt != null) { LitFurnace litFurnace = new LitFurnace { Coordinates = furnace.Coordinates, Metadata = furnace.Metadata }; level.SetBlock(litFurnace); furnace = litFurnace; BurnTime = GetFuelEfficiency(fuel); FuelEfficiency = BurnTime; CookTime = 0; Inventory.DecreaseSlot(1); } } if (furnace is LitFurnace) { if (BurnTime > 0) { BurnTime--; BurnTick = (short) Math.Ceiling((double) BurnTime/FuelEfficiency*200d); Item ingredient = GetIngredient(); Item smelt = ingredient.GetSmelt(); if (smelt != null) { CookTime++; if (CookTime >= 200) { Inventory.DecreaseSlot(0); Inventory.IncreaseSlot(2, smelt.Id, smelt.Metadata); CookTime = 0; } } else { CookTime = 0; } } if (BurnTime <= 0) { var fuel = GetFuel(); Item ingredient = GetIngredient(); Item smelt = ingredient.GetSmelt(); if (fuel.Count > 0 && fuel.FuelEfficiency > 0 && smelt != null) { Inventory.DecreaseSlot(1); CookTime = 0; BurnTime = GetFuelEfficiency(fuel); FuelEfficiency = BurnTime; BurnTick = (short) Math.Ceiling((double) BurnTime/FuelEfficiency*200d); } else { // No more fule or nothin more to smelt. Furnace unlitFurnace = new Furnace { Coordinates = furnace.Coordinates, Metadata = furnace.Metadata }; level.SetBlock(unlitFurnace); FuelEfficiency = 0; BurnTick = 0; BurnTime = 0; CookTime = 0; } } } foreach (var observer in Inventory.Observers) { var cookTimeSetData = McpeContainerSetData.CreateObject(); cookTimeSetData.windowId = Inventory.WindowsId; cookTimeSetData.property = 0; cookTimeSetData.value = CookTime; observer.SendPackage(cookTimeSetData); var burnTimeSetData = McpeContainerSetData.CreateObject(); burnTimeSetData.windowId = Inventory.WindowsId; burnTimeSetData.property = 1; burnTimeSetData.value = BurnTick; observer.SendPackage(burnTimeSetData); } }
public override void OnTick(Level level) { if (Inventory == null) return; Furnace furnace = level.GetBlock(Coordinates) as Furnace; if (furnace == null) return; if (!(furnace is LitFurnace)) { if (GetFuel().Id != 0) { LitFurnace litFurnace = new LitFurnace { Coordinates = furnace.Coordinates, Metadata = furnace.Metadata }; level.SetBlock(litFurnace); furnace = litFurnace; BurnTime = GetFuelEfficiency(GetFuel()); FuelEfficiency = BurnTime; CookTime = 0; Inventory.DecreaseSlot(1); } } if (!(furnace is LitFurnace)) return; if (BurnTime > 0) { BurnTime--; BurnTick = (short) Math.Ceiling((double) BurnTime/FuelEfficiency*200d); if (GetIngredient().Id != 0) { CookTime++; if (CookTime >= 200) { Item result = GetResult(GetIngredient()); if (result != null) { Inventory.DecreaseSlot(0); Inventory.IncreaseSlot(2, result.Id, result.Metadata); } CookTime = 0; } } else { CookTime = 0; } } if (BurnTime <= 0) { if (!Inventory.DecreaseSlot(1)) { //CookTime = 0; BurnTime = GetFuelEfficiency(GetFuel()); FuelEfficiency = BurnTime; BurnTick = (short) Math.Ceiling((double) BurnTime/FuelEfficiency*200d); } else { // No more fule Furnace unlitFurnace = new Furnace { Coordinates = furnace.Coordinates, Metadata = furnace.Metadata }; level.SetBlock(unlitFurnace); FuelEfficiency = 0; BurnTick = 0; BurnTime = 0; CookTime = 0; } } level.RelayBroadcast(new McpeContainerSetData { windowId = Inventory.WindowsId, property = 0, value = CookTime }); level.RelayBroadcast(new McpeContainerSetData { windowId = Inventory.WindowsId, property = 1, value = BurnTick }); }
private bool[] GetOptimalFlowDirections(Level world, int x, int y, int z) { int l; int x2; for (l = 0; l < 4; ++l) { _flowCost[l] = 1000; x2 = x; int z2 = z; if (l == 0) { x2 = x - 1; } if (l == 1) { ++x2; } if (l == 2) { z2 = z - 1; } if (l == 3) { ++z2; } if (!BlocksFluid(world, x2, y, z2) && (!IsSameMaterial(world.GetBlock(x2, y, z2)) || world.GetBlock(x2, y, z2).Metadata != 0)) { if (BlocksFluid(world, x2, y - 1, z2)) { _flowCost[l] = CalculateFlowCost(world, x2, y, z2, 1, l); } else { _flowCost[l] = 0; } } } l = _flowCost[0]; for (x2 = 1; x2 < 4; ++x2) { if (_flowCost[x2] < l) { l = _flowCost[x2]; } } for (x2 = 0; x2 < 4; ++x2) { _optimalFlowDirections[x2] = _flowCost[x2] == l; } return _optimalFlowDirections; }
private bool IsWater(Level world, int x, int y, int z) { Block block = world.GetBlock(x, y, z); return block is FlowingWater || block is StationaryWater; }
private int GetFlowDecay(Level world, int x, int y, int z) { Block block = world.GetBlock(x, y, z); return IsSameMaterial(block) ? block.Metadata : -1; }
private void SetToStill(Level world, int x, int y, int z) { byte meta = world.GetBlock(x, y, z).Metadata; Block stillBlock = BlockFactory.GetBlockById((byte) (Id + 1)); stillBlock.Metadata = meta; stillBlock.Coordinates = new BlockCoordinates(x, y, z); world.SetBlock(stillBlock, applyPhysics: false); }
private bool CanBeFlownInto(Level world, int x, int y, int z) { Block block = world.GetBlock(x, y, z); return !IsSameMaterial(block) && (!(block is FlowingLava) && !(block is StationaryLava)) && !BlocksFluid(block); }
public override void OnTick(Level world) { Random random = new Random(); int x = Coordinates.X; int y = Coordinates.Y; int z = Coordinates.Z; int currentDecay = GetFlowDecay(world, x, y, z); byte multiplier = 1; if (this is FlowingLava) { multiplier = 2; } bool flag = true; int tickRate = TickRate(); if (currentDecay > 0) { int smallestFlowDecay = -100; _adjacentSources = 0; smallestFlowDecay = GetSmallestFlowDecay(world, x - 1, y, z, smallestFlowDecay); smallestFlowDecay = GetSmallestFlowDecay(world, x + 1, y, z, smallestFlowDecay); smallestFlowDecay = GetSmallestFlowDecay(world, x, y, z - 1, smallestFlowDecay); smallestFlowDecay = GetSmallestFlowDecay(world, x, y, z + 1, smallestFlowDecay); int newDecay = smallestFlowDecay + multiplier; if (newDecay >= 8 || smallestFlowDecay < 0) { newDecay = -1; } if (GetFlowDecay(world, x, y + 1, z) >= 0) { int topFlowDecay = GetFlowDecay(world, x, y + 1, z); if (topFlowDecay >= 8) { newDecay = topFlowDecay; } else { newDecay = topFlowDecay + 8; } } if (_adjacentSources >= 2 && this is FlowingWater) { if (world.GetBlock(x, y - 1, z).IsSolid) { newDecay = 0; } else if (IsSameMaterial(world.GetBlock(x, y - 1, z)) && world.GetBlock(x, y - 1, z).Metadata == 0) { newDecay = 0; } } if (this is FlowingLava && currentDecay < 8 && newDecay < 8 && newDecay > currentDecay && random.Next(4) != 0) { //newDecay = currentDecay; //flag = false; tickRate *= 4; } if (newDecay == currentDecay) { if (flag) { SetToStill(world, x, y, z); } } else { currentDecay = newDecay; if (newDecay < 0) { world.SetAir(x, y, z); } else { world.SetData(x, y, z, (byte) newDecay); world.ApplyPhysics(x, y, z); world.ScheduleBlockTick(this, tickRate); // Schedule tick } } } else { SetToStill(world, x, y, z); } if (CanBeFlownInto(world, x, y - 1, z) /* || world.GetBlock(x, y - 1, z) is Flowing*/) { if (this is FlowingLava && (world.GetBlock(x, y - 1, z) is FlowingWater || world.GetBlock(x, y - 1, z) is StationaryWater)) { world.SetBlock(new Cobblestone {Coordinates = new BlockCoordinates(x, y - 1, z)}); return; } if (currentDecay >= 8) { Flow(world, x, y - 1, z, currentDecay); } else { Flow(world, x, y - 1, z, currentDecay + 8); } } else if (currentDecay >= 0 && (currentDecay == 0 || BlocksFluid(world, x, y - 1, z))) { bool[] optimalFlowDirections = GetOptimalFlowDirections(world, x, y, z); int newDecay = currentDecay + multiplier; if (currentDecay >= 8) { newDecay = 1; } if (newDecay >= 8) { return; } if (optimalFlowDirections[0]) { Flow(world, x - 1, y, z, newDecay); } if (optimalFlowDirections[1]) { Flow(world, x + 1, y, z, newDecay); } if (optimalFlowDirections[2]) { Flow(world, x, y, z - 1, newDecay); } if (optimalFlowDirections[3]) { Flow(world, x, y, z + 1, newDecay); } } }
private int CalculateFlowCost(Level world, int x, int y, int z, int accumulatedCost, int prevDirection) { int cost = 1000; for (int direction = 0; direction < 4; ++direction) { if ((direction != 0 || prevDirection != 1) && (direction != 1 || prevDirection != 0) && (direction != 2 || prevDirection != 3) && (direction != 3 || prevDirection != 2)) { int x2 = x; int z2 = z; if (direction == 0) { x2 = x - 1; } if (direction == 1) { ++x2; } if (direction == 2) { z2 = z - 1; } if (direction == 3) { ++z2; } if (!BlocksFluid(world, x2, y, z2) && (!IsSameMaterial(world.GetBlock(x2, y, z2)) || world.GetBlock(x2, y, z2).Metadata != 0)) { if (!BlocksFluid(world, x2, y - 1, z2)) { return accumulatedCost; } if (accumulatedCost < 4) { int j2 = CalculateFlowCost(world, x2, y, z2, accumulatedCost + 1, direction); if (j2 < cost) { cost = j2; } } } } } return cost; }