From 9b6046cb83f18bb0f39555cc06cea66c9dc2c237 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:52:50 -0500 Subject: [PATCH] TU19: merge Minecraft.World/Blocks --- Minecraft.World/Blocks/AnvilTile.cpp | 24 +- Minecraft.World/Blocks/AnvilTile.h | 3 +- Minecraft.World/Blocks/BaseEntityTile.cpp | 32 + Minecraft.World/Blocks/BaseEntityTile.h | 16 + .../Blocks/BasePressurePlateTile.cpp | 163 ++ .../Blocks/BasePressurePlateTile.h | 59 + Minecraft.World/Blocks/BaseRailTile.cpp | 418 ++++ Minecraft.World/Blocks/BaseRailTile.h | 97 + Minecraft.World/Blocks/BeaconTile.cpp | 52 + Minecraft.World/Blocks/BeaconTile.h | 22 + Minecraft.World/Blocks/BedTile.cpp | 49 +- Minecraft.World/Blocks/BedTile.h | 2 + Minecraft.World/Blocks/BrewingStandTile.cpp | 37 +- Minecraft.World/Blocks/BrewingStandTile.h | 17 +- Minecraft.World/Blocks/ButtonTile.cpp | 44 +- Minecraft.World/Blocks/ButtonTile.h | 7 +- Minecraft.World/Blocks/CactusTile.cpp | 10 +- Minecraft.World/Blocks/CakeTile.cpp | 10 +- Minecraft.World/Blocks/CarrotTile.cpp | 3 +- Minecraft.World/Blocks/CauldronTile.cpp | 34 +- Minecraft.World/Blocks/CauldronTile.h | 4 + Minecraft.World/Blocks/ChestTile.cpp | 125 +- Minecraft.World/Blocks/ChestTile.h | 36 +- Minecraft.World/Blocks/ClothTile.cpp | 23 - Minecraft.World/Blocks/CocoaTile.cpp | 16 +- Minecraft.World/Blocks/CocoaTile.h | 2 +- Minecraft.World/Blocks/ColoredTile.cpp | 26 + .../Blocks/{ClothTile.h => ColoredTile.h} | 19 +- Minecraft.World/Blocks/CommandBlock.cpp | 86 + Minecraft.World/Blocks/CommandBlock.h | 27 + Minecraft.World/Blocks/ComparatorTile.cpp | 215 ++ Minecraft.World/Blocks/ComparatorTile.h | 68 + Minecraft.World/Blocks/CropTile.cpp | 15 +- Minecraft.World/Blocks/CropTile.h | 2 +- .../Blocks/DaylightDetectorTile.cpp | 96 + Minecraft.World/Blocks/DaylightDetectorTile.h | 30 + Minecraft.World/Blocks/DetectorRailTile.cpp | 61 +- Minecraft.World/Blocks/DetectorRailTile.h | 15 +- Minecraft.World/Blocks/DiodeTile.cpp | 289 +-- Minecraft.World/Blocks/DiodeTile.h | 78 +- Minecraft.World/Blocks/DirectionalTile.cpp | 3 - Minecraft.World/Blocks/DirectionalTile.h | 1 - Minecraft.World/Blocks/DispenserTile.cpp | 462 +--- Minecraft.World/Blocks/DispenserTile.h | 41 +- Minecraft.World/Blocks/DoorTile.cpp | 63 +- Minecraft.World/Blocks/DoorTile.h | 15 +- Minecraft.World/Blocks/DropperTile.cpp | 68 + Minecraft.World/Blocks/DropperTile.h | 23 + Minecraft.World/Blocks/EggTile.cpp | 44 +- Minecraft.World/Blocks/EggTile.h | 2 +- .../Blocks/EnchantmentTableTile.cpp | 21 +- Minecraft.World/Blocks/EnchantmentTableTile.h | 27 +- Minecraft.World/Blocks/EnderChestTile.cpp | 7 +- Minecraft.World/Blocks/EnderChestTile.h | 7 +- Minecraft.World/Blocks/FallingTile.cpp | 61 +- Minecraft.World/Blocks/FallingTile.h | 3 + Minecraft.World/Blocks/FarmTile.cpp | 27 +- Minecraft.World/Blocks/FenceGateTile.cpp | 15 +- Minecraft.World/Blocks/FenceGateTile.h | 3 +- Minecraft.World/Blocks/FenceTile.cpp | 36 +- Minecraft.World/Blocks/FenceTile.h | 12 +- Minecraft.World/Blocks/FireTile.cpp | 64 +- Minecraft.World/Blocks/FireTile.h | 3 +- Minecraft.World/Blocks/FlowerPotTile.cpp | 17 +- Minecraft.World/Blocks/FurnaceTile.cpp | 46 +- Minecraft.World/Blocks/FurnaceTile.h | 12 +- Minecraft.World/Blocks/GlowstoneTile.cpp | 19 + .../{LightGemTile.h => GlowstoneTile.h} | 4 +- Minecraft.World/Blocks/GrassTile.cpp | 4 +- Minecraft.World/Blocks/GravelTile.cpp | 1 + Minecraft.World/Blocks/HalfSlabTile.cpp | 27 +- Minecraft.World/Blocks/HalfSlabTile.h | 3 + .../Blocks/HalfTransparentTile.cpp | 2 +- Minecraft.World/Blocks/HalfTransparentTile.h | 2 +- Minecraft.World/Blocks/HayBlockTile.cpp | 14 + Minecraft.World/Blocks/HayBlockTile.h | 18 + Minecraft.World/Blocks/HeavyTile.cpp | 12 +- Minecraft.World/Blocks/HeavyTile.h | 2 +- Minecraft.World/Blocks/HellStoneTile.cpp | 4 - Minecraft.World/Blocks/HellStoneTile.h | 7 - Minecraft.World/Blocks/HopperTile.cpp | 189 ++ Minecraft.World/Blocks/HopperTile.h | 70 + Minecraft.World/Blocks/HugeMushroomTile.cpp | 20 +- Minecraft.World/Blocks/HugeMushroomTile.h | 3 + Minecraft.World/Blocks/IceTile.cpp | 14 +- Minecraft.World/Blocks/JukeboxTile.cpp | 159 ++ Minecraft.World/Blocks/JukeboxTile.h | 61 + Minecraft.World/Blocks/LadderTile.cpp | 7 +- Minecraft.World/Blocks/LeafTile.cpp | 32 +- Minecraft.World/Blocks/LeverTile.cpp | 88 +- Minecraft.World/Blocks/LeverTile.h | 10 +- Minecraft.World/Blocks/LightGemTile.cpp | 18 - Minecraft.World/Blocks/LiquidTile.cpp | 34 +- Minecraft.World/Blocks/LiquidTile.h | 2 +- Minecraft.World/Blocks/LiquidTileDynamic.cpp | 26 +- Minecraft.World/Blocks/LiquidTileDynamic.h | 1 + Minecraft.World/Blocks/LiquidTileStatic.cpp | 11 +- Minecraft.World/Blocks/LockedChestTile.cpp | 2 +- Minecraft.World/Blocks/MelonTile.cpp | 7 +- Minecraft.World/Blocks/MelonTile.h | 3 - Minecraft.World/Blocks/MobSpawner.cpp | 193 +- Minecraft.World/Blocks/MobSpawner.h | 12 +- Minecraft.World/Blocks/MobSpawnerTile.cpp | 4 +- Minecraft.World/Blocks/MobSpawnerTile.h | 4 +- Minecraft.World/Blocks/MushroomPlantTile.cpp | 19 +- Minecraft.World/Blocks/MushroomPlantTile.h | 6 +- Minecraft.World/Blocks/MycelTile.cpp | 4 +- Minecraft.World/Blocks/NetherStalkTile.cpp | 100 - Minecraft.World/Blocks/NetherWartTile.cpp | 90 + .../{NetherStalkTile.h => NetherWartTile.h} | 8 +- Minecraft.World/Blocks/NetherrackTile.cpp | 4 + Minecraft.World/Blocks/NetherrackTile.h | 7 + Minecraft.World/Blocks/NotGateTile.cpp | 71 +- Minecraft.World/Blocks/NotGateTile.h | 9 +- .../{MusicTile.cpp => NoteBlockTile.cpp} | 31 +- .../Blocks/{MusicTile.h => NoteBlockTile.h} | 8 +- Minecraft.World/Blocks/PistonBaseTile.cpp | 135 +- Minecraft.World/Blocks/PistonBaseTile.h | 9 +- .../Blocks/PistonExtensionTile.cpp | 28 +- Minecraft.World/Blocks/PistonExtensionTile.h | 10 +- .../Blocks/PistonMovingTileEntity.cpp | 9 +- .../Blocks/PistonMovingTileEntity.h | 4 +- Minecraft.World/Blocks/PlantTile.cpp | 8 +- Minecraft.World/Blocks/PortalTile.cpp | 33 +- Minecraft.World/Blocks/PotatoTile.cpp | 3 +- Minecraft.World/Blocks/PoweredMetalTile.cpp | 12 + Minecraft.World/Blocks/PoweredMetalTile.h | 11 + Minecraft.World/Blocks/PoweredRailTile.cpp | 153 ++ Minecraft.World/Blocks/PoweredRailTile.h | 26 + Minecraft.World/Blocks/PressurePlateTile.cpp | 202 +- Minecraft.World/Blocks/PressurePlateTile.h | 52 +- Minecraft.World/Blocks/PumpkinTile.cpp | 66 +- Minecraft.World/Blocks/PumpkinTile.h | 3 +- Minecraft.World/Blocks/QuartzBlockTile.cpp | 27 +- Minecraft.World/Blocks/RailTile.cpp | 559 +---- Minecraft.World/Blocks/RailTile.h | 94 +- Minecraft.World/Blocks/RecordPlayerTile.cpp | 103 - Minecraft.World/Blocks/RecordPlayerTile.h | 73 - Minecraft.World/Blocks/RedLightTile.cpp | 9 +- Minecraft.World/Blocks/RedStoneDustTile.cpp | 185 +- Minecraft.World/Blocks/RedStoneDustTile.h | 5 +- Minecraft.World/Blocks/RedStoneOreTile.cpp | 8 +- Minecraft.World/Blocks/RedStoneOreTile.h | 2 +- Minecraft.World/Blocks/ReedTile.cpp | 10 +- Minecraft.World/Blocks/RepeaterTile.cpp | 109 + Minecraft.World/Blocks/RepeaterTile.h | 42 + Minecraft.World/Blocks/RotatedPillarTile.cpp | 64 + Minecraft.World/Blocks/RotatedPillarTile.h | 36 + Minecraft.World/Blocks/SaplingPlantTile.cpp | 46 +- Minecraft.World/Blocks/SaplingPlantTile.h | 8 +- Minecraft.World/Blocks/SignTile.cpp | 10 +- Minecraft.World/Blocks/SignTile.h | 4 +- Minecraft.World/Blocks/SkullTile.cpp | 294 ++- Minecraft.World/Blocks/SkullTile.h | 10 +- .../Blocks/SmoothStoneBrickTile.cpp | 7 +- Minecraft.World/Blocks/SnowTile.cpp | 2 +- .../{HellSandTile.cpp => SoulSandTile.cpp} | 8 +- .../Blocks/{HellSandTile.h => SoulSandTile.h} | 4 +- Minecraft.World/Blocks/SpringTile.cpp | 33 - Minecraft.World/Blocks/SpringTile.h | 16 - Minecraft.World/Blocks/StainedGlassBlock.cpp | 35 + Minecraft.World/Blocks/StainedGlassBlock.h | 27 + .../Blocks/StainedGlassPaneBlock.cpp | 42 + .../Blocks/StainedGlassPaneBlock.h | 23 + Minecraft.World/Blocks/StairTile.cpp | 59 +- Minecraft.World/Blocks/StairTile.h | 98 +- Minecraft.World/Blocks/StemTile.cpp | 35 +- Minecraft.World/Blocks/StemTile.h | 2 +- Minecraft.World/Blocks/StoneButtonTile.cpp | 9 + Minecraft.World/Blocks/StoneButtonTile.h | 10 + Minecraft.World/Blocks/StoneMonsterTile.cpp | 32 +- Minecraft.World/Blocks/StoneSlabTile.cpp | 4 +- Minecraft.World/Blocks/StoneTile.cpp | 2 +- Minecraft.World/Blocks/TallGrassPlantTile.cpp | 2 +- .../Blocks/TheEndPortalFrameTile.cpp | 23 +- .../Blocks/TheEndPortalFrameTile.h | 6 +- Minecraft.World/Blocks/TheEndPortalTile.cpp | 17 +- Minecraft.World/Blocks/TheEndPortalTile.h | 4 +- Minecraft.World/Blocks/ThinFenceTile.cpp | 9 +- Minecraft.World/Blocks/ThinFenceTile.h | 2 +- Minecraft.World/Blocks/Tile.cpp | 1853 +++++++++-------- Minecraft.World/Blocks/Tile.h | 214 +- .../Blocks/TileEntities/BeaconTileEntity.cpp | 302 +++ .../Blocks/TileEntities/BeaconTileEntity.h | 75 + .../TileEntities/BrewingStandTileEntity.cpp | 79 +- .../TileEntities/BrewingStandTileEntity.h | 25 +- .../Blocks/TileEntities/ChestTileEntity.cpp | 185 +- .../Blocks/TileEntities/ChestTileEntity.h | 31 +- .../TileEntities/CommandBlockEntity.cpp | 99 + .../Blocks/TileEntities/CommandBlockEntity.h | 43 + .../TileEntities/ComparatorTileEntity.cpp | 28 + .../TileEntities/ComparatorTileEntity.h | 21 + .../DaylightDetectorTileEntity.cpp | 26 + .../TileEntities/DaylightDetectorTileEntity.h | 15 + .../TileEntities/DispenserTileEntity.cpp | 102 +- .../Blocks/TileEntities/DispenserTileEntity.h | 21 +- .../Blocks/TileEntities/DropperTileEntity.cpp | 18 + .../Blocks/TileEntities/DropperTileEntity.h | 14 + .../EnchantmentTableTileEntity.cpp | 25 + .../TileEntities/EnchantmentTableTileEntity.h | 8 + .../TileEntities/EnderChestTileEntity.cpp | 4 +- .../TileEntities/EnderChestTileEntity.h | 2 +- .../Blocks/TileEntities/EntityTile.cpp | 30 - .../Blocks/TileEntities/EntityTile.h | 12 +- .../Blocks/TileEntities/FurnaceTileEntity.cpp | 180 +- .../Blocks/TileEntities/FurnaceTileEntity.h | 39 +- Minecraft.World/Blocks/TileEntities/Hopper.h | 13 + .../Blocks/TileEntities/HopperTileEntity.cpp | 435 ++++ .../Blocks/TileEntities/HopperTileEntity.h | 91 + .../TileEntities/MobSpawnerTileEntity.cpp | 209 +- .../TileEntities/MobSpawnerTileEntity.h | 49 +- .../Blocks/TileEntities/MusicTileEntity.cpp | 2 +- .../TileEntities/PistonPieceTileEntity.cpp | 12 +- .../Blocks/TileEntities/PotionBrewing.cpp | 53 +- .../Blocks/TileEntities/PotionBrewing.h | 15 + .../Blocks/TileEntities/SignTileEntity.cpp | 21 +- .../Blocks/TileEntities/SignTileEntity.h | 5 +- .../Blocks/TileEntities/SkullTileEntity.cpp | 2 +- .../Blocks/TileEntities/TileEntity.cpp | 25 +- .../Blocks/TileEntities/TileEntity.h | 22 +- Minecraft.World/Blocks/TntTile.cpp | 53 +- Minecraft.World/Blocks/TntTile.h | 34 +- Minecraft.World/Blocks/TopSnowTile.cpp | 46 +- Minecraft.World/Blocks/TorchTile.cpp | 24 +- Minecraft.World/Blocks/TorchTile.h | 5 +- Minecraft.World/Blocks/TrapDoorTile.cpp | 18 +- Minecraft.World/Blocks/TreeTile.cpp | 71 +- Minecraft.World/Blocks/TreeTile.h | 17 +- Minecraft.World/Blocks/TripWireSourceTile.cpp | 51 +- Minecraft.World/Blocks/TripWireSourceTile.h | 5 +- Minecraft.World/Blocks/TripWireTile.cpp | 19 +- Minecraft.World/Blocks/VineTile.cpp | 34 +- Minecraft.World/Blocks/WallTile.cpp | 4 +- Minecraft.World/Blocks/WaterLilyTile.cpp | 4 +- .../Blocks/WeightedPressurePlateTile.cpp | 41 + .../Blocks/WeightedPressurePlateTile.h | 18 + Minecraft.World/Blocks/WoodButtonTile.cpp | 9 + Minecraft.World/Blocks/WoodButtonTile.h | 10 + Minecraft.World/Blocks/WoodTile.cpp | 7 +- Minecraft.World/Blocks/WoolCarpetTile.cpp | 4 +- Minecraft.World/Blocks/WorkbenchTile.cpp | 1 + 241 files changed, 8070 insertions(+), 4644 deletions(-) create mode 100644 Minecraft.World/Blocks/BaseEntityTile.cpp create mode 100644 Minecraft.World/Blocks/BaseEntityTile.h create mode 100644 Minecraft.World/Blocks/BasePressurePlateTile.cpp create mode 100644 Minecraft.World/Blocks/BasePressurePlateTile.h create mode 100644 Minecraft.World/Blocks/BaseRailTile.cpp create mode 100644 Minecraft.World/Blocks/BaseRailTile.h create mode 100644 Minecraft.World/Blocks/BeaconTile.cpp create mode 100644 Minecraft.World/Blocks/BeaconTile.h delete mode 100644 Minecraft.World/Blocks/ClothTile.cpp create mode 100644 Minecraft.World/Blocks/ColoredTile.cpp rename Minecraft.World/Blocks/{ClothTile.h => ColoredTile.h} (50%) create mode 100644 Minecraft.World/Blocks/CommandBlock.cpp create mode 100644 Minecraft.World/Blocks/CommandBlock.h create mode 100644 Minecraft.World/Blocks/ComparatorTile.cpp create mode 100644 Minecraft.World/Blocks/ComparatorTile.h create mode 100644 Minecraft.World/Blocks/DaylightDetectorTile.cpp create mode 100644 Minecraft.World/Blocks/DaylightDetectorTile.h create mode 100644 Minecraft.World/Blocks/DropperTile.cpp create mode 100644 Minecraft.World/Blocks/DropperTile.h create mode 100644 Minecraft.World/Blocks/GlowstoneTile.cpp rename Minecraft.World/Blocks/{LightGemTile.h => GlowstoneTile.h} (75%) create mode 100644 Minecraft.World/Blocks/HayBlockTile.cpp create mode 100644 Minecraft.World/Blocks/HayBlockTile.h delete mode 100644 Minecraft.World/Blocks/HellStoneTile.cpp delete mode 100644 Minecraft.World/Blocks/HellStoneTile.h create mode 100644 Minecraft.World/Blocks/HopperTile.cpp create mode 100644 Minecraft.World/Blocks/HopperTile.h create mode 100644 Minecraft.World/Blocks/JukeboxTile.cpp create mode 100644 Minecraft.World/Blocks/JukeboxTile.h delete mode 100644 Minecraft.World/Blocks/LightGemTile.cpp delete mode 100644 Minecraft.World/Blocks/NetherStalkTile.cpp create mode 100644 Minecraft.World/Blocks/NetherWartTile.cpp rename Minecraft.World/Blocks/{NetherStalkTile.h => NetherWartTile.h} (89%) create mode 100644 Minecraft.World/Blocks/NetherrackTile.cpp create mode 100644 Minecraft.World/Blocks/NetherrackTile.h rename Minecraft.World/Blocks/{MusicTile.cpp => NoteBlockTile.cpp} (68%) rename Minecraft.World/Blocks/{MusicTile.h => NoteBlockTile.h} (79%) create mode 100644 Minecraft.World/Blocks/PoweredMetalTile.cpp create mode 100644 Minecraft.World/Blocks/PoweredMetalTile.h create mode 100644 Minecraft.World/Blocks/PoweredRailTile.cpp create mode 100644 Minecraft.World/Blocks/PoweredRailTile.h delete mode 100644 Minecraft.World/Blocks/RecordPlayerTile.cpp delete mode 100644 Minecraft.World/Blocks/RecordPlayerTile.h create mode 100644 Minecraft.World/Blocks/RepeaterTile.cpp create mode 100644 Minecraft.World/Blocks/RepeaterTile.h create mode 100644 Minecraft.World/Blocks/RotatedPillarTile.cpp create mode 100644 Minecraft.World/Blocks/RotatedPillarTile.h rename Minecraft.World/Blocks/{HellSandTile.cpp => SoulSandTile.cpp} (60%) rename Minecraft.World/Blocks/{HellSandTile.h => SoulSandTile.h} (81%) delete mode 100644 Minecraft.World/Blocks/SpringTile.cpp delete mode 100644 Minecraft.World/Blocks/SpringTile.h create mode 100644 Minecraft.World/Blocks/StainedGlassBlock.cpp create mode 100644 Minecraft.World/Blocks/StainedGlassBlock.h create mode 100644 Minecraft.World/Blocks/StainedGlassPaneBlock.cpp create mode 100644 Minecraft.World/Blocks/StainedGlassPaneBlock.h create mode 100644 Minecraft.World/Blocks/StoneButtonTile.cpp create mode 100644 Minecraft.World/Blocks/StoneButtonTile.h create mode 100644 Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/BeaconTileEntity.h create mode 100644 Minecraft.World/Blocks/TileEntities/CommandBlockEntity.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/CommandBlockEntity.h create mode 100644 Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.h create mode 100644 Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.h create mode 100644 Minecraft.World/Blocks/TileEntities/DropperTileEntity.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/DropperTileEntity.h delete mode 100644 Minecraft.World/Blocks/TileEntities/EntityTile.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/Hopper.h create mode 100644 Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp create mode 100644 Minecraft.World/Blocks/TileEntities/HopperTileEntity.h create mode 100644 Minecraft.World/Blocks/WeightedPressurePlateTile.cpp create mode 100644 Minecraft.World/Blocks/WeightedPressurePlateTile.h create mode 100644 Minecraft.World/Blocks/WoodButtonTile.cpp create mode 100644 Minecraft.World/Blocks/WoodButtonTile.h diff --git a/Minecraft.World/Blocks/AnvilTile.cpp b/Minecraft.World/Blocks/AnvilTile.cpp index 7e2f3e3ec..5e158ed19 100644 --- a/Minecraft.World/Blocks/AnvilTile.cpp +++ b/Minecraft.World/Blocks/AnvilTile.cpp @@ -16,7 +16,8 @@ const unsigned int AnvilTile::ANVIL_NAMES[ANVIL_NAMES_LENGTH] = { std::wstring AnvilTile::TEXTURE_DAMAGE_NAMES[ANVIL_NAMES_LENGTH] = { L"anvil_top", L"anvil_top_damaged_1", L"anvil_top_damaged_2"}; -AnvilTile::AnvilTile(int id) : HeavyTile(id, Material::heavyMetal, false) { +AnvilTile::AnvilTile(int id) + : HeavyTile(id, Material::heavyMetal, false) { part = PART_BASE; setLightBlock(0); icons = NULL; @@ -44,15 +45,24 @@ void AnvilTile::registerIcons(IconRegister* iconRegister) { } void AnvilTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3; int dmg = level->getData(x, y, z) >> 2; dir = ++dir % 4; - if (dir == 0) level->setData(x, y, z, Direction::NORTH | (dmg << 2)); - if (dir == 1) level->setData(x, y, z, Direction::EAST | (dmg << 2)); - if (dir == 2) level->setData(x, y, z, Direction::SOUTH | (dmg << 2)); - if (dir == 3) level->setData(x, y, z, Direction::WEST | (dmg << 2)); + if (dir == 0) + level->setData(x, y, z, Direction::NORTH | (dmg << 2), + Tile::UPDATE_CLIENTS); + if (dir == 1) + level->setData(x, y, z, Direction::EAST | (dmg << 2), + Tile::UPDATE_CLIENTS); + if (dir == 2) + level->setData(x, y, z, Direction::SOUTH | (dmg << 2), + Tile::UPDATE_CLIENTS); + if (dir == 3) + level->setData(x, y, z, Direction::WEST | (dmg << 2), + Tile::UPDATE_CLIENTS); } bool AnvilTile::use(Level* level, int x, int y, int z, @@ -92,4 +102,4 @@ void AnvilTile::onLand(Level* level, int xt, int yt, int zt, int data) { bool AnvilTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { return true; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/AnvilTile.h b/Minecraft.World/Blocks/AnvilTile.h index 30c8882a2..141940a50 100644 --- a/Minecraft.World/Blocks/AnvilTile.h +++ b/Minecraft.World/Blocks/AnvilTile.h @@ -36,7 +36,8 @@ public: Icon* getTexture(int face, int data); void registerIcons(IconRegister* iconRegister); void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); bool use(Level* level, int x, int y, int z, std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); diff --git a/Minecraft.World/Blocks/BaseEntityTile.cpp b/Minecraft.World/Blocks/BaseEntityTile.cpp new file mode 100644 index 000000000..9bd4763da --- /dev/null +++ b/Minecraft.World/Blocks/BaseEntityTile.cpp @@ -0,0 +1,32 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.entity.h" +#include "TileEntities/TileEntity.h" +#include "BaseEntityTile.h" + +BaseEntityTile::BaseEntityTile(int id, Material* material, + bool isSolidRender /*= true*/) + : Tile(id, material, isSolidRender) { + _isEntityTile = true; +} + +void BaseEntityTile::onPlace(Level* level, int x, int y, int z) { + Tile::onPlace(level, x, y, z); + // level->setTileEntity(x, y, z, newTileEntity(level)); +} + +void BaseEntityTile::onRemove(Level* level, int x, int y, int z, int id, + int data) { + Tile::onRemove(level, x, y, z, id, data); + level->removeTileEntity(x, y, z); +} + +bool BaseEntityTile::triggerEvent(Level* level, int x, int y, int z, int b0, + int b1) { + Tile::triggerEvent(level, x, y, z, b0, b1); + std::shared_ptr te = level->getTileEntity(x, y, z); + if (te != NULL) { + return te->triggerEvent(b0, b1); + } + return false; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/BaseEntityTile.h b/Minecraft.World/Blocks/BaseEntityTile.h new file mode 100644 index 000000000..efb07a99c --- /dev/null +++ b/Minecraft.World/Blocks/BaseEntityTile.h @@ -0,0 +1,16 @@ +#pragma once +#include "Tile.h" +#include "TileEntities/EntityTile.h" + +class TileEntity; + +class BaseEntityTile : public Tile, public EntityTile { +protected: + BaseEntityTile(int id, Material* material, bool isSolidRender = true); + +public: + virtual void onPlace(Level* level, int x, int y, int z); + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + virtual bool triggerEvent(Level* level, int x, int y, int z, int b0, + int b1); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.cpp b/Minecraft.World/Blocks/BasePressurePlateTile.cpp new file mode 100644 index 000000000..740e0a871 --- /dev/null +++ b/Minecraft.World/Blocks/BasePressurePlateTile.cpp @@ -0,0 +1,163 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.phys.h" +#include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.h" +#include "BasePressurePlateTile.h" + +BasePressurePlateTile::BasePressurePlateTile(int id, const std::wstring& tex, + Material* material) + : Tile(id, material, false) { + texture = tex; + setTicking(true); + + // 4J Stu - Move this to derived classes + // updateShape(getDataForSignal(Redstone::SIGNAL_MAX)); +} + +void BasePressurePlateTile::updateShape( + LevelSource* level, int x, int y, int z, int forceData, + std::shared_ptr forceEntity) { + updateShape(level->getData(x, y, z)); +} + +void BasePressurePlateTile::updateShape(int data) { + bool pressed = getSignalForData(data) > Redstone::SIGNAL_NONE; + float o = 1 / 16.0f; + + if (pressed) { + setShape(o, 0, o, 1 - o, 0.5f / 16.0f, 1 - o); + } else { + setShape(o, 0, o, 1 - o, 1 / 16.0f, 1 - o); + } +} + +int BasePressurePlateTile::getTickDelay(Level* level) { + return SharedConstants::TICKS_PER_SECOND; +} + +AABB* BasePressurePlateTile::getAABB(Level* level, int x, int y, int z) { + return NULL; +} + +bool BasePressurePlateTile::isSolidRender(bool isServerLevel) { return false; } + +bool BasePressurePlateTile::blocksLight() { return false; } + +bool BasePressurePlateTile::isCubeShaped() { return false; } + +bool BasePressurePlateTile::isPathfindable(LevelSource* level, int x, int y, + int z) { + return true; +} + +bool BasePressurePlateTile::mayPlace(Level* level, int x, int y, int z) { + return level->isTopSolidBlocking(x, y - 1, z) || + FenceTile::isFence(level->getTile(x, y - 1, z)); +} + +void BasePressurePlateTile::neighborChanged(Level* level, int x, int y, int z, + int type) { + bool replace = false; + + if (!level->isTopSolidBlocking(x, y - 1, z) && + !FenceTile::isFence(level->getTile(x, y - 1, z))) + replace = true; + + if (replace) { + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); + } +} + +void BasePressurePlateTile::tick(Level* level, int x, int y, int z, + Random* random) { + if (level->isClientSide) return; + int signal = getSignalForData(level->getData(x, y, z)); + if (signal > Redstone::SIGNAL_NONE) checkPressed(level, x, y, z, signal); +} + +void BasePressurePlateTile::entityInside(Level* level, int x, int y, int z, + std::shared_ptr entity) { + if (level->isClientSide) return; + int signal = getSignalForData(level->getData(x, y, z)); + if (signal == Redstone::SIGNAL_NONE) checkPressed(level, x, y, z, signal); +} + +void BasePressurePlateTile::checkPressed(Level* level, int x, int y, int z, + int oldSignal) { + int signal = getSignalStrength(level, x, y, z); + bool wasPressed = oldSignal > Redstone::SIGNAL_NONE; + bool shouldBePressed = signal > Redstone::SIGNAL_NONE; + + if (oldSignal != signal) { + level->setData(x, y, z, getDataForSignal(signal), Tile::UPDATE_CLIENTS); + updateNeighbours(level, x, y, z); + level->setTilesDirty(x, y, z, x, y, z); + } + + if (!shouldBePressed && wasPressed) { + level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, + 0.3f, 0.5f); + } else if (shouldBePressed && !wasPressed) { + level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, + 0.3f, 0.6f); + } + + if (shouldBePressed) { + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); + } +} + +AABB* BasePressurePlateTile::getSensitiveAABB(int x, int y, int z) { + float b = 2 / 16.0f; + return AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b); +} + +void BasePressurePlateTile::onRemove(Level* level, int x, int y, int z, int id, + int data) { + if (getSignalForData(data) > 0) { + updateNeighbours(level, x, y, z); + } + + Tile::onRemove(level, x, y, z, id, data); +} + +void BasePressurePlateTile::updateNeighbours(Level* level, int x, int y, + int z) { + level->updateNeighborsAt(x, y, z, id); + level->updateNeighborsAt(x, y - 1, z, id); +} + +int BasePressurePlateTile::getSignal(LevelSource* level, int x, int y, int z, + int dir) { + return getSignalForData(level->getData(x, y, z)); +} + +int BasePressurePlateTile::getDirectSignal(LevelSource* level, int x, int y, + int z, int dir) { + if (dir == Facing::UP) { + return getSignalForData(level->getData(x, y, z)); + } else { + return Redstone::SIGNAL_NONE; + } +} + +bool BasePressurePlateTile::isSignalSource() { return true; } + +void BasePressurePlateTile::updateDefaultShape() { + float x = 8 / 16.0f; + float y = 2 / 16.0f; + float z = 8 / 16.0f; + setShape(0.5f - x, 0.5f - y, 0.5f - z, 0.5f + x, 0.5f + y, 0.5f + z); +} + +int BasePressurePlateTile::getPistonPushReaction() { + return Material::PUSH_DESTROY; +} + +void BasePressurePlateTile::registerIcons(IconRegister* iconRegister) { + icon = iconRegister->registerIcon(texture); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.h b/Minecraft.World/Blocks/BasePressurePlateTile.h new file mode 100644 index 000000000..62d8de583 --- /dev/null +++ b/Minecraft.World/Blocks/BasePressurePlateTile.h @@ -0,0 +1,59 @@ +#pragma once + +#include "Tile.h" + +class BasePressurePlateTile : public Tile { +private: + std::wstring texture; + +protected: + BasePressurePlateTile(int id, const std::wstring& tex, Material* material); + +public: + virtual void updateShape(LevelSource* level, int x, int y, int z, + int forceData = -1, + std::shared_ptr forceEntity = + std::shared_ptr()); + +protected: + virtual void updateShape(int data); + +public: + virtual int getTickDelay(Level* level); + virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual bool isSolidRender(bool isServerLevel = false); + virtual bool blocksLight(); + virtual bool isCubeShaped(); + virtual bool isPathfindable(LevelSource* level, int x, int y, int z); + virtual bool mayPlace(Level* level, int x, int y, int z); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual void entityInside(Level* level, int x, int y, int z, + std::shared_ptr entity); + +protected: + virtual void checkPressed(Level* level, int x, int y, int z, int oldSignal); + virtual AABB* getSensitiveAABB(int x, int y, int z); + +public: + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + +protected: + virtual void updateNeighbours(Level* level, int x, int y, int z); + +public: + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); + virtual bool isSignalSource(); + virtual void updateDefaultShape(); + virtual int getPistonPushReaction(); + +protected: + virtual int getSignalStrength(Level* level, int x, int y, int z) = 0; + virtual int getSignalForData(int data) = 0; + virtual int getDataForSignal(int signal) = 0; + +public: + virtual void registerIcons(IconRegister* iconRegister); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/BaseRailTile.cpp b/Minecraft.World/Blocks/BaseRailTile.cpp new file mode 100644 index 000000000..6478c61bb --- /dev/null +++ b/Minecraft.World/Blocks/BaseRailTile.cpp @@ -0,0 +1,418 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.phys.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.h" +#include "BaseRailTile.h" + +BaseRailTile::Rail::Rail(Level* level, int x, int y, int z) { + this->level = level; + this->x = x; + this->y = y; + this->z = z; + + int id = level->getTile(x, y, z); + + // 4J Stu - We saw a random crash near the end of development on XboxOne + // orignal version where the id here isn't a tile any more Adding this check + // in to avoid that crash + m_bValidRail = isRail(id); + if (m_bValidRail) { + int direction = level->getData(x, y, z); + if (((BaseRailTile*)Tile::tiles[id])->usesDataBit) { + usesDataBit = true; + direction = direction & ~RAIL_DATA_BIT; + } else { + usesDataBit = false; + } + updateConnections(direction); + } +} + +BaseRailTile::Rail::~Rail() { + for (int i = 0; i < connections.size(); i++) { + delete connections[i]; + } +} + +void BaseRailTile::Rail::updateConnections(int direction) { + if (m_bValidRail) { + for (int i = 0; i < connections.size(); i++) { + delete connections[i]; + } + connections.clear(); + MemSect(50); + if (direction == DIR_FLAT_Z) { + connections.push_back(new TilePos(x, y, z - 1)); + connections.push_back(new TilePos(x, y, z + 1)); + } else if (direction == DIR_FLAT_X) { + connections.push_back(new TilePos(x - 1, y, z)); + connections.push_back(new TilePos(x + 1, y, z)); + } else if (direction == 2) { + connections.push_back(new TilePos(x - 1, y, z)); + connections.push_back(new TilePos(x + 1, y + 1, z)); + } else if (direction == 3) { + connections.push_back(new TilePos(x - 1, y + 1, z)); + connections.push_back(new TilePos(x + 1, y, z)); + } else if (direction == 4) { + connections.push_back(new TilePos(x, y + 1, z - 1)); + connections.push_back(new TilePos(x, y, z + 1)); + } else if (direction == 5) { + connections.push_back(new TilePos(x, y, z - 1)); + connections.push_back(new TilePos(x, y + 1, z + 1)); + } else if (direction == 6) { + connections.push_back(new TilePos(x + 1, y, z)); + connections.push_back(new TilePos(x, y, z + 1)); + } else if (direction == 7) { + connections.push_back(new TilePos(x - 1, y, z)); + connections.push_back(new TilePos(x, y, z + 1)); + } else if (direction == 8) { + connections.push_back(new TilePos(x - 1, y, z)); + connections.push_back(new TilePos(x, y, z - 1)); + } else if (direction == 9) { + connections.push_back(new TilePos(x + 1, y, z)); + connections.push_back(new TilePos(x, y, z - 1)); + } + MemSect(0); + } +} + +void BaseRailTile::Rail::removeSoftConnections() { + if (m_bValidRail) { + for (unsigned int i = 0; i < connections.size(); i++) { + Rail* rail = getRail(connections[i]); + if (rail == NULL || !rail->connectsTo(this)) { + delete connections[i]; + connections.erase(connections.begin() + i); + i--; + } else { + delete connections[i]; + MemSect(50); + connections[i] = new TilePos(rail->x, rail->y, rail->z); + MemSect(0); + } + delete rail; + } + } +} + +bool BaseRailTile::Rail::hasRail(int x, int y, int z) { + if (!m_bValidRail) return false; + if (isRail(level, x, y, z)) return true; + if (isRail(level, x, y + 1, z)) return true; + if (isRail(level, x, y - 1, z)) return true; + return false; +} + +BaseRailTile::Rail* BaseRailTile::Rail::getRail(TilePos* p) { + if (!m_bValidRail) return NULL; + if (isRail(level, p->x, p->y, p->z)) + return new Rail(level, p->x, p->y, p->z); + if (isRail(level, p->x, p->y + 1, p->z)) + return new Rail(level, p->x, p->y + 1, p->z); + if (isRail(level, p->x, p->y - 1, p->z)) + return new Rail(level, p->x, p->y - 1, p->z); + return NULL; +} + +bool BaseRailTile::Rail::connectsTo(Rail* rail) { + if (m_bValidRail) { + AUTO_VAR(itEnd, connections.end()); + for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) { + TilePos* p = *it; // connections[i]; + if (p->x == rail->x && p->z == rail->z) { + return true; + } + } + } + return false; +} + +bool BaseRailTile::Rail::hasConnection(int x, int y, int z) { + if (m_bValidRail) { + AUTO_VAR(itEnd, connections.end()); + for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) { + TilePos* p = *it; // connections[i]; + if (p->x == x && p->z == z) { + return true; + } + } + } + return false; +} + +int BaseRailTile::Rail::countPotentialConnections() { + int count = 0; + + if (m_bValidRail) { + if (hasRail(x, y, z - 1)) count++; + if (hasRail(x, y, z + 1)) count++; + if (hasRail(x - 1, y, z)) count++; + if (hasRail(x + 1, y, z)) count++; + } + + return count; +} + +bool BaseRailTile::Rail::canConnectTo(Rail* rail) { + if (!m_bValidRail) return false; + if (connectsTo(rail)) return true; + if (connections.size() == 2) { + return false; + } + if (connections.empty()) { + return true; + } + + return true; +} + +void BaseRailTile::Rail::connectTo(Rail* rail) { + if (m_bValidRail) { + MemSect(50); + connections.push_back(new TilePos(rail->x, rail->y, rail->z)); + MemSect(0); + + bool n = hasConnection(x, y, z - 1); + bool s = hasConnection(x, y, z + 1); + bool w = hasConnection(x - 1, y, z); + bool e = hasConnection(x + 1, y, z); + + int dir = -1; + + if (n || s) dir = DIR_FLAT_Z; + if (w || e) dir = DIR_FLAT_X; + + if (!usesDataBit) { + if (s && e && !n && !w) dir = 6; + if (s && w && !n && !e) dir = 7; + if (n && w && !s && !e) dir = 8; + if (n && e && !s && !w) dir = 9; + } + if (dir == DIR_FLAT_Z) { + if (isRail(level, x, y + 1, z - 1)) dir = 4; + if (isRail(level, x, y + 1, z + 1)) dir = 5; + } + if (dir == DIR_FLAT_X) { + if (isRail(level, x + 1, y + 1, z)) dir = 2; + if (isRail(level, x - 1, y + 1, z)) dir = 3; + } + + if (dir < 0) dir = DIR_FLAT_Z; + + int data = dir; + if (usesDataBit) { + data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir; + } + + level->setData(x, y, z, data, Tile::UPDATE_ALL); + } +} + +bool BaseRailTile::Rail::hasNeighborRail(int x, int y, int z) { + if (!m_bValidRail) return false; + TilePos tp(x, y, z); + Rail* neighbor = getRail(&tp); + if (neighbor == NULL) return false; + neighbor->removeSoftConnections(); + bool retval = neighbor->canConnectTo(this); + delete neighbor; + return retval; +} + +void BaseRailTile::Rail::place(bool hasSignal, bool first) { + if (m_bValidRail) { + bool n = hasNeighborRail(x, y, z - 1); + bool s = hasNeighborRail(x, y, z + 1); + bool w = hasNeighborRail(x - 1, y, z); + bool e = hasNeighborRail(x + 1, y, z); + + int dir = -1; + + if ((n || s) && !w && !e) dir = DIR_FLAT_Z; + if ((w || e) && !n && !s) dir = DIR_FLAT_X; + + if (!usesDataBit) { + if (s && e && !n && !w) dir = 6; + if (s && w && !n && !e) dir = 7; + if (n && w && !s && !e) dir = 8; + if (n && e && !s && !w) dir = 9; + } + if (dir == -1) { + if (n || s) dir = DIR_FLAT_Z; + if (w || e) dir = DIR_FLAT_X; + + if (!usesDataBit) { + if (hasSignal) { + if (s && e) dir = 6; + if (w && s) dir = 7; + if (e && n) dir = 9; + if (n && w) dir = 8; + } else { + if (n && w) dir = 8; + if (e && n) dir = 9; + if (w && s) dir = 7; + if (s && e) dir = 6; + } + } + } + + if (dir == DIR_FLAT_Z) { + if (isRail(level, x, y + 1, z - 1)) dir = 4; + if (isRail(level, x, y + 1, z + 1)) dir = 5; + } + if (dir == DIR_FLAT_X) { + if (isRail(level, x + 1, y + 1, z)) dir = 2; + if (isRail(level, x - 1, y + 1, z)) dir = 3; + } + + if (dir < 0) dir = DIR_FLAT_Z; + + updateConnections(dir); + + int data = dir; + if (usesDataBit) { + data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir; + } + + if (first || level->getData(x, y, z) != data) { + level->setData(x, y, z, data, Tile::UPDATE_ALL); + + AUTO_VAR(itEnd, connections.end()); + for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) { + Rail* neighbor = getRail(*it); + if (neighbor == NULL) continue; + neighbor->removeSoftConnections(); + + if (neighbor->canConnectTo(this)) { + neighbor->connectTo(this); + } + delete neighbor; + } + } + } +} + +bool BaseRailTile::isRail(Level* level, int x, int y, int z) { + return isRail(level->getTile(x, y, z)); +} + +bool BaseRailTile::isRail(int id) { + return id == Tile::rail_Id || id == Tile::goldenRail_Id || + id == Tile::detectorRail_Id || id == Tile::activatorRail_Id; +} + +BaseRailTile::BaseRailTile(int id, bool usesDataBit) + : Tile(id, Material::decoration, false) { + this->usesDataBit = usesDataBit; + setShape(0, 0, 0, 1, 2 / 16.0f, 1); + + iconTurn = NULL; +} + +bool BaseRailTile::isUsesDataBit() { return usesDataBit; } + +AABB* BaseRailTile::getAABB(Level* level, int x, int y, int z) { return NULL; } + +bool BaseRailTile::blocksLight() { return false; } + +bool BaseRailTile::isSolidRender(bool isServerLevel) { return false; } + +HitResult* BaseRailTile::clip(Level* level, int xt, int yt, int zt, Vec3* a, + Vec3* b) { + updateShape(level, xt, yt, zt); + return Tile::clip(level, xt, yt, zt, a, b); +} + +void BaseRailTile::updateShape( + LevelSource* level, int x, int y, int z, int forceData, + std::shared_ptr + forceEntity) // 4J added forceData, forceEntity param +{ + int data = level->getData(x, y, z); + if (data >= 2 && data <= 5) { + setShape(0, 0, 0, 1, 2 / 16.0f + 0.5f, 1); + } else { + setShape(0, 0, 0, 1, 2 / 16.0f, 1); + } +} + +bool BaseRailTile::isCubeShaped() { return false; } + +int BaseRailTile::getRenderShape() { return Tile::SHAPE_RAIL; } + +int BaseRailTile::getResourceCount(Random random) { return 1; } + +bool BaseRailTile::mayPlace(Level* level, int x, int y, int z) { + if (level->isTopSolidBlocking(x, y - 1, z)) { + return true; + } + return false; +} + +void BaseRailTile::onPlace(Level* level, int x, int y, int z) { + if (!level->isClientSide) { + updateDir(level, x, y, z, true); + + if (usesDataBit) { + neighborChanged(level, x, y, z, id); + } + } +} + +void BaseRailTile::neighborChanged(Level* level, int x, int y, int z, + int type) { + if (level->isClientSide) return; + + int data = level->getData(x, y, z); + int dir = data; + if (usesDataBit) { + dir = dir & RAIL_DIRECTION_MASK; + } + bool remove = false; + + if (!level->isTopSolidBlocking(x, y - 1, z)) remove = true; + if (dir == 2 && !level->isTopSolidBlocking(x + 1, y, z)) remove = true; + if (dir == 3 && !level->isTopSolidBlocking(x - 1, y, z)) remove = true; + if (dir == 4 && !level->isTopSolidBlocking(x, y, z - 1)) remove = true; + if (dir == 5 && !level->isTopSolidBlocking(x, y, z + 1)) remove = true; + + if (remove) { + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); + } else { + updateState(level, x, y, z, data, dir, type); + } +} + +void BaseRailTile::updateState(Level* level, int x, int y, int z, int data, + int dir, int type) {} + +void BaseRailTile::updateDir(Level* level, int x, int y, int z, bool first) { + if (level->isClientSide) return; + Rail* rail = new Rail(level, x, y, z); + rail->place(level->hasNeighborSignal(x, y, z), first); + delete rail; +} + +int BaseRailTile::getPistonPushReaction() { + // override the decoration material's reaction + return Material::PUSH_NORMAL; +} + +void BaseRailTile::onRemove(Level* level, int x, int y, int z, int id, + int data) { + int dir = data; + if (usesDataBit) { + dir &= RAIL_DIRECTION_MASK; + } + + Tile::onRemove(level, x, y, z, id, data); + + if (dir == 2 || dir == 3 || dir == 4 || dir == 5) { + level->updateNeighborsAt(x, y + 1, z, id); + } + if (usesDataBit) { + level->updateNeighborsAt(x, y, z, id); + level->updateNeighborsAt(x, y - 1, z, id); + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/BaseRailTile.h b/Minecraft.World/Blocks/BaseRailTile.h new file mode 100644 index 000000000..e352bd3ca --- /dev/null +++ b/Minecraft.World/Blocks/BaseRailTile.h @@ -0,0 +1,97 @@ +#pragma once +#include "Tile.h" +#include "../Level/TilePos.h" +#include "../Util/Definitions.h" + +class Random; +class HitResult; +class ChunkRebuildData; + +class BaseRailTile : public Tile { + friend class Tile; + friend class ChunkRebuildData; + +public: + static const int DIR_FLAT_Z = 0; + static const int DIR_FLAT_X = 1; + // the data bit is used by boosters and detectors, so they can't turn + static const int RAIL_DATA_BIT = 8; + static const int RAIL_DIRECTION_MASK = 7; + +private: + Icon* iconTurn; + +protected: + bool usesDataBit; + + class Rail { + friend class BaseRailTile; + friend class RailTile; + + private: + Level* level; + int x, y, z; + bool usesDataBit; + std::vector connections; + bool m_bValidRail; // 4J added + + public: + Rail(Level* level, int x, int y, int z); + ~Rail(); + + private: + void updateConnections(int direction); + void removeSoftConnections(); + bool hasRail(int x, int y, int z); + Rail* getRail(TilePos* p); + bool connectsTo(Rail* rail); + bool hasConnection(int x, int y, int z); + + protected: + int countPotentialConnections(); + + private: + bool canConnectTo(Rail* rail); + void connectTo(Rail* rail); + bool hasNeighborRail(int x, int y, int z); + + public: + void place(bool hasSignal, bool first); + }; + +public: + static bool isRail(Level* level, int x, int y, int z); + static bool isRail(int id); + +protected: + BaseRailTile(int id, bool usesDataBit); + +public: + using Tile::getResourceCount; + + bool isUsesDataBit(); + virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual bool blocksLight(); + virtual bool isSolidRender(bool isServerLevel = false); + virtual HitResult* clip(Level* level, int xt, int yt, int zt, Vec3* a, + Vec3* b); + virtual void updateShape( + LevelSource* level, int x, int y, int z, int forceData = -1, + std::shared_ptr forceEntity = std::shared_ptr< + TileEntity>()); // 4J added forceData, forceEntity param + virtual bool isCubeShaped(); + virtual int getRenderShape(); + virtual int getResourceCount(Random random); + virtual bool mayPlace(Level* level, int x, int y, int z); + virtual void onPlace(Level* level, int x, int y, int z); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + +protected: + virtual void updateState(Level* level, int x, int y, int z, int data, + int dir, int type); + virtual void updateDir(Level* level, int x, int y, int z, bool first); + +public: + int getPistonPushReaction(); + void onRemove(Level* level, int x, int y, int z, int id, int data); +}; diff --git a/Minecraft.World/Blocks/BeaconTile.cpp b/Minecraft.World/Blocks/BeaconTile.cpp new file mode 100644 index 000000000..641dbc0fa --- /dev/null +++ b/Minecraft.World/Blocks/BeaconTile.cpp @@ -0,0 +1,52 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "BeaconTile.h" + +BeaconTile::BeaconTile(int id) + : BaseEntityTile(id, Material::glass, false) { + setDestroyTime(3.0f); +} + +std::shared_ptr BeaconTile::newTileEntity(Level* level) { + return std::shared_ptr(new BeaconTileEntity()); +} + +bool BeaconTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, bool soundOnly) { + if (level->isClientSide) return true; + + std::shared_ptr beacon = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + if (beacon != NULL) player->openBeacon(beacon); + + return true; +} + +bool BeaconTile::isSolidRender(bool isServerLevel) { return false; } + +bool BeaconTile::isCubeShaped() { return false; } + +bool BeaconTile::blocksLight() { return false; } + +int BeaconTile::getRenderShape() { return SHAPE_BEACON; } + +void BeaconTile::registerIcons(IconRegister* iconRegister) { + BaseEntityTile::registerIcons(iconRegister); +} + +void BeaconTile::setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance) { + BaseEntityTile::setPlacedBy(level, x, y, z, by, itemInstance); + if (itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->setCustomName(itemInstance->getHoverName()); + } +} + +bool BeaconTile::TestUse() { return true; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/BeaconTile.h b/Minecraft.World/Blocks/BeaconTile.h new file mode 100644 index 000000000..f1e90a0b5 --- /dev/null +++ b/Minecraft.World/Blocks/BeaconTile.h @@ -0,0 +1,22 @@ +#pragma once + +#include "BaseEntityTile.h" + +class BeaconTile : public BaseEntityTile { +public: + BeaconTile(int id); + + std::shared_ptr newTileEntity(Level* level); + bool use(Level* level, int x, int y, int z, std::shared_ptr player, + int clickedFace, float clickX, float clickY, float clickZ, + bool soundOnly = false); + bool isSolidRender(bool isServerLevel = false); + bool isCubeShaped(); + bool blocksLight(); + int getRenderShape(); + void registerIcons(IconRegister* iconRegister); + void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); + virtual bool TestUse(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/BedTile.cpp b/Minecraft.World/Blocks/BedTile.cpp index 0982bdc1b..372e4105f 100644 --- a/Minecraft.World/Blocks/BedTile.cpp +++ b/Minecraft.World/Blocks/BedTile.cpp @@ -9,7 +9,8 @@ int BedTile::HEAD_DIRECTION_OFFSETS[4][2] = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}}; -BedTile::BedTile(int id) : DirectionalTile(id, Material::cloth, false) { +BedTile::BedTile(int id) + : DirectionalTile(id, Material::cloth, false) { setShape(); iconEnd = NULL; @@ -64,7 +65,7 @@ bool BedTile::use(Level* level, int x, int y, int z, int data = level->getData(x, y, z); - if (!BedTile::isHeadPiece(data)) { + if (!isHeadPiece(data)) { // fetch head piece instead int direction = getDirection(data); x += HEAD_DIRECTION_OFFSETS[direction][0]; @@ -75,16 +76,17 @@ bool BedTile::use(Level* level, int x, int y, int z, data = level->getData(x, y, z); } - if (!level->dimension->mayRespawn()) { + if (!level->dimension->mayRespawn() || + level->getBiome(x, z) == Biome::hell) { double xc = x + 0.5; double yc = y + 0.5; double zc = z + 0.5; - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); int direction = getDirection(data); x += HEAD_DIRECTION_OFFSETS[direction][0]; z += HEAD_DIRECTION_OFFSETS[direction][1]; if (level->getTile(x, y, z) == id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); xc = (xc + x + 0.5) / 2; yc = (yc + y + 0.5) / 2; zc = (zc + z + 0.5) / 2; @@ -93,7 +95,7 @@ bool BedTile::use(Level* level, int x, int y, int z, return true; } - if (BedTile::isOccupied(data)) { + if (isOccupied(data)) { std::shared_ptr sleepingPlayer = nullptr; AUTO_VAR(itEnd, level->players.end()); for (AUTO_VAR(it, level->players.begin()); it != itEnd; it++) { @@ -107,7 +109,7 @@ bool BedTile::use(Level* level, int x, int y, int z, } if (sleepingPlayer == NULL) { - BedTile::setOccupied(level, x, y, z, false); + setOccupied(level, x, y, z, false); } else { player->displayClientMessage(IDS_TILE_BED_OCCUPIED); @@ -117,7 +119,7 @@ bool BedTile::use(Level* level, int x, int y, int z, Player::BedSleepingResult result = player->startSleepInBed(x, y, z); if (result == Player::OK) { - BedTile::setOccupied(level, x, y, z, true); + setOccupied(level, x, y, z, true); // 4J-PB added // are there multiple players in the same world as us? if (level->AllPlayersAreSleeping() == false) { @@ -190,12 +192,12 @@ void BedTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (isHeadPiece(data)) { if (level->getTile(x - HEAD_DIRECTION_OFFSETS[direction][0], y, z - HEAD_DIRECTION_OFFSETS[direction][1]) != id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } else { if (level->getTile(x + HEAD_DIRECTION_OFFSETS[direction][0], y, z + HEAD_DIRECTION_OFFSETS[direction][1]) != id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); if (!level->isClientSide) { Tile::spawnResources( level, x, y, z, data, @@ -226,7 +228,7 @@ void BedTile::setOccupied(Level* level, int x, int y, int z, bool occupied) { } else { data = data & ~OCCUPIED_DATA; } - level->setData(x, y, z, data); + level->setData(x, y, z, data, Tile::UPDATE_NONE); } Pos* BedTile::findStandUpPosition(Level* level, int x, int y, int z, @@ -236,10 +238,8 @@ Pos* BedTile::findStandUpPosition(Level* level, int x, int y, int z, // try to find a clear location near the bed for (int step = 0; step <= 1; step++) { - int startX = - x - BedTile::HEAD_DIRECTION_OFFSETS[direction][0] * step - 1; - int startZ = - z - BedTile::HEAD_DIRECTION_OFFSETS[direction][1] * step - 1; + int startX = x - HEAD_DIRECTION_OFFSETS[direction][0] * step - 1; + int startZ = z - HEAD_DIRECTION_OFFSETS[direction][1] * step - 1; int endX = startX + 2; int endZ = startZ + 2; @@ -249,8 +249,9 @@ Pos* BedTile::findStandUpPosition(Level* level, int x, int y, int z, // isEmpty for the blocks that we wish to place the player This // allows the player to spawn in blocks with snow, grass etc if (level->isTopSolidBlocking(standX, y - 1, standZ) && - !level->isSolidBlockingTile(standX, y, standZ) && - !level->isSolidBlockingTile(standX, y + 1, standZ)) { + !level->getMaterial(standX, y, standZ)->isSolidBlocking() && + !level->getMaterial(standX, y + 1, standZ) + ->isSolidBlocking()) { if (skipCount > 0) { skipCount--; continue; @@ -276,3 +277,17 @@ int BedTile::getPistonPushReaction() { return Material::PUSH_DESTROY; } int BedTile::cloneTileId(Level* level, int x, int y, int z) { return Item::bed_Id; } + +void BedTile::playerWillDestroy(Level* level, int x, int y, int z, int data, + std::shared_ptr player) { + if (player->abilities.instabuild) { + if (isHeadPiece(data)) { + int direction = getDirection(data); + x -= HEAD_DIRECTION_OFFSETS[direction][0]; + z -= HEAD_DIRECTION_OFFSETS[direction][1]; + if (level->getTile(x, y, z) == id) { + level->removeTile(x, y, z); + } + } + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/BedTile.h b/Minecraft.World/Blocks/BedTile.h index 8b2ab316d..043256708 100644 --- a/Minecraft.World/Blocks/BedTile.h +++ b/Minecraft.World/Blocks/BedTile.h @@ -58,4 +58,6 @@ public: float odds, int playerBonus); virtual int getPistonPushReaction(); virtual int cloneTileId(Level* level, int x, int y, int z); + virtual void playerWillDestroy(Level* level, int x, int y, int z, int data, + std::shared_ptr player); }; diff --git a/Minecraft.World/Blocks/BrewingStandTile.cpp b/Minecraft.World/Blocks/BrewingStandTile.cpp index 749a3c8fe..67fdbe3fb 100644 --- a/Minecraft.World/Blocks/BrewingStandTile.cpp +++ b/Minecraft.World/Blocks/BrewingStandTile.cpp @@ -5,11 +5,10 @@ #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.h" - -const std::wstring BrewingStandTile::TEXTURE_BASE = L"brewingStand_base"; +#include "../Headers/net.minecraft.world.inventory.h" BrewingStandTile::BrewingStandTile(int id) - : EntityTile(id, Material::metal, false) { + : BaseEntityTile(id, Material::metal, false) { random = new Random(); iconBase = NULL; } @@ -31,9 +30,9 @@ void BrewingStandTile::addAABBs(Level* level, int x, int y, int z, AABB* box, std::shared_ptr source) { setShape(7.0f / 16.0f, 0, 7.0f / 16.0f, 9.0f / 16.0f, 14.0f / 16.0f, 9.0f / 16.0f); - EntityTile::addAABBs(level, x, y, z, box, boxes, source); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); updateDefaultShape(); - EntityTile::addAABBs(level, x, y, z, box, boxes, source); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); } void BrewingStandTile::updateDefaultShape() { @@ -58,6 +57,16 @@ bool BrewingStandTile::use( return true; } +void BrewingStandTile::setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance) { + if (itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->setCustomName(itemInstance->getHoverName()); + } +} + void BrewingStandTile::animateTick(Level* level, int xt, int yt, int zt, Random* random) { double x = xt + 0.4f + random->nextFloat() * 0.2f; @@ -105,7 +114,7 @@ void BrewingStandTile::onRemove(Level* level, int x, int y, int z, int id, } } } - EntityTile::onRemove(level, x, y, z, id, data); + BaseEntityTile::onRemove(level, x, y, z, id, data); } int BrewingStandTile::getResource(int data, Random* random, @@ -117,9 +126,17 @@ int BrewingStandTile::cloneTileId(Level* level, int x, int y, int z) { return Item::brewingStand_Id; } -void BrewingStandTile::registerIcons(IconRegister* iconRegister) { - EntityTile::registerIcons(iconRegister); - iconBase = iconRegister->registerIcon(TEXTURE_BASE); +bool BrewingStandTile::hasAnalogOutputSignal() { return true; } + +int BrewingStandTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + return AbstractContainerMenu::getRedstoneSignalFromContainer( + std::dynamic_pointer_cast(level->getTileEntity(x, y, z))); } -Icon* BrewingStandTile::getBaseTexture() { return iconBase; } +void BrewingStandTile::registerIcons(IconRegister* iconRegister) { + BaseEntityTile::registerIcons(iconRegister); + iconBase = iconRegister->registerIcon(getIconName() + L"_base"); +} + +Icon* BrewingStandTile::getBaseTexture() { return iconBase; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/BrewingStandTile.h b/Minecraft.World/Blocks/BrewingStandTile.h index 4be3140c2..30ae2bd7b 100644 --- a/Minecraft.World/Blocks/BrewingStandTile.h +++ b/Minecraft.World/Blocks/BrewingStandTile.h @@ -1,15 +1,12 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class IconRegister; class ChunkRebuildData; -class BrewingStandTile : public EntityTile { +class BrewingStandTile : public BaseEntityTile { friend ChunkRebuildData; -public: - static const std::wstring TEXTURE_BASE; - private: Random* random; Icon* iconBase; @@ -28,11 +25,17 @@ public: std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param + virtual void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); virtual void animateTick(Level* level, int xt, int yt, int zt, Random* random); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); virtual int getResource(int data, Random* random, int playerBonusLevel); virtual int cloneTileId(Level* level, int x, int y, int z); - void registerIcons(IconRegister* iconRegister); - Icon* getBaseTexture(); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + virtual void registerIcons(IconRegister* iconRegister); + virtual Icon* getBaseTexture(); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/ButtonTile.cpp b/Minecraft.World/Blocks/ButtonTile.cpp index 17febb8ea..fc2532ddb 100644 --- a/Minecraft.World/Blocks/ButtonTile.cpp +++ b/Minecraft.World/Blocks/ButtonTile.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.projectile.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.h" #include "ButtonTile.h" @@ -16,12 +17,12 @@ Icon* ButtonTile::getTexture(int face, int data) { if (id == Tile::button_wood_Id) return Tile::wood->getTexture(Facing::UP); else - return Tile::rock->getTexture(Facing::UP); + return Tile::stone->getTexture(Facing::UP); } AABB* ButtonTile::getAABB(Level* level, int x, int y, int z) { return NULL; } -int ButtonTile::getTickDelay() { return sensitive ? 30 : 20; } +int ButtonTile::getTickDelay(Level* level) { return sensitive ? 30 : 20; } bool ButtonTile::blocksLight() { return false; } @@ -100,8 +101,8 @@ void ButtonTile::neighborChanged(Level* level, int x, int y, int z, int type) { replace = true; if (replace) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); } } } @@ -109,7 +110,7 @@ void ButtonTile::neighborChanged(Level* level, int x, int y, int z, int type) { bool ButtonTile::checkCanSurvive(Level* level, int x, int y, int z) { if (!mayPlace(level, x, y, z)) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return false; } return true; @@ -164,12 +165,13 @@ bool ButtonTile::use(Level* level, int x, int y, int z, 0.3f, 0.6f); return false; } + int data = level->getData(x, y, z); int dir = data & 7; int open = 8 - (data & 8); if (open == 0) return true; - level->setData(x, y, z, dir + open); + level->setData(x, y, z, dir + open, Tile::UPDATE_ALL); level->setTilesDirty(x, y, z, x, y, z); level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_CLICK, 0.3f, @@ -177,7 +179,7 @@ bool ButtonTile::use(Level* level, int x, int y, int z, updateNeighbours(level, x, y, z, dir); - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); return true; } @@ -190,20 +192,22 @@ void ButtonTile::onRemove(Level* level, int x, int y, int z, int id, int data) { Tile::onRemove(level, x, y, z, id, data); } -bool ButtonTile::getSignal(LevelSource* level, int x, int y, int z, int dir) { - return (level->getData(x, y, z) & 8) > 0; +int ButtonTile::getSignal(LevelSource* level, int x, int y, int z, int dir) { + return (level->getData(x, y, z) & 8) > 0 ? Redstone::SIGNAL_MAX + : Redstone::SIGNAL_NONE; } -bool ButtonTile::getDirectSignal(Level* level, int x, int y, int z, int dir) { +int ButtonTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int dir) { int data = level->getData(x, y, z); - if ((data & 8) == 0) return false; + if ((data & 8) == 0) return Redstone::SIGNAL_NONE; int myDir = data & 7; - if (myDir == 5 && dir == 1) return true; - if (myDir == 4 && dir == 2) return true; - if (myDir == 3 && dir == 3) return true; - if (myDir == 2 && dir == 4) return true; - if (myDir == 1 && dir == 5) return true; + if (myDir == 5 && dir == 1) return Redstone::SIGNAL_MAX; + if (myDir == 4 && dir == 2) return Redstone::SIGNAL_MAX; + if (myDir == 3 && dir == 3) return Redstone::SIGNAL_MAX; + if (myDir == 2 && dir == 4) return Redstone::SIGNAL_MAX; + if (myDir == 1 && dir == 5) return Redstone::SIGNAL_MAX; return false; } @@ -219,7 +223,7 @@ void ButtonTile::tick(Level* level, int x, int y, int z, Random* random) { if (sensitive) { checkPressed(level, x, y, z); } else { - level->setData(x, y, z, data & 7); + level->setData(x, y, z, data & 7, Tile::UPDATE_ALL); int dir = data & 7; updateNeighbours(level, x, y, z, dir); @@ -265,7 +269,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) { delete entities; if (shouldBePressed && !wasPressed) { - level->setData(x, y, z, dir | 8); + level->setData(x, y, z, dir | 8, Tile::UPDATE_ALL); updateNeighbours(level, x, y, z, dir); level->setTilesDirty(x, y, z, x, y, z); @@ -273,7 +277,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) { 0.3f, 0.6f); } if (!shouldBePressed && wasPressed) { - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_ALL); updateNeighbours(level, x, y, z, dir); level->setTilesDirty(x, y, z, x, y, z); @@ -282,7 +286,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) { } if (shouldBePressed) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } } diff --git a/Minecraft.World/Blocks/ButtonTile.h b/Minecraft.World/Blocks/ButtonTile.h index 3bdffe67c..da0f6f757 100644 --- a/Minecraft.World/Blocks/ButtonTile.h +++ b/Minecraft.World/Blocks/ButtonTile.h @@ -18,7 +18,7 @@ protected: public: Icon* getTexture(int face, int data); virtual AABB* getAABB(Level* level, int x, int y, int z); - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); @@ -55,8 +55,9 @@ public: float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param virtual void onRemove(Level* level, int x, int y, int z, int id, int data); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); virtual bool isSignalSource(); virtual void tick(Level* level, int x, int y, int z, Random* random); virtual void updateDefaultShape(); diff --git a/Minecraft.World/Blocks/CactusTile.cpp b/Minecraft.World/Blocks/CactusTile.cpp index 25072b23d..34469f773 100644 --- a/Minecraft.World/Blocks/CactusTile.cpp +++ b/Minecraft.World/Blocks/CactusTile.cpp @@ -23,10 +23,11 @@ void CactusTile::tick(Level* level, int x, int y, int z, Random* random) { if (height < 3) { int age = level->getData(x, y, z); if (age == 15) { - level->setTile(x, y + 1, z, id); - level->setData(x, y, z, 0); + level->setTileAndUpdate(x, y + 1, z, id); + level->setData(x, y, z, 0, Tile::UPDATE_NONE); + neighborChanged(level, x, y + 1, z, id); } else { - level->setData(x, y, z, age + 1); + level->setData(x, y, z, age + 1, Tile::UPDATE_NONE); } } } @@ -64,8 +65,7 @@ bool CactusTile::mayPlace(Level* level, int x, int y, int z) { void CactusTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!canSurvive(level, x, y, z)) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->destroyTile(x, y, z, true); } } diff --git a/Minecraft.World/Blocks/CakeTile.cpp b/Minecraft.World/Blocks/CakeTile.cpp index faafa0118..b0d8d8ee9 100644 --- a/Minecraft.World/Blocks/CakeTile.cpp +++ b/Minecraft.World/Blocks/CakeTile.cpp @@ -93,10 +93,9 @@ void CakeTile::eat(Level* level, int x, int y, int z, int d = level->getData(x, y, z) + 1; if (d >= 6) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } else { - level->setData(x, y, z, d); - level->setTileDirty(x, y, z); + level->setData(x, y, z, d, Tile::UPDATE_CLIENTS); } } } @@ -109,8 +108,7 @@ bool CakeTile::mayPlace(Level* level, int x, int y, int z) { void CakeTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!canSurvive(level, x, y, z)) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } @@ -126,4 +124,4 @@ int CakeTile::getResource(int data, Random* random, int playerBonusLevel) { int CakeTile::cloneTileId(Level* level, int x, int y, int z) { return Item::cake_Id; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/CarrotTile.cpp b/Minecraft.World/Blocks/CarrotTile.cpp index 300e14711..c5e118d5d 100644 --- a/Minecraft.World/Blocks/CarrotTile.cpp +++ b/Minecraft.World/Blocks/CarrotTile.cpp @@ -22,6 +22,7 @@ int CarrotTile::getBasePlantId() { return Item::carrots_Id; } void CarrotTile::registerIcons(IconRegister* iconRegister) { for (int i = 0; i < 4; i++) { - icons[i] = iconRegister->registerIcon(L"carrots_" + _toString(i)); + icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + + _toString(i)); } } \ No newline at end of file diff --git a/Minecraft.World/Blocks/CauldronTile.cpp b/Minecraft.World/Blocks/CauldronTile.cpp index 6ccd67813..7c040383c 100644 --- a/Minecraft.World/Blocks/CauldronTile.cpp +++ b/Minecraft.World/Blocks/CauldronTile.cpp @@ -11,7 +11,8 @@ const std::wstring CauldronTile::TEXTURE_INSIDE = L"cauldron_inner"; const std::wstring CauldronTile::TEXTURE_BOTTOM = L"cauldron_bottom"; -CauldronTile::CauldronTile(int id) : Tile(id, Material::metal, false) { +CauldronTile::CauldronTile(int id) + : Tile(id, Material::metal, false) { iconInner = NULL; iconTop = NULL; iconBottom = NULL; @@ -82,9 +83,10 @@ bool CauldronTile::use(Level* level, int x, int y, int z, } int currentData = level->getData(x, y, z); + int fillLevel = getFillLevel(currentData); if (item->id == Item::bucket_water_Id) { - if (currentData < 3) { + if (fillLevel < 3) { if (!player->abilities.instabuild) { player->inventory->setItem( player->inventory->selected, @@ -92,11 +94,12 @@ bool CauldronTile::use(Level* level, int x, int y, int z, new ItemInstance(Item::bucket_empty))); } - level->setData(x, y, z, 3); + level->setData(x, y, z, 3, Tile::UPDATE_CLIENTS); + level->updateNeighbourForOutputSignal(x, y, z, id); } return true; } else if (item->id == Item::glassBottle_Id) { - if (currentData > 0) { + if (fillLevel > 0) { std::shared_ptr potion = std::shared_ptr( new ItemInstance(Item::potion, 1, 0)); @@ -106,7 +109,7 @@ bool CauldronTile::use(Level* level, int x, int y, int z, } // 4J Stu - Brought forward change to update inventory when filling // bottles with water - else if (std::dynamic_pointer_cast(player) != NULL) { + else if (player->instanceof(eTYPE_SERVERPLAYER)) { std::dynamic_pointer_cast(player) ->refreshContainer(player->inventoryMenu); } @@ -118,13 +121,15 @@ bool CauldronTile::use(Level* level, int x, int y, int z, nullptr); } } - level->setData(x, y, z, currentData - 1); + level->setData(x, y, z, fillLevel - 1, Tile::UPDATE_CLIENTS); + level->updateNeighbourForOutputSignal(x, y, z, id); } - } else if (currentData > 0) { + } else if (fillLevel > 0) { ArmorItem* armor = dynamic_cast(item->getItem()); if (armor && armor->getMaterial() == ArmorItem::ArmorMaterial::CLOTH) { armor->clearColor(item); - level->setData(x, y, z, currentData - 1); + level->setData(x, y, z, fillLevel - 1, Tile::UPDATE_CLIENTS); + level->updateNeighbourForOutputSignal(x, y, z, id); return true; } } @@ -138,7 +143,7 @@ void CauldronTile::handleRain(Level* level, int x, int y, int z) { int data = level->getData(x, y, z); if (data < 3) { - level->setData(x, y, z, data + 1); + level->setData(x, y, z, data + 1, Tile::UPDATE_CLIENTS); } } @@ -149,3 +154,14 @@ int CauldronTile::getResource(int data, Random* random, int playerBonusLevel) { int CauldronTile::cloneTileId(Level* level, int x, int y, int z) { return Item::cauldron_Id; } + +bool CauldronTile::hasAnalogOutputSignal() { return true; } + +int CauldronTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + int data = level->getData(x, y, z); + + return getFillLevel(data); +} + +int CauldronTile::getFillLevel(int data) { return data; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/CauldronTile.h b/Minecraft.World/Blocks/CauldronTile.h index 9609171ff..09cde15cd 100644 --- a/Minecraft.World/Blocks/CauldronTile.h +++ b/Minecraft.World/Blocks/CauldronTile.h @@ -33,4 +33,8 @@ public: virtual void handleRain(Level* level, int x, int y, int z); virtual int getResource(int data, Random* random, int playerBonusLevel); virtual int cloneTileId(Level* level, int x, int y, int z); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + static int getFillLevel(int data); }; diff --git a/Minecraft.World/Blocks/ChestTile.cpp b/Minecraft.World/Blocks/ChestTile.cpp index 00249f673..9ac3c5364 100644 --- a/Minecraft.World/Blocks/ChestTile.cpp +++ b/Minecraft.World/Blocks/ChestTile.cpp @@ -2,16 +2,19 @@ #include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.entity.item.h" +#include "../Headers/net.minecraft.world.entity.animal.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.world.level.tile.entity.h" #include "../Headers/net.minecraft.world.phys.h" #include "ChestTile.h" #include "../Util/Facing.h" -#include "../Entities/Mobs/Ocelot.h" -ChestTile::ChestTile(int id) : EntityTile(id, Material::wood, false) { +ChestTile::ChestTile(int id, int type) + : BaseEntityTile(id, Material::wood, false) { random = new Random(); + this->type = type; setShape(1 / 16.0f, 0, 1 / 16.0f, 15 / 16.0f, 14 / 16.0f, 15 / 16.0f); } @@ -41,7 +44,7 @@ void ChestTile::updateShape(LevelSource* level, int x, int y, int z, } void ChestTile::onPlace(Level* level, int x, int y, int z) { - EntityTile::onPlace(level, x, y, z); + BaseEntityTile::onPlace(level, x, y, z); recalcLockDir(level, x, y, z); int n = level->getTile(x, y, z - 1); // face = 2 @@ -55,7 +58,8 @@ void ChestTile::onPlace(Level* level, int x, int y, int z) { } void ChestTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int n = level->getTile(x, y, z - 1); // face = 2 int s = level->getTile(x, y, z + 1); // face = 3 int w = level->getTile(x - 1, y, z); // face = 4 @@ -70,25 +74,31 @@ void ChestTile::setPlacedBy(Level* level, int x, int y, int z, if (dir == 3) facing = Facing::WEST; if (n != id && s != id && w != id && e != id) { - level->setData(x, y, z, facing); + level->setData(x, y, z, facing, Tile::UPDATE_ALL); } else { if ((n == id || s == id) && (facing == Facing::WEST || facing == Facing::EAST)) { if (n == id) - level->setData(x, y, z - 1, facing); + level->setData(x, y, z - 1, facing, Tile::UPDATE_ALL); else - level->setData(x, y, z + 1, facing); - level->setData(x, y, z, facing); + level->setData(x, y, z + 1, facing, Tile::UPDATE_ALL); + level->setData(x, y, z, facing, Tile::UPDATE_ALL); } if ((w == id || e == id) && (facing == Facing::NORTH || facing == Facing::SOUTH)) { if (w == id) - level->setData(x - 1, y, z, facing); + level->setData(x - 1, y, z, facing, Tile::UPDATE_ALL); else - level->setData(x + 1, y, z, facing); - level->setData(x, y, z, facing); + level->setData(x + 1, y, z, facing, Tile::UPDATE_ALL); + level->setData(x, y, z, facing, Tile::UPDATE_ALL); } } + + if (itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->setCustomName(itemInstance->getHoverName()); + } } void ChestTile::recalcLockDir(Level* level, int x, int y, int z) { @@ -148,7 +158,7 @@ void ChestTile::recalcLockDir(Level* level, int x, int y, int z) { if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4; } - level->setData(x, y, z, lockDir); + level->setData(x, y, z, lockDir, Tile::UPDATE_ALL); } bool ChestTile::mayPlace(Level* level, int x, int y, int z) { @@ -178,7 +188,7 @@ bool ChestTile::isFullChest(Level* level, int x, int y, int z) { } void ChestTile::neighborChanged(Level* level, int x, int y, int z, int type) { - EntityTile::neighborChanged(level, x, y, z, type); + BaseEntityTile::neighborChanged(level, x, y, z, type); std::shared_ptr(cte) = std::dynamic_pointer_cast( level->getTileEntity(x, y, z)); @@ -225,8 +235,9 @@ void ChestTile::onRemove(Level* level, int x, int y, int z, int id, int data) { container->setItem(i, nullptr); } } + level->updateNeighbourForOutputSignal(x, y, z, id); } - EntityTile::onRemove(level, x, y, z, id, data); + BaseEntityTile::onRemove(level, x, y, z, id, data); } // 4J-PB - Adding a TestUse for tooltip display @@ -243,31 +254,41 @@ bool ChestTile::use(Level* level, int x, int y, int z, if (level->isClientSide) { return true; } + std::shared_ptr container = getContainer(level, x, y, z); + if (container != NULL) { + player->openContainer(container); + } + + return true; +} + +std::shared_ptr ChestTile::getContainer(Level* level, int x, int y, + int z) { std::shared_ptr container = std::dynamic_pointer_cast( level->getTileEntity(x, y, z)); - if (container == NULL) return true; + if (container == NULL) return nullptr; - if (level->isSolidBlockingTile(x, y + 1, z)) return true; - if (isCatSittingOnChest(level, x, y, z)) return true; + if (level->isSolidBlockingTile(x, y + 1, z)) return nullptr; + if (isCatSittingOnChest(level, x, y, z)) return nullptr; if (level->getTile(x - 1, y, z) == id && (level->isSolidBlockingTile(x - 1, y + 1, z) || isCatSittingOnChest(level, x - 1, y, z))) - return true; + return nullptr; if (level->getTile(x + 1, y, z) == id && (level->isSolidBlockingTile(x + 1, y + 1, z) || isCatSittingOnChest(level, x + 1, y, z))) - return true; + return nullptr; if (level->getTile(x, y, z - 1) == id && (level->isSolidBlockingTile(x, y + 1, z - 1) || isCatSittingOnChest(level, x, y, z - 1))) - return true; + return nullptr; if (level->getTile(x, y, z + 1) == id && (level->isSolidBlockingTile(x, y + 1, z + 1) || isCatSittingOnChest(level, x, y, z + 1))) - return true; + return nullptr; if (level->getTile(x - 1, y, z) == id) container = std::shared_ptr( @@ -292,23 +313,7 @@ bool ChestTile::use(Level* level, int x, int y, int z, std::dynamic_pointer_cast( level->getTileEntity(x, y, z + 1)))); - player->openContainer(container); - - return true; -} - -// 4J-PB - added from 1.5 -bool ChestTile::isCatSittingOnChest(Level* level, int x, int y, int z) { - std::vector >* entities = level->getEntitiesOfClass( - typeid(Ozelot), AABB::newTemp(x, y + 1, z, x + 1, y + 2, z + 1)); - for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { - std::shared_ptr ocelot = std::dynamic_pointer_cast(*it); - if (ocelot->isSitting()) { - return true; - } - } - - return false; + return container; } std::shared_ptr ChestTile::newTileEntity(Level* level) { @@ -319,8 +324,50 @@ std::shared_ptr ChestTile::newTileEntity(Level* level) { return retval; } +bool ChestTile::isSignalSource() { return type == TYPE_TRAP; } + +int ChestTile::getSignal(LevelSource* level, int x, int y, int z, int dir) { + if (!isSignalSource()) return Redstone::SIGNAL_NONE; + + int openCount = std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->openCount; + return Mth::clamp(openCount, Redstone::SIGNAL_NONE, Redstone::SIGNAL_MAX); +} + +int ChestTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int dir) { + if (dir == Facing::UP) { + return getSignal(level, x, y, z, dir); + } else { + return Redstone::SIGNAL_NONE; + } +} + +bool ChestTile::isCatSittingOnChest(Level* level, int x, int y, int z) { + std::vector >* entities = level->getEntitiesOfClass( + typeid(Ocelot), AABB::newTemp(x, y + 1, z, x + 1, y + 2, z + 1)); + for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { + std::shared_ptr ocelot = std::dynamic_pointer_cast(*it); + if (ocelot->isSitting()) { + delete entities; + return true; + } + } + delete entities; + return false; +} + +bool ChestTile::hasAnalogOutputSignal() { return true; } + +int ChestTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + return AbstractContainerMenu::getRedstoneSignalFromContainer( + getContainer(level, x, y, z)); +} + void ChestTile::registerIcons(IconRegister* iconRegister) { // Register wood as the chest's icon, because it's used by the particles // when destroying the chest - icon = iconRegister->registerIcon(L"wood"); + icon = iconRegister->registerIcon(L"planks_oak"); } diff --git a/Minecraft.World/Blocks/ChestTile.h b/Minecraft.World/Blocks/ChestTile.h index e42d21508..ace667ca9 100644 --- a/Minecraft.World/Blocks/ChestTile.h +++ b/Minecraft.World/Blocks/ChestTile.h @@ -1,21 +1,28 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" #include "Material.h" class Player; class Random; -class ChestTile : public EntityTile { +class ChestTile : public BaseEntityTile { friend class Tile; + friend class Minecraft; public: + static const int TYPE_BASIC = 0; + static const int TYPE_TRAP = 1; + static const int EVENT_SET_OPEN_COUNT = 1; private: Random* random; +public: + int type; + protected: - ChestTile(int id); + ChestTile(int id, int type); ~ChestTile(); public: @@ -28,13 +35,13 @@ public: std::shared_ptr()); virtual void onPlace(Level* level, int x, int y, int z); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); void recalcLockDir(Level* level, int x, int y, int z); virtual bool mayPlace(Level* level, int x, int y, int z); private: bool isFullChest(Level* level, int x, int y, int z); - bool isCatSittingOnChest(Level* level, int x, int y, int z); public: virtual void neighborChanged(Level* level, int x, int y, int z, int type); @@ -44,7 +51,20 @@ public: std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param - std::shared_ptr newTileEntity(Level* level); - //@Override - void registerIcons(IconRegister* iconRegister); + virtual std::shared_ptr getContainer(Level* level, int x, int y, + int z); + virtual std::shared_ptr newTileEntity(Level* level); + virtual bool isSignalSource(); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); + +private: + bool isCatSittingOnChest(Level* level, int x, int y, int z); + +public: + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + virtual void registerIcons(IconRegister* iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/ClothTile.cpp b/Minecraft.World/Blocks/ClothTile.cpp deleted file mode 100644 index 66c441858..000000000 --- a/Minecraft.World/Blocks/ClothTile.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "../Platform/stdafx.h" -#include "../Headers/net.minecraft.world.h" -#include "ClothTile.h" - -ClothTile::ClothTile() : Tile(35, Material::cloth) { icons = NULL; } - -Icon* ClothTile::getTexture(int face, int data) { return icons[data]; } - -int ClothTile::getSpawnResourcesAuxValue(int data) { return data; } - -int ClothTile::getTileDataForItemAuxValue(int auxValue) { - return (~auxValue & 0xf); -} - -int ClothTile::getItemAuxValueForTileData(int data) { return (~data & 0xf); } - -void ClothTile::registerIcons(IconRegister* iconRegister) { - icons = new Icon*[16]; - - for (int i = 0; i < 16; i++) { - icons[i] = iconRegister->registerIcon(L"cloth_" + _toString(i)); - } -} \ No newline at end of file diff --git a/Minecraft.World/Blocks/CocoaTile.cpp b/Minecraft.World/Blocks/CocoaTile.cpp index d58c70d17..c0a066699 100644 --- a/Minecraft.World/Blocks/CocoaTile.cpp +++ b/Minecraft.World/Blocks/CocoaTile.cpp @@ -9,7 +9,8 @@ const std::wstring CocoaTile::TEXTURE_AGES[] = {L"cocoa_0", L"cocoa_1", L"cocoa_2"}; -CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, false) { +CocoaTile::CocoaTile(int id) + : DirectionalTile(id, Material::plant, false) { setTicking(true); } @@ -25,13 +26,14 @@ Icon* CocoaTile::getTextureForAge(int age) { void CocoaTile::tick(Level* level, int x, int y, int z, Random* random) { if (!canSurvive(level, x, y, z)) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->setTileAndData(x, y, z, 0, 0, UPDATE_CLIENTS); } else if (level->random->nextInt(5) == 0) { int data = level->getData(x, y, z); int age = getAge(data); if (age < 2) { age++; - level->setData(x, y, z, (age << 2) | (getDirection(data))); + level->setData(x, y, z, (age << 2) | (getDirection(data)), + Tile::UPDATE_CLIENTS); } } } @@ -101,10 +103,10 @@ void CocoaTile::updateShape(LevelSource* level, int x, int y, int z, } void CocoaTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by, + std::shared_ptr by, std::shared_ptr itemInstance) { int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3) + 0) % 4; - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); } int CocoaTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, @@ -119,7 +121,7 @@ int CocoaTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, void CocoaTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!canSurvive(level, x, y, z)) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->setTileAndData(x, y, z, 0, 0, UPDATE_CLIENTS); } } @@ -155,4 +157,4 @@ void CocoaTile::registerIcons(IconRegister* iconRegister) { for (int i = 0; i < COCOA_TEXTURES_LENGTH; i++) { icons[i] = iconRegister->registerIcon(TEXTURE_AGES[i]); } -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/CocoaTile.h b/Minecraft.World/Blocks/CocoaTile.h index 088b511b2..9726e232b 100644 --- a/Minecraft.World/Blocks/CocoaTile.h +++ b/Minecraft.World/Blocks/CocoaTile.h @@ -29,7 +29,7 @@ public: std::shared_ptr forceEntity = std::shared_ptr()); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by, + std::shared_ptr by, std::shared_ptr itemInstance); virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, diff --git a/Minecraft.World/Blocks/ColoredTile.cpp b/Minecraft.World/Blocks/ColoredTile.cpp new file mode 100644 index 000000000..3f2be2ebd --- /dev/null +++ b/Minecraft.World/Blocks/ColoredTile.cpp @@ -0,0 +1,26 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.world.item.h" +#include "ColoredTile.h" + +ColoredTile::ColoredTile(int id, Material* material) : Tile(id, material) {} + +Icon* ColoredTile::getTexture(int face, int data) { + return icons[data % ICON_COUNT]; +} + +int ColoredTile::getSpawnResourcesAuxValue(int data) { return data; } + +int ColoredTile::getTileDataForItemAuxValue(int auxValue) { + return (~auxValue & 0xf); +} + +int ColoredTile::getItemAuxValueForTileData(int data) { return (~data & 0xf); } + +void ColoredTile::registerIcons(IconRegister* iconRegister) { + for (int i = 0; i < ICON_COUNT; i++) { + icons[i] = iconRegister->registerIcon( + getIconName() + L"_" + + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForTileData(i)]); + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/ClothTile.h b/Minecraft.World/Blocks/ColoredTile.h similarity index 50% rename from Minecraft.World/Blocks/ClothTile.h rename to Minecraft.World/Blocks/ColoredTile.h index e8fd0b5b7..3f7e14dce 100644 --- a/Minecraft.World/Blocks/ClothTile.h +++ b/Minecraft.World/Blocks/ColoredTile.h @@ -1,25 +1,20 @@ #pragma once + #include "Tile.h" -#include "Material.h" -class ChunkRebuildData; - -class ClothTile : public Tile { +class ColoredTile : public Tile { friend class ChunkRebuildData; private: - Icon** icons; + static const int ICON_COUNT = 16; + Icon* icons[ICON_COUNT]; public: - ClothTile(); - virtual Icon* getTexture(int face, int data); + ColoredTile(int id, Material* material); -protected: + Icon* getTexture(int face, int data); virtual int getSpawnResourcesAuxValue(int data); - -public: static int getTileDataForItemAuxValue(int auxValue); static int getItemAuxValueForTileData(int data); - //@Override - void registerIcons(IconRegister* iconRegister); + virtual void registerIcons(IconRegister* iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/CommandBlock.cpp b/Minecraft.World/Blocks/CommandBlock.cpp new file mode 100644 index 000000000..ce5c1e63c --- /dev/null +++ b/Minecraft.World/Blocks/CommandBlock.cpp @@ -0,0 +1,86 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "CommandBlock.h" + +CommandBlock::CommandBlock(int id) + : BaseEntityTile(id, Material::metal, false) {} + +std::shared_ptr CommandBlock::newTileEntity(Level* level) { + return std::shared_ptr(new CommandBlockEntity()); +} + +void CommandBlock::neighborChanged(Level* level, int x, int y, int z, + int type) { + if (!level->isClientSide) { + bool signal = level->hasNeighborSignal(x, y, z); + int data = level->getData(x, y, z); + bool isTriggered = (data & TRIGGER_BIT) != 0; + + if (signal && !isTriggered) { + level->setData(x, y, z, data | TRIGGER_BIT, Tile::UPDATE_NONE); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); + } else if (!signal && isTriggered) { + level->setData(x, y, z, data & ~TRIGGER_BIT, Tile::UPDATE_NONE); + } + } +} + +void CommandBlock::tick(Level* level, int x, int y, int z, Random* random) { + std::shared_ptr tileEntity = level->getTileEntity(x, y, z); + + if (tileEntity != NULL && + std::dynamic_pointer_cast(tileEntity) != NULL) { + std::shared_ptr commandBlock = + std::dynamic_pointer_cast(tileEntity); + commandBlock->setSuccessCount(commandBlock->performCommand(level)); + level->updateNeighbourForOutputSignal(x, y, z, id); + } +} + +int CommandBlock::getTickDelay(Level* level) { return 1; } + +bool CommandBlock::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly) { + std::shared_ptr amce = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + + if (amce != NULL) { + player->openTextEdit(amce); + } + + return true; +} + +bool CommandBlock::hasAnalogOutputSignal() { return true; } + +int CommandBlock::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + std::shared_ptr tileEntity = level->getTileEntity(x, y, z); + + if (tileEntity != NULL && + std::dynamic_pointer_cast(tileEntity) != NULL) { + return std::dynamic_pointer_cast(tileEntity) + ->getSuccessCount(); + } + + return Redstone::SIGNAL_NONE; +} + +void CommandBlock::setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance) { + std::shared_ptr cblock = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + + if (itemInstance->hasCustomHoverName()) { + cblock->setName(itemInstance->getHoverName()); + } +} + +int CommandBlock::getResourceCount(Random* random) { return 0; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/CommandBlock.h b/Minecraft.World/Blocks/CommandBlock.h new file mode 100644 index 000000000..9ef8e4fff --- /dev/null +++ b/Minecraft.World/Blocks/CommandBlock.h @@ -0,0 +1,27 @@ +#pragma once + +#include "BaseEntityTile.h" + +class CommandBlock : public BaseEntityTile { +private: + static const int TRIGGER_BIT = 1; + +public: + CommandBlock(int id); + + virtual std::shared_ptr newTileEntity(Level* level); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual int getTickDelay(Level* level); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + virtual void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); + virtual int getResourceCount(Random* random); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/ComparatorTile.cpp b/Minecraft.World/Blocks/ComparatorTile.cpp new file mode 100644 index 000000000..e4e5d4b75 --- /dev/null +++ b/Minecraft.World/Blocks/ComparatorTile.cpp @@ -0,0 +1,215 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "../Headers/net.minecraft.h" +#include "ComparatorTile.h" + +ComparatorTile::ComparatorTile(int id, bool on) : DiodeTile(id, on) { + _isEntityTile = true; +} + +int ComparatorTile::getResource(int data, Random* random, + int playerBonusLevel) { + return Item::comparator_Id; +} + +int ComparatorTile::cloneTileId(Level* level, int x, int y, int z) { + return Item::comparator_Id; +} + +int ComparatorTile::getTurnOnDelay(int data) { return 2; } + +DiodeTile* ComparatorTile::getOnTile() { return Tile::comparator_on; } + +DiodeTile* ComparatorTile::getOffTile() { return Tile::comparator_off; } + +int ComparatorTile::getRenderShape() { return SHAPE_COMPARATOR; } + +Icon* ComparatorTile::getTexture(int face, int data) { + bool isOn = on || (data & BIT_IS_LIT) != 0; + // down is used by the torch tesselator + if (face == Facing::DOWN) { + if (isOn) { + return Tile::redstoneTorch_on->getTexture(face); + } + return Tile::redstoneTorch_off->getTexture(face); + } + if (face == Facing::UP) { + if (isOn) { + return Tile::comparator_on->icon; + } + return icon; + } + // edge of stone half-step + return Tile::stoneSlab->getTexture(Facing::UP); +} + +bool ComparatorTile::isOn(int data) { return on || (data & BIT_IS_LIT) != 0; } + +int ComparatorTile::getOutputSignal(LevelSource* levelSource, int x, int y, + int z, int data) { + return getComparator(levelSource, x, y, z)->getOutputSignal(); +} + +int ComparatorTile::calculateOutputSignal(Level* level, int x, int y, int z, + int data) { + if (!isReversedOutputSignal(data)) { + return getInputSignal(level, x, y, z, data); + } else { + return std::max(getInputSignal(level, x, y, z, data) - + getAlternateSignal(level, x, y, z, data), + Redstone::SIGNAL_NONE); + } +} + +bool ComparatorTile::isReversedOutputSignal(int data) { + return (data & BIT_OUTPUT_SUBTRACT) == BIT_OUTPUT_SUBTRACT; +} + +bool ComparatorTile::shouldTurnOn(Level* level, int x, int y, int z, int data) { + int input = getInputSignal(level, x, y, z, data); + if (input >= Redstone::SIGNAL_MAX) return true; + if (input == Redstone::SIGNAL_NONE) return false; + + int alt = getAlternateSignal(level, x, y, z, data); + if (alt == Redstone::SIGNAL_NONE) return true; + + return input >= alt; +} + +int ComparatorTile::getInputSignal(Level* level, int x, int y, int z, + int data) { + int result = DiodeTile::getInputSignal(level, x, y, z, data); + + int dir = getDirection(data); + int xx = x + Direction::STEP_X[dir]; + int zz = z + Direction::STEP_Z[dir]; + int tile = level->getTile(xx, y, zz); + + if (tile > 0) { + if (Tile::tiles[tile]->hasAnalogOutputSignal()) { + result = Tile::tiles[tile]->getAnalogOutputSignal( + level, xx, y, zz, Direction::DIRECTION_OPPOSITE[dir]); + } else if (result < Redstone::SIGNAL_MAX && + Tile::isSolidBlockingTile(tile)) { + xx += Direction::STEP_X[dir]; + zz += Direction::STEP_Z[dir]; + tile = level->getTile(xx, y, zz); + + if (tile > 0 && Tile::tiles[tile]->hasAnalogOutputSignal()) { + result = Tile::tiles[tile]->getAnalogOutputSignal( + level, xx, y, zz, Direction::DIRECTION_OPPOSITE[dir]); + } + } + } + + return result; +} + +std::shared_ptr ComparatorTile::getComparator( + LevelSource* level, int x, int y, int z) { + return std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); +} + +bool ComparatorTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly) { + int data = level->getData(x, y, z); + bool isOn = on || ((data & BIT_IS_LIT) != 0); + bool subtract = !isReversedOutputSignal(data); + int outputBit = subtract ? BIT_OUTPUT_SUBTRACT : 0; + outputBit |= isOn ? BIT_IS_LIT : 0; + + level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_CLICK, 0.3f, + subtract ? 0.55f : 0.5f); + + if (!soundOnly) { + level->setData(x, y, z, outputBit | (data & DIRECTION_MASK), + Tile::UPDATE_CLIENTS); + refreshOutputState(level, x, y, z, level->random); + } + + return true; +} + +void ComparatorTile::checkTickOnNeighbor(Level* level, int x, int y, int z, + int type) { + if (!level->isTileToBeTickedAt(x, y, z, id)) { + int data = level->getData(x, y, z); + int outputValue = calculateOutputSignal(level, x, y, z, data); + int oldValue = getComparator(level, x, y, z)->getOutputSignal(); + + if (outputValue != oldValue || + (isOn(data) != shouldTurnOn(level, x, y, z, data))) { + // prioritize locking comparators + if (shouldPrioritize(level, x, y, z, data)) { + level->addToTickNextTick(x, y, z, id, getTurnOnDelay(0), -1); + } else { + level->addToTickNextTick(x, y, z, id, getTurnOnDelay(0), 0); + } + } + } +} + +void ComparatorTile::refreshOutputState(Level* level, int x, int y, int z, + Random* random) { + int data = level->getData(x, y, z); + int outputValue = calculateOutputSignal(level, x, y, z, data); + int oldValue = getComparator(level, x, y, z)->getOutputSignal(); + getComparator(level, x, y, z)->setOutputSignal(outputValue); + + if (oldValue != outputValue || !isReversedOutputSignal(data)) { + bool sourceOn = shouldTurnOn(level, x, y, z, data); + bool isOn = on || (data & BIT_IS_LIT) != 0; + if (isOn && !sourceOn) { + level->setData(x, y, z, data & ~BIT_IS_LIT, Tile::UPDATE_CLIENTS); + } else if (!isOn && sourceOn) { + level->setData(x, y, z, data | BIT_IS_LIT, Tile::UPDATE_CLIENTS); + } + updateNeighborsInFront(level, x, y, z); + } +} + +void ComparatorTile::tick(Level* level, int x, int y, int z, Random* random) { + if (on) { + // clean-up old tiles with the 'on' id + int data = level->getData(x, y, z); + level->setTileAndData(x, y, z, getOffTile()->id, data | BIT_IS_LIT, + Tile::UPDATE_NONE); + } + refreshOutputState(level, x, y, z, random); +} + +void ComparatorTile::onPlace(Level* level, int x, int y, int z) { + DiodeTile::onPlace(level, x, y, z); + level->setTileEntity(x, y, z, newTileEntity(level)); +} + +void ComparatorTile::onRemove(Level* level, int x, int y, int z, int id, + int data) { + DiodeTile::onRemove(level, x, y, z, id, data); + level->removeTileEntity(x, y, z); + + updateNeighborsInFront(level, x, y, z); +} + +bool ComparatorTile::triggerEvent(Level* level, int x, int y, int z, int b0, + int b1) { + DiodeTile::triggerEvent(level, x, y, z, b0, b1); + std::shared_ptr te = level->getTileEntity(x, y, z); + if (te != NULL) { + return te->triggerEvent(b0, b1); + } + return false; +} + +std::shared_ptr ComparatorTile::newTileEntity(Level* level) { + return std::shared_ptr(new ComparatorTileEntity()); +} + +bool ComparatorTile::TestUse() { return true; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/ComparatorTile.h b/Minecraft.World/Blocks/ComparatorTile.h new file mode 100644 index 000000000..55d0712bf --- /dev/null +++ b/Minecraft.World/Blocks/ComparatorTile.h @@ -0,0 +1,68 @@ +#pragma once + +#include "DiodeTile.h" +#include "TileEntities/EntityTile.h" + +class ComparatorTileEntity; + +class ComparatorTile : public DiodeTile, public EntityTile { +private: + static const int BIT_OUTPUT_SUBTRACT = 0x4; + static const int BIT_IS_LIT = 0x8; + +public: + ComparatorTile(int id, bool on); + + virtual int getResource(int data, Random* random, int playerBonusLevel); + virtual int cloneTileId(Level* level, int x, int y, int z); + +protected: + virtual int getTurnOnDelay(int data); + virtual DiodeTile* getOnTile(); + virtual DiodeTile* getOffTile(); + +public: + virtual int getRenderShape(); + virtual Icon* getTexture(int face, int data); + +protected: + virtual bool isOn(int data); + virtual int getOutputSignal(LevelSource* levelSource, int x, int y, int z, + int data); + +private: + virtual int calculateOutputSignal(Level* level, int x, int y, int z, + int data); + +public: + virtual bool isReversedOutputSignal(int data); + +protected: + virtual bool shouldTurnOn(Level* level, int x, int y, int z, int data); + virtual int getInputSignal(Level* level, int x, int y, int z, int data); + virtual std::shared_ptr getComparator( + LevelSource* level, int x, int y, int z); + +public: + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); + +protected: + virtual void checkTickOnNeighbor(Level* level, int x, int y, int z, + int type); + +private: + virtual void refreshOutputState(Level* level, int x, int y, int z, + Random* random); + +public: + virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual void onPlace(Level* level, int x, int y, int z); + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + virtual bool triggerEvent(Level* level, int x, int y, int z, int b0, + int b1); + virtual std::shared_ptr newTileEntity(Level* level); + virtual bool TestUse(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/CropTile.cpp b/Minecraft.World/Blocks/CropTile.cpp index 75959a31a..474a54f25 100644 --- a/Minecraft.World/Blocks/CropTile.cpp +++ b/Minecraft.World/Blocks/CropTile.cpp @@ -33,14 +33,16 @@ void CropTile::tick(Level* level, int x, int y, int z, Random* random) { if (random->nextInt((int)(25 / growthSpeed) + 1) == 0) { age++; - level->setData(x, y, z, age); + level->setData(x, y, z, age, Tile::UPDATE_CLIENTS); } } } } -void CropTile::growCropsToMax(Level* level, int x, int y, int z) { - level->setData(x, y, z, 7); +void CropTile::growCrops(Level* level, int x, int y, int z) { + int stage = level->getData(x, y, z) + Mth::nextInt(level->random, 2, 5); + if (stage > 7) stage = 7; + level->setData(x, y, z, stage, Tile::UPDATE_CLIENTS); } float CropTile::getGrowthSpeed(Level* level, int x, int y, int z) { @@ -56,10 +58,9 @@ float CropTile::getGrowthSpeed(Level* level, int x, int y, int z) { int d2 = level->getTile(x + 1, y, z + 1); int d3 = level->getTile(x - 1, y, z + 1); - bool horizontal = w == this->id || e == this->id; - bool vertical = n == this->id || s == this->id; - bool diagonal = - d0 == this->id || d1 == this->id || d2 == this->id || d3 == this->id; + bool horizontal = w == id || e == id; + bool vertical = n == id || s == id; + bool diagonal = d0 == id || d1 == id || d2 == id || d3 == id; for (int xx = x - 1; xx <= x + 1; xx++) for (int zz = z - 1; zz <= z + 1; zz++) { diff --git a/Minecraft.World/Blocks/CropTile.h b/Minecraft.World/Blocks/CropTile.h index 383a95632..02e9fe38f 100644 --- a/Minecraft.World/Blocks/CropTile.h +++ b/Minecraft.World/Blocks/CropTile.h @@ -21,7 +21,7 @@ public: // 4J Added override virtual void updateDefaultShape(); virtual void tick(Level* level, int x, int y, int z, Random* random); - void growCropsToMax(Level* level, int x, int y, int z); + virtual void growCrops(Level* level, int x, int y, int z); private: float getGrowthSpeed(Level* level, int x, int y, int z); diff --git a/Minecraft.World/Blocks/DaylightDetectorTile.cpp b/Minecraft.World/Blocks/DaylightDetectorTile.cpp new file mode 100644 index 000000000..f001325b8 --- /dev/null +++ b/Minecraft.World/Blocks/DaylightDetectorTile.cpp @@ -0,0 +1,96 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.level.dimension.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "../Headers/net.minecraft.world.h" +#include "../Util/JavaMath.h" +#include "DaylightDetectorTile.h" + +DaylightDetectorTile::DaylightDetectorTile(int id) + : BaseEntityTile(id, Material::wood, false) { + updateDefaultShape(); +} + +void DaylightDetectorTile::updateDefaultShape() { + setShape(0, 0, 0, 1, 6.0f / 16.0f, 1); +} + +void DaylightDetectorTile::updateShape( + LevelSource* level, int x, int y, int z, int forceData, + std::shared_ptr forceEntity) { + setShape(0, 0, 0, 1, 6.0f / 16.0f, 1); +} + +int DaylightDetectorTile::getSignal(LevelSource* level, int x, int y, int z, + int dir) { + return level->getData(x, y, z); +} + +void DaylightDetectorTile::tick(Level* level, int x, int y, int z, + Random* random) { + // updateSignalStrength(level, x, y, z); +} + +void DaylightDetectorTile::neighborChanged(Level* level, int x, int y, int z, + int type) { + // level.addToTickNextTick(x, y, z, id, getTickDelay()); +} + +void DaylightDetectorTile::onPlace(Level* level, int x, int y, int z) { + // level.addToTickNextTick(x, y, z, id, getTickDelay()); +} + +void DaylightDetectorTile::updateSignalStrength(Level* level, int x, int y, + int z) { + if (level->dimension->hasCeiling) return; + + int current = level->getData(x, y, z); + int target = + level->getBrightness(LightLayer::Sky, x, y, z) - level->skyDarken; + float sunAngle = level->getSunAngle(1); + + // tilt sunAngle towards zenith (to make the transition to night + // smoother) + if (sunAngle < PI) { + sunAngle = sunAngle + (0 - sunAngle) * .2f; + } else { + sunAngle = sunAngle + (PI * 2.0f - sunAngle) * .2f; + } + + target = Math::round((float)target * Mth::cos(sunAngle)); + if (target < 0) { + target = 0; + } + if (target > Redstone::SIGNAL_MAX) { + target = Redstone::SIGNAL_MAX; + } + + if (current != target) { + level->setData(x, y, z, target, UPDATE_ALL); + } +} + +bool DaylightDetectorTile::isCubeShaped() { return false; } + +bool DaylightDetectorTile::isSolidRender(bool isServerLevel) { return false; } + +bool DaylightDetectorTile::isSignalSource() { return true; } + +std::shared_ptr DaylightDetectorTile::newTileEntity(Level* level) { + return std::shared_ptr( + new DaylightDetectorTileEntity()); +} + +Icon* DaylightDetectorTile::getTexture(int face, int data) { + if (face == Facing::UP) { + return icons[0]; + } + return icons[1]; +} + +void DaylightDetectorTile::registerIcons(IconRegister* iconRegister) { + icons[0] = iconRegister->registerIcon(getIconName() + L"_top"); + icons[1] = iconRegister->registerIcon(getIconName() + L"_side"); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/DaylightDetectorTile.h b/Minecraft.World/Blocks/DaylightDetectorTile.h new file mode 100644 index 000000000..a602abd36 --- /dev/null +++ b/Minecraft.World/Blocks/DaylightDetectorTile.h @@ -0,0 +1,30 @@ +#pragma once + +#include "BaseEntityTile.h" + +class DaylightDetectorTile : public BaseEntityTile { + friend class ChunkRebuildData; + +private: + Icon* icons[2]; + +public: + DaylightDetectorTile(int id); + + virtual void updateDefaultShape(); // 4J Added override + virtual void updateShape(LevelSource* level, int x, int y, int z, + int forceData = -1, + std::shared_ptr forceEntity = + std::shared_ptr()); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + virtual void onPlace(Level* level, int x, int y, int z); + virtual void updateSignalStrength(Level* level, int x, int y, int z); + virtual bool isCubeShaped(); + virtual bool isSolidRender(bool isServerLevel = false); + virtual bool isSignalSource(); + virtual std::shared_ptr newTileEntity(Level* level); + virtual Icon* getTexture(int face, int data); + virtual void registerIcons(IconRegister* iconRegister); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/DetectorRailTile.cpp b/Minecraft.World/Blocks/DetectorRailTile.cpp index e903e3897..dacc5f51b 100644 --- a/Minecraft.World/Blocks/DetectorRailTile.cpp +++ b/Minecraft.World/Blocks/DetectorRailTile.cpp @@ -1,5 +1,7 @@ #include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.inventory.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.phys.h" @@ -7,12 +9,12 @@ #include "DetectorRailTile.h" #include "../Headers/net.minecraft.h" -DetectorRailTile::DetectorRailTile(int id) : RailTile(id, true) { +DetectorRailTile::DetectorRailTile(int id) : BaseRailTile(id, true) { setTicking(true); icons = NULL; } -int DetectorRailTile::getTickDelay() { return 20; } +int DetectorRailTile::getTickDelay(Level* level) { return 20; } bool DetectorRailTile::isSignalSource() { return true; } @@ -41,15 +43,19 @@ void DetectorRailTile::tick(Level* level, int x, int y, int z, Random* random) { checkPressed(level, x, y, z, data); } -bool DetectorRailTile::getSignal(LevelSource* level, int x, int y, int z, - int dir) { - return (level->getData(x, y, z) & RAIL_DATA_BIT) != 0; +int DetectorRailTile::getSignal(LevelSource* level, int x, int y, int z, + int dir) { + return (level->getData(x, y, z) & RAIL_DATA_BIT) != 0 + ? Redstone::SIGNAL_MAX + : Redstone::SIGNAL_NONE; } -bool DetectorRailTile::getDirectSignal(Level* level, int x, int y, int z, - int facing) { - if ((level->getData(x, y, z) & RAIL_DATA_BIT) == 0) return false; - return (facing == Facing::UP); +int DetectorRailTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int facing) { + if ((level->getData(x, y, z) & RAIL_DATA_BIT) == 0) + return Redstone::SIGNAL_NONE; + return (facing == Facing::UP) ? Redstone::SIGNAL_MAX + : Redstone::SIGNAL_NONE; } void DetectorRailTile::checkPressed(Level* level, int x, int y, int z, @@ -66,25 +72,56 @@ void DetectorRailTile::checkPressed(Level* level, int x, int y, int z, } if (shouldBePressed && !wasPressed) { - level->setData(x, y, z, currentData | RAIL_DATA_BIT); + level->setData(x, y, z, currentData | RAIL_DATA_BIT, Tile::UPDATE_ALL); level->updateNeighborsAt(x, y, z, id); level->updateNeighborsAt(x, y - 1, z, id); level->setTilesDirty(x, y, z, x, y, z); } if (!shouldBePressed && wasPressed) { - level->setData(x, y, z, currentData & RAIL_DIRECTION_MASK); + level->setData(x, y, z, currentData & RAIL_DIRECTION_MASK, + Tile::UPDATE_ALL); level->updateNeighborsAt(x, y, z, id); level->updateNeighborsAt(x, y - 1, z, id); level->setTilesDirty(x, y, z, x, y, z); } if (shouldBePressed) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } + level->updateNeighbourForOutputSignal(x, y, z, id); + delete entities; } +void DetectorRailTile::onPlace(Level* level, int x, int y, int z) { + BaseRailTile::onPlace(level, x, y, z); + checkPressed(level, x, y, z, level->getData(x, y, z)); +} + +bool DetectorRailTile::hasAnalogOutputSignal() { return true; } + +int DetectorRailTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + if ((level->getData(x, y, z) & RAIL_DATA_BIT) > 0) { + float b = 2 / 16.0f; + std::vector >* entities = + level->getEntitiesOfClass( + typeid(Minecart), + AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 1 - b, z + 1 - b), + EntitySelector::CONTAINER_ENTITY_SELECTOR); + + if (entities->size() > 0) { + std::shared_ptr out = entities->at(0); + delete entities; + return AbstractContainerMenu::getRedstoneSignalFromContainer( + std::dynamic_pointer_cast(out)); + } + } + + return Redstone::SIGNAL_NONE; +} + void DetectorRailTile::registerIcons(IconRegister* iconRegister) { icons = new Icon*[2]; icons[0] = iconRegister->registerIcon(L"detectorRail"); diff --git a/Minecraft.World/Blocks/DetectorRailTile.h b/Minecraft.World/Blocks/DetectorRailTile.h index 3689adb02..11836b29d 100644 --- a/Minecraft.World/Blocks/DetectorRailTile.h +++ b/Minecraft.World/Blocks/DetectorRailTile.h @@ -1,12 +1,12 @@ #pragma once -#include "RailTile.h" +#include "BaseRailTile.h" class Entity; class Random; class Level; class ChunkRebuildData; -class DetectorRailTile : public RailTile { +class DetectorRailTile : public BaseRailTile { friend class ChunkRebuildData; private: @@ -14,13 +14,18 @@ private: public: DetectorRailTile(int id); - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual bool isSignalSource(); virtual void entityInside(Level* level, int x, int y, int z, std::shared_ptr entity); virtual void tick(Level* level, int x, int y, int z, Random* random); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int facing); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int facing); + virtual void onPlace(Level* level, int x, int y, int z); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); private: virtual void checkPressed(Level* level, int x, int y, int z, diff --git a/Minecraft.World/Blocks/DiodeTile.cpp b/Minecraft.World/Blocks/DiodeTile.cpp index 89e4a6018..f5d324ab5 100644 --- a/Minecraft.World/Blocks/DiodeTile.cpp +++ b/Minecraft.World/Blocks/DiodeTile.cpp @@ -1,15 +1,13 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.h" #include "DiodeTile.h" -const double DiodeTile::DELAY_RENDER_OFFSETS[4] = {-1.0f / 16.0f, 1.0f / 16.0f, - 3.0f / 16.0f, 5.0f / 16.0f}; -const int DiodeTile::DELAYS[4] = {1, 2, 3, 4}; - DiodeTile::DiodeTile(int id, bool on) : DirectionalTile(id, Material::decoration, false) { this->on = on; @@ -37,17 +35,20 @@ bool DiodeTile::canSurvive(Level* level, int x, int y, int z) { void DiodeTile::tick(Level* level, int x, int y, int z, Random* random) { int data = level->getData(x, y, z); - bool sourceOn = getSourceSignal(level, x, y, z, data); - if (on && !sourceOn) { - level->setTileAndData(x, y, z, Tile::diode_off_Id, data); - } else if (!on) { - // when off-diodes are ticked, they always turn on for one tick and - // then off again if necessary - level->setTileAndData(x, y, z, Tile::diode_on_Id, data); - if (!sourceOn) { - int delay = (data & DELAY_MASK) >> DELAY_SHIFT; - level->addToTickNextTick(x, y, z, Tile::diode_on_Id, - DELAYS[delay] * 2); + if (!isLocked(level, x, y, z, data)) { + bool sourceOn = shouldTurnOn(level, x, y, z, data); + if (on && !sourceOn) { + level->setTileAndData(x, y, z, getOffTile()->id, data, + Tile::UPDATE_CLIENTS); + } else if (!on) { + // when off-diodes are ticked, they always turn on for one tick and + // then off again if necessary + level->setTileAndData(x, y, z, getOnTile()->id, data, + Tile::UPDATE_CLIENTS); + if (!sourceOn) { + level->addToTickNextTick(x, y, z, getOnTile()->id, + getTurnOffDelay(data), -1); + } } } } @@ -56,9 +57,9 @@ Icon* DiodeTile::getTexture(int face, int data) { // down is used by the torch tesselator if (face == Facing::DOWN) { if (on) { - return Tile::notGate_on->getTexture(face); + return Tile::redstoneTorch_on->getTexture(face); } - return Tile::notGate_off->getTexture(face); + return Tile::redstoneTorch_off->getTexture(face); } if (face == Facing::UP) { return icon; @@ -67,10 +68,6 @@ Icon* DiodeTile::getTexture(int face, int data) { return Tile::stoneSlab->getTexture(Facing::UP); } -void DiodeTile::registerIcons(IconRegister* iconRegister) { - icon = iconRegister->registerIcon(on ? L"repeater_lit" : L"repeater"); -} - bool DiodeTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { if (face == Facing::DOWN || face == Facing::UP) { @@ -82,29 +79,37 @@ bool DiodeTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int DiodeTile::getRenderShape() { return SHAPE_DIODE; } -bool DiodeTile::getDirectSignal(Level* level, int x, int y, int z, int dir) { +bool DiodeTile::isOn(int data) { return on; } + +int DiodeTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int dir) { return getSignal(level, x, y, z, dir); } -bool DiodeTile::getSignal(LevelSource* level, int x, int y, int z, int facing) { - if (!on) { - return false; +int DiodeTile::getSignal(LevelSource* level, int x, int y, int z, int facing) { + int data = level->getData(x, y, z); + if (!isOn(data)) { + return Redstone::SIGNAL_NONE; } - int dir = getDirection(level->getData(x, y, z)); + int dir = getDirection(data); - if (dir == Direction::SOUTH && facing == Facing::SOUTH) return true; - if (dir == Direction::WEST && facing == Facing::WEST) return true; - if (dir == Direction::NORTH && facing == Facing::NORTH) return true; - if (dir == Direction::EAST && facing == Facing::EAST) return true; + if (dir == Direction::SOUTH && facing == Facing::SOUTH) + return getOutputSignal(level, x, y, z, data); + if (dir == Direction::WEST && facing == Facing::WEST) + return getOutputSignal(level, x, y, z, data); + if (dir == Direction::NORTH && facing == Facing::NORTH) + return getOutputSignal(level, x, y, z, data); + if (dir == Direction::EAST && facing == Facing::EAST) + return getOutputSignal(level, x, y, z, data); - return false; + return Redstone::SIGNAL_NONE; } void DiodeTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!canSurvive(level, x, y, z)) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); level->updateNeighborsAt(x + 1, y, z, id); level->updateNeighborsAt(x - 1, y, z, id); level->updateNeighborsAt(x, y, z + 1, id); @@ -114,76 +119,125 @@ void DiodeTile::neighborChanged(Level* level, int x, int y, int z, int type) { return; } + checkTickOnNeighbor(level, x, y, z, type); +} + +void DiodeTile::checkTickOnNeighbor(Level* level, int x, int y, int z, + int type) { int data = level->getData(x, y, z); - bool sourceOn = getSourceSignal(level, x, y, z, data); - int delay = (data & DELAY_MASK) >> DELAY_SHIFT; - if ((on && !sourceOn) || (!on && sourceOn)) { - level->addToTickNextTick(x, y, z, id, DELAYS[delay] * 2); + if (!isLocked(level, x, y, z, data)) { + bool sourceOn = shouldTurnOn(level, x, y, z, data); + if ((on && !sourceOn || !on && sourceOn) && + !level->isTileToBeTickedAt(x, y, z, id)) { + int prio = -1; + + // if the tile in front is a repeater, we prioritize this update + if (shouldPrioritize(level, x, y, z, data)) { + prio = -3; + } else if (on) { + prio = -2; + } + + level->addToTickNextTick(x, y, z, id, getTurnOnDelay(data), prio); + } } } -bool DiodeTile::getSourceSignal(Level* level, int x, int y, int z, int data) { - int dir = getDirection(data); - switch (dir) { - case Direction::SOUTH: - return level->getSignal(x, y, z + 1, Facing::SOUTH) || - (level->getTile(x, y, z + 1) == Tile::redStoneDust_Id && - level->getData(x, y, z + 1) > 0); - case Direction::NORTH: - return level->getSignal(x, y, z - 1, Facing::NORTH) || - (level->getTile(x, y, z - 1) == Tile::redStoneDust_Id && - level->getData(x, y, z - 1) > 0); - case Direction::EAST: - return level->getSignal(x + 1, y, z, Facing::EAST) || - (level->getTile(x + 1, y, z) == Tile::redStoneDust_Id && - level->getData(x + 1, y, z) > 0); - case Direction::WEST: - return level->getSignal(x - 1, y, z, Facing::WEST) || - (level->getTile(x - 1, y, z) == Tile::redStoneDust_Id && - level->getData(x - 1, y, z) > 0); - } +bool DiodeTile::isLocked(LevelSource* level, int x, int y, int z, int data) { return false; } -// 4J-PB - Adding a TestUse for tooltip display -bool DiodeTile::TestUse() { return true; } +bool DiodeTile::shouldTurnOn(Level* level, int x, int y, int z, int data) { + return getInputSignal(level, x, y, z, data) > Redstone::SIGNAL_NONE; +} -bool DiodeTile::use(Level* level, int x, int y, int z, - std::shared_ptr player, int clickedFace, - float clickX, float clickY, float clickZ, - bool soundOnly /*=false*/) // 4J added soundOnly param -{ - if (soundOnly) return false; +int DiodeTile::getInputSignal(Level* level, int x, int y, int z, int data) { + int dir = getDirection(data); - int data = level->getData(x, y, z); - int delay = (data & DELAY_MASK) >> DELAY_SHIFT; - delay = ((delay + 1) << DELAY_SHIFT) & DELAY_MASK; + int xx = x + Direction::STEP_X[dir]; + int zz = z + Direction::STEP_Z[dir]; + int input = level->getSignal(xx, y, zz, Direction::DIRECTION_FACING[dir]); - level->setData(x, y, z, delay | (data & DIRECTION_MASK)); - return true; + if (input >= Redstone::SIGNAL_MAX) return input; + return std::max(input, level->getTile(xx, y, zz) == Tile::redStoneDust_Id + ? level->getData(xx, y, zz) + : Redstone::SIGNAL_NONE); +} + +int DiodeTile::getAlternateSignal(LevelSource* level, int x, int y, int z, + int data) { + int dir = getDirection(data); + + switch (dir) { + case Direction::SOUTH: + case Direction::NORTH: + return std::max( + getAlternateSignalAt(level, x - 1, y, z, Facing::WEST), + getAlternateSignalAt(level, x + 1, y, z, Facing::EAST)); + case Direction::EAST: + case Direction::WEST: + return std::max( + getAlternateSignalAt(level, x, y, z + 1, Facing::SOUTH), + getAlternateSignalAt(level, x, y, z - 1, Facing::NORTH)); + } + + return Redstone::SIGNAL_NONE; +} + +int DiodeTile::getAlternateSignalAt(LevelSource* level, int x, int y, int z, + int facing) { + int tile = level->getTile(x, y, z); + + if (isAlternateInput(tile)) { + if (tile == Tile::redStoneDust_Id) { + return level->getData(x, y, z); + } else { + return level->getDirectSignal(x, y, z, facing); + } + } + + return Redstone::SIGNAL_NONE; } bool DiodeTile::isSignalSource() { return true; } void DiodeTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3) + 2) % 4; - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_ALL); - bool sourceOn = getSourceSignal(level, x, y, z, dir); + bool sourceOn = shouldTurnOn(level, x, y, z, dir); if (sourceOn) { level->addToTickNextTick(x, y, z, id, 1); } } void DiodeTile::onPlace(Level* level, int x, int y, int z) { - level->updateNeighborsAt(x + 1, y, z, id); - level->updateNeighborsAt(x - 1, y, z, id); - level->updateNeighborsAt(x, y, z + 1, id); - level->updateNeighborsAt(x, y, z - 1, id); - level->updateNeighborsAt(x, y - 1, z, id); - level->updateNeighborsAt(x, y + 1, z, id); + updateNeighborsInFront(level, x, y, z); +} + +void DiodeTile::updateNeighborsInFront(Level* level, int x, int y, int z) { + int dir = getDirection(level->getData(x, y, z)); + if (dir == Direction::WEST) { + level->neighborChanged(x + 1, y, z, id); + level->updateNeighborsAtExceptFromFacing(x + 1, y, z, id, Facing::WEST); + } + if (dir == Direction::EAST) { + level->neighborChanged(x - 1, y, z, id); + level->updateNeighborsAtExceptFromFacing(x - 1, y, z, id, Facing::EAST); + } + if (dir == Direction::NORTH) { + level->neighborChanged(x, y, z + 1, id); + level->updateNeighborsAtExceptFromFacing(x, y, z + 1, id, + Facing::NORTH); + } + if (dir == Direction::SOUTH) { + level->neighborChanged(x, y, z - 1, id); + level->updateNeighborsAtExceptFromFacing(x, y, z - 1, id, + Facing::SOUTH); + } } void DiodeTile::destroy(Level* level, int x, int y, int z, int data) { @@ -200,60 +254,37 @@ void DiodeTile::destroy(Level* level, int x, int y, int z, int data) { bool DiodeTile::isSolidRender(bool isServerLevel) { return false; } -int DiodeTile::getResource(int data, Random* random, int playerBonusLevel) { - return Item::diode->id; +bool DiodeTile::isAlternateInput(int tile) { + Tile* tt = Tile::tiles[tile]; + return tt != NULL && tt->isSignalSource(); } -void DiodeTile::animateTick(Level* level, int xt, int yt, int zt, - Random* random) { - if (!on) return; - int data = level->getData(xt, yt, zt); +int DiodeTile::getOutputSignal(LevelSource* level, int x, int y, int z, + int data) { + return Redstone::SIGNAL_MAX; +} + +bool DiodeTile::isDiode(int id) { + return Tile::diode_off->isSameDiode(id) || + Tile::comparator_off->isSameDiode(id); +} + +bool DiodeTile::isSameDiode(int id) { + return id == getOnTile()->id || id == getOffTile()->id; +} + +bool DiodeTile::shouldPrioritize(Level* level, int x, int y, int z, int data) { int dir = getDirection(data); - - double x = xt + 0.5f + (random->nextFloat() - 0.5f) * 0.2; - double y = yt + 0.4f + (random->nextFloat() - 0.5f) * 0.2; - double z = zt + 0.5f + (random->nextFloat() - 0.5f) * 0.2; - - double xo = 0; - double zo = 0; - - if (random->nextInt(2) == 0) { - // spawn on receiver - switch (dir) { - case Direction::SOUTH: - zo = -5.0f / 16.0f; - break; - case Direction::NORTH: - zo = 5.0f / 16.0f; - break; - case Direction::EAST: - xo = -5.0f / 16.0f; - break; - case Direction::WEST: - xo = 5.0f / 16.0f; - break; - } - } else { - // spawn on transmitter - int delay = (data & DELAY_MASK) >> DELAY_SHIFT; - switch (dir) { - case Direction::SOUTH: - zo = DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::NORTH: - zo = -DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::EAST: - xo = DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::WEST: - xo = -DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - } + if (isDiode(level->getTile(x - Direction::STEP_X[dir], y, + z - Direction::STEP_Z[dir]))) { + int odata = level->getData(x - Direction::STEP_X[dir], y, + z - Direction::STEP_Z[dir]); + int odir = getDirection(odata); + return odir != dir; } - level->addParticle(eParticleType_reddust, x + xo, y, z + zo, 0, 0, 0); + return false; } -int DiodeTile::cloneTileId(Level* level, int x, int y, int z) { - return Item::diode_Id; -} +int DiodeTile::getTurnOffDelay(int data) { return getTurnOnDelay(data); } + +bool DiodeTile::isMatching(int id) { return isSameDiode(id); } \ No newline at end of file diff --git a/Minecraft.World/Blocks/DiodeTile.h b/Minecraft.World/Blocks/DiodeTile.h index 2b0ced2f2..733d62b4e 100644 --- a/Minecraft.World/Blocks/DiodeTile.h +++ b/Minecraft.World/Blocks/DiodeTile.h @@ -8,14 +8,7 @@ class Level; class DiodeTile : public DirectionalTile { friend class Tile; -public: - static const int DELAY_MASK = DIRECTION_INV_MASK; - static const int DELAY_SHIFT = 2; - - static const double DELAY_RENDER_OFFSETS[4]; - static const int DELAYS[4]; - -private: +protected: bool on; protected: @@ -28,32 +21,67 @@ public: virtual bool canSurvive(Level* level, int x, int y, int z); virtual void tick(Level* level, int x, int y, int z, Random* random); virtual Icon* getTexture(int face, int data); - //@Override - void registerIcons(IconRegister* iconRegister); virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face); virtual int getRenderShape(); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int facing); - virtual void neighborChanged(Level* level, int x, int y, int z, int type); -private: - virtual bool getSourceSignal(Level* level, int x, int y, int z, int data); +protected: + virtual bool isOn(int data); + +public: + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); + virtual int getSignal(LevelSource* level, int x, int y, int z, int facing); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + +protected: + virtual void checkTickOnNeighbor(Level* level, int x, int y, int z, + int type); + +public: + virtual bool isLocked(LevelSource* level, int x, int y, int z, int data); + +protected: + virtual bool shouldTurnOn(Level* level, int x, int y, int z, int data); + virtual int getInputSignal(Level* level, int x, int y, int z, int data); + virtual int getAlternateSignal(LevelSource* level, int x, int y, int z, + int data); + virtual int getAlternateSignalAt(LevelSource* level, int x, int y, int z, + int facing); public: - virtual bool TestUse(); - virtual bool use(Level* level, int x, int y, int z, - std::shared_ptr player, int clickedFace, - float clickX, float clickY, float clickZ, - bool soundOnly = false); // 4J added soundOnly param virtual bool isSignalSource(); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); virtual void onPlace(Level* level, int x, int y, int z); + +protected: + virtual void updateNeighborsInFront(Level* level, int x, int y, int z); + +public: virtual void destroy(Level* level, int x, int y, int z, int data); virtual bool isSolidRender(bool isServerLevel = false); - virtual int getResource(int data, Random* random, int playerBonusLevel); - virtual void animateTick(Level* level, int xt, int yt, int zt, - Random* random); - virtual int cloneTileId(Level* level, int x, int y, int z); + virtual int getResource(int data, Random* random, int playerBonusLevel) = 0; + virtual int cloneTileId(Level* level, int x, int y, int z) = 0; + +protected: + virtual bool isAlternateInput(int tile); + virtual int getOutputSignal(LevelSource* level, int x, int y, int z, + int data); + +public: + static bool isDiode(int id); + virtual bool isSameDiode(int id); + virtual bool shouldPrioritize(Level* level, int x, int y, int z, int data); + +protected: + virtual int getTurnOffDelay(int data); + + virtual int getTurnOnDelay(int data) = 0; + virtual DiodeTile* getOnTile() = 0; + virtual DiodeTile* getOffTile() = 0; + +public: + virtual bool isMatching(int id); }; diff --git a/Minecraft.World/Blocks/DirectionalTile.cpp b/Minecraft.World/Blocks/DirectionalTile.cpp index f9a934411..6b4735d30 100644 --- a/Minecraft.World/Blocks/DirectionalTile.cpp +++ b/Minecraft.World/Blocks/DirectionalTile.cpp @@ -2,9 +2,6 @@ #include "DirectionalTile.h" -DirectionalTile::DirectionalTile(int id, Material* material) - : Tile(id, material) {} - DirectionalTile::DirectionalTile(int id, Material* material, bool isSolidRender) : Tile(id, material, isSolidRender) {} diff --git a/Minecraft.World/Blocks/DirectionalTile.h b/Minecraft.World/Blocks/DirectionalTile.h index 2ded263a1..1132f4fc6 100644 --- a/Minecraft.World/Blocks/DirectionalTile.h +++ b/Minecraft.World/Blocks/DirectionalTile.h @@ -8,7 +8,6 @@ public: static const int DIRECTION_INV_MASK = 0xC; protected: - DirectionalTile(int id, Material* material); DirectionalTile(int id, Material* material, bool isSolidRender); public: diff --git a/Minecraft.World/Blocks/DispenserTile.cpp b/Minecraft.World/Blocks/DispenserTile.cpp index dfabb985b..b6133a5d8 100644 --- a/Minecraft.World/Blocks/DispenserTile.cpp +++ b/Minecraft.World/Blocks/DispenserTile.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.entity.projectile.h" #include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.inventory.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.tile.entity.h" @@ -11,7 +12,10 @@ #include "../Headers/net.minecraft.h" #include "../Entities/Mob.h" -DispenserTile::DispenserTile(int id) : EntityTile(id, Material::stone) { +BehaviorRegistry DispenserTile::REGISTRY = + BehaviorRegistry(new DefaultDispenseItemBehavior()); + +DispenserTile::DispenserTile(int id) : BaseEntityTile(id, Material::stone) { random = new Random(); iconTop = NULL; @@ -19,14 +23,10 @@ DispenserTile::DispenserTile(int id) : EntityTile(id, Material::stone) { iconFrontVertical = NULL; } -int DispenserTile::getTickDelay() { return 4; } - -int DispenserTile::getResource(int data, Random* random, int playerBonusLevel) { - return Tile::dispenser_Id; -} +int DispenserTile::getTickDelay(Level* level) { return 4; } void DispenserTile::onPlace(Level* level, int x, int y, int z) { - EntityTile::onPlace(level, x, y, z); + BaseEntityTile::onPlace(level, x, y, z); recalcLockDir(level, x, y, z); } @@ -45,7 +45,7 @@ void DispenserTile::recalcLockDir(Level* level, int x, int y, int z) { if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2; if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5; if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4; - level->setData(x, y, z, lockDir); + level->setData(x, y, z, lockDir, Tile::UPDATE_CLIENTS); } Icon* DispenserTile::getTexture(int face, int data) { @@ -97,68 +97,53 @@ bool DispenserTile::use(Level* level, int x, int y, int z, return true; } -void DispenserTile::fireArrow(Level* level, int x, int y, int z, - Random* random) { - const int lockDir = level->getData(x, y, z); - // const float power = 1.1f; - const int accuracy = 6; - // bool bLaunched=true; - - int xd = 0, zd = 0; - if (lockDir == Facing::SOUTH) { - zd = 1; - } else if (lockDir == Facing::NORTH) { - zd = -1; - } else if (lockDir == Facing::EAST) { - xd = 1; - } else { - xd = -1; - } - +void DispenserTile::dispenseFrom(Level* level, int x, int y, int z) { + BlockSourceImpl source(level, x, y, z); std::shared_ptr trap = - std::dynamic_pointer_cast( - level->getTileEntity(x, y, z)); - if (trap != NULL) { - int slot = trap->getRandomSlot(); + std::dynamic_pointer_cast(source.getEntity()); + if (trap == NULL) return; - if (slot < 0) { - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - } else { - double xp = x + xd * 0.6 + 0.5; - double yp = y + 0.5; - double zp = z + zd * 0.6 + 0.5; - std::shared_ptr item = trap->getItem(slot); - int result = dispenseItem(trap, level, item, random, x, y, z, xd, - zd, xp, yp, zp); - if (result == REMOVE_ITEM) { - trap->removeItem(slot, 1); - } else if (result == DISPENSE_ITEM) { - item = trap->removeItem(slot, 1); - throwItem(level, item, random, accuracy, xd, zd, xp, yp, zp); - level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0); - } + int slot = trap->getRandomSlot(); + if (slot < 0) { + level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); + } else { + std::shared_ptr item = trap->getItem(slot); + DispenseItemBehavior* behavior = getDispenseMethod(item); - level->levelEvent(LevelEvent::PARTICLES_SHOOT, x, y, z, - (xd + 1) + (zd + 1) * 3); + if (behavior != DispenseItemBehavior::NOOP) { + std::shared_ptr leftOver = + behavior->dispense(&source, item); + + trap->setItem(slot, leftOver->count == 0 ? nullptr : leftOver); } } } +DispenseItemBehavior* DispenserTile::getDispenseMethod( + std::shared_ptr item) { + return REGISTRY.get(item->getItem()); +} + void DispenserTile::neighborChanged(Level* level, int x, int y, int z, int type) { - if (type > 0 && Tile::tiles[type]->isSignalSource()) { - bool signal = level->hasNeighborSignal(x, y, z) || - level->hasNeighborSignal(x, y + 1, z); - if (signal) { - level->addToTickNextTick(x, y, z, this->id, getTickDelay()); - } + bool signal = level->hasNeighborSignal(x, y, z) || + level->hasNeighborSignal(x, y + 1, z); + int data = level->getData(x, y, z); + bool isTriggered = (data & TRIGGER_BIT) != 0; + + if (signal && !isTriggered) { + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); + level->setData(x, y, z, data | TRIGGER_BIT, UPDATE_NONE); + } else if (!signal && isTriggered) { + level->setData(x, y, z, data & ~TRIGGER_BIT, UPDATE_NONE); } } void DispenserTile::tick(Level* level, int x, int y, int z, Random* random) { - if (!level->isClientSide && (level->hasNeighborSignal(x, y, z) || - level->hasNeighborSignal(x, y + 1, z))) { - fireArrow(level, x, y, z, random); + if (!level->isClientSide) // && (level.hasNeighborSignal(x, y, z) || + // level.hasNeighborSignal(x, y + 1, z))) + { + dispenseFrom(level, x, y, z); } } @@ -167,13 +152,17 @@ std::shared_ptr DispenserTile::newTileEntity(Level* level) { } void DispenserTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { - int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3; + std::shared_ptr by, + std::shared_ptr itemInstance) { + int dir = PistonBaseTile::getNewFacing(level, x, y, z, by); - if (dir == 0) level->setData(x, y, z, Facing::NORTH); - if (dir == 1) level->setData(x, y, z, Facing::EAST); - if (dir == 2) level->setData(x, y, z, Facing::SOUTH); - if (dir == 3) level->setData(x, y, z, Facing::WEST); + level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); + + if (itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->setCustomName(itemInstance->getHoverName()); + } } void DispenserTile::onRemove(Level* level, int x, int y, int z, int id, @@ -216,340 +205,29 @@ void DispenserTile::onRemove(Level* level, int x, int y, int z, int id, container->setItem(i, nullptr); } } + level->updateNeighbourForOutputSignal(x, y, z, id); } - EntityTile::onRemove(level, x, y, z, id, data); + BaseEntityTile::onRemove(level, x, y, z, id, data); } -void DispenserTile::throwItem(Level* level, std::shared_ptr item, - Random* random, int accuracy, int xd, int zd, - double xp, double yp, double zp) { - std::shared_ptr itemEntity = std::shared_ptr( - new ItemEntity(level, xp, yp - 0.3, zp, item)); +Position* DispenserTile::getDispensePosition(BlockSource* source) { + FacingEnum* facing = getFacing(source->getData()); - double pow = random->nextDouble() * 0.1 + 0.2; - itemEntity->xd = xd * pow; - itemEntity->yd = .2f; - itemEntity->zd = zd * pow; + double originX = source->getX() + 0.7 * facing->getStepX(); + double originY = source->getY() + 0.7 * facing->getStepY(); + double originZ = source->getZ() + 0.7 * facing->getStepZ(); - itemEntity->xd += (random->nextGaussian()) * 0.0075f * accuracy; - itemEntity->yd += (random->nextGaussian()) * 0.0075f * accuracy; - itemEntity->zd += (random->nextGaussian()) * 0.0075f * accuracy; - - level->addEntity(itemEntity); + return new PositionImpl(originX, originY, originZ); } -int DispenserTile::dispenseItem(std::shared_ptr trap, - Level* level, - std::shared_ptr item, - Random* random, int x, int y, int z, int xd, - int zd, double xp, double yp, double zp) { - float power = 1.1f; - int accuracy = 6; - - // 4J-PB - moved to a switch - switch (item->id) { - case Item::arrow_Id: { - int currentProjectiles = - level->countInstanceOf(eTYPE_PROJECTILE, false); - if (currentProjectiles < - Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit - { - std::shared_ptr arrow = - std::shared_ptr(new Arrow(level, xp, yp, zp)); - arrow->shoot(xd, .1f, zd, power, (float)accuracy); - arrow->pickup = Arrow::PICKUP_ALLOWED; - level->addEntity(arrow); - level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0); - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::egg_Id: { - int currentProjectiles = - level->countInstanceOf(eTYPE_PROJECTILE, false); - if (currentProjectiles < - Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit - { - std::shared_ptr egg = std::shared_ptr( - new ThrownEgg(level, xp, yp, zp)); - egg->shoot(xd, .1f, zd, power, (float)accuracy); - level->addEntity(egg); - level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0); - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::snowBall_Id: { - int currentProjectiles = - level->countInstanceOf(eTYPE_PROJECTILE, false); - if (currentProjectiles < - Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit - { - std::shared_ptr snowball = - std::shared_ptr(new Snowball(level, xp, yp, zp)); - snowball->shoot(xd, .1f, zd, power, (float)accuracy); - level->addEntity(snowball); - level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0); - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::potion_Id: { - int currentProjectiles = - level->countInstanceOf(eTYPE_PROJECTILE, false); - if (currentProjectiles < - Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit - { - if (PotionItem::isThrowable(item->getAuxValue())) { - std::shared_ptr potion = - std::shared_ptr(new ThrownPotion( - level, xp, yp, zp, item->getAuxValue())); - potion->shoot(xd, .1f, zd, power * 1.25f, accuracy * .5f); - level->addEntity(potion); - level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0); - } else { - std::shared_ptr itemEntity = - std::shared_ptr( - new ItemEntity(level, xp, yp - 0.3, zp, item)); - - double pow = random->nextDouble() * 0.1 + 0.2; - itemEntity->xd = xd * pow; - itemEntity->yd = .2f; - itemEntity->zd = zd * pow; - - itemEntity->xd += - (random->nextGaussian()) * 0.0075f * accuracy; - itemEntity->yd += - (random->nextGaussian()) * 0.0075f * accuracy; - itemEntity->zd += - (random->nextGaussian()) * 0.0075f * accuracy; - - level->addEntity(itemEntity); - level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0); - } - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::expBottle_Id: { - int currentProjectiles = - level->countInstanceOf(eTYPE_PROJECTILE, false); - if (currentProjectiles < - Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit - { - std::shared_ptr expBottle = - std::shared_ptr( - new ThrownExpBottle(level, xp, yp, zp)); - expBottle->shoot(xd, .1f, zd, power * 1.25f, accuracy * .5f); - level->addEntity(expBottle); - level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0); - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::fireball_Id: // TU9 - { - int currentFireballs = - level->countInstanceOf(eTYPE_SMALL_FIREBALL, true); - if (currentFireballs < - Level::MAX_DISPENSABLE_FIREBALLS) // 4J - added limit - { - std::shared_ptr fireball = - std::shared_ptr( - new SmallFireball(level, xp + xd * .3, yp, zp + zd * .3, - xd + random->nextGaussian() * .05, - random->nextGaussian() * .05, - zd + random->nextGaussian() * .05)); - level->addEntity(fireball); - level->levelEvent(LevelEvent::SOUND_BLAZE_FIREBALL, x, y, z, 0); - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::monsterPlacer_Id: { - int iResult = 0; - // MonsterPlacerItem *spawnEgg = (MonsterPlacerItem - // *)item->getItem(); - std::shared_ptr newEntity = MonsterPlacerItem::canSpawn( - item->getAuxValue(), level, &iResult); - - std::shared_ptr mob = - std::dynamic_pointer_cast(newEntity); - if (mob != NULL) { - // 4J-PB - Changed the line below slightly since mobs were - // sticking to the dispenser rather than dropping down when - // fired - mob->moveTo(xp + xd * 0.4, yp - 0.3, zp + zd * 0.4, - level->random->nextFloat() * 360, 0); - mob->finalizeMobSpawn(); - level->addEntity(mob); - level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0); - return REMOVE_ITEM; - } else { - // some negative sound effect? - level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - - // not sending a message here, since we will probably get - // flooded with them when people have automatic dispensers for - // spawn eggs - return LEAVE_ITEM; - } - } break; - case Item::bucket_lava_Id: - case Item::bucket_water_Id: { - BucketItem* pBucket = (BucketItem*)item->getItem(); - - if (pBucket->emptyBucket(level, x, y, z, x + xd, y, z + zd)) { - item->id = Item::bucket_empty_Id; - item->count = 1; - return LEAVE_ITEM; - } - return DISPENSE_ITEM; - } break; - case Item::bucket_empty_Id: { - int xt = x + xd; - int zt = z + zd; - Material* pMaterial = level->getMaterial(xt, y, zt); - int data = level->getData(xt, y, zt); - - if (pMaterial == Material::water && data == 0) { - level->setTile(xt, y, zt, 0); - - if (--item->count == 0) { - item->id = Item::bucket_water_Id; - item->count = 1; - } else if (trap->addItem(std::shared_ptr( - new ItemInstance(Item::bucket_water))) < 0) { - throwItem(level, - std::shared_ptr( - new ItemInstance(Item::bucket_water)), - random, 6, xd, zd, xp, yp, zp); - } - - return LEAVE_ITEM; - } else if (pMaterial == Material::lava && data == 0) { - level->setTile(xt, y, zt, 0); - - if (--item->count == 0) { - item->id = Item::bucket_lava_Id; - item->count = 1; - } else if (trap->addItem(std::shared_ptr( - new ItemInstance(Item::bucket_lava))) < 0) { - throwItem(level, - std::shared_ptr( - new ItemInstance(Item::bucket_lava)), - random, 6, xd, zd, xp, yp, zp); - } - - return LEAVE_ITEM; - } - return DISPENSE_ITEM; - } - - break; - // TU12 - case Item::minecart_Id: - case Item::minecart_chest_Id: - case Item::minecart_furnace_Id: { - xp = x + (xd < 0 ? xd * 0.8 : xd * 1.8f) + Mth::abs(zd) * 0.5f; - zp = z + (zd < 0 ? zd * 0.8 : zd * 1.8f) + Mth::abs(xd) * 0.5f; - - if (RailTile::isRail(level, x + xd, y, z + zd)) { - yp = y + 0.5f; - } else if (level->isEmptyTile(x + xd, y, z + zd) && - RailTile::isRail(level, x + xd, y - 1, z + zd)) { - yp = y - 0.5f; - } else { - return DISPENSE_ITEM; - } - - if (level->countInstanceOf(eTYPE_MINECART, true) < - Level::MAX_CONSOLE_MINECARTS) // 4J - added limit - { - std::shared_ptr minecart = std::shared_ptr( - new Minecart(level, xp, yp, zp, - ((MinecartItem*)item->getItem())->type)); - level->addEntity(minecart); - level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0); - - return REMOVE_ITEM; - } else { - return DISPENSE_ITEM; - } - } break; - - case Item::boat_Id: { - bool bLaunchBoat = false; - - xp = x + (xd < 0 ? xd * 0.8 : xd * 1.8f) + Mth::abs(zd) * 0.5f; - zp = z + (zd < 0 ? zd * 0.8 : zd * 1.8f) + Mth::abs(xd) * 0.5f; - - if (level->getMaterial(x + xd, y, z + zd) == Material::water) { - bLaunchBoat = true; - yp = y + 1.0f; - } else if (level->isEmptyTile(x + xd, y, z + zd) && - level->getMaterial(x + xd, y - 1, z + zd) == - Material::water) { - bLaunchBoat = true; - yp = y; - } - - // check the limit on boats - if (bLaunchBoat && level->countInstanceOf(eTYPE_BOAT, true) < - Level::MAX_XBOX_BOATS) // 4J - added limit - { - std::shared_ptr boat = - std::shared_ptr(new Boat(level, xp, yp, zp)); - level->addEntity(boat); - level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0); - return REMOVE_ITEM; - } else { - return DISPENSE_ITEM; - } - } break; - } - - return DISPENSE_ITEM; +FacingEnum* DispenserTile::getFacing(int data) { + return FacingEnum::fromData(data & FACING_MASK); } + +bool DispenserTile::hasAnalogOutputSignal() { return true; } + +int DispenserTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + return AbstractContainerMenu::getRedstoneSignalFromContainer( + std::dynamic_pointer_cast(level->getTileEntity(x, y, z))); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/DispenserTile.h b/Minecraft.World/Blocks/DispenserTile.h index 4caa43963..de051f1f7 100644 --- a/Minecraft.World/Blocks/DispenserTile.h +++ b/Minecraft.World/Blocks/DispenserTile.h @@ -1,20 +1,19 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" +#include "../Headers/net.minecraft.core.h" class Player; class Mob; class ChunkRebuildData; -class DispenserTile : public EntityTile { + +class DispenserTile : public BaseEntityTile { friend class Tile; friend class ChunkRebuildData; -private: - static const int DISPENSE_ITEM = 0; - static const int REMOVE_ITEM = 1; - static const int LEAVE_ITEM = 2; - public: static const int FACING_MASK = 0x7; + static const int TRIGGER_BIT = 8; + static BehaviorRegistry REGISTRY; protected: Random* random; @@ -27,8 +26,7 @@ protected: DispenserTile(int id); public: - virtual int getTickDelay(); - virtual int getResource(int data, Random* random, int playerBonusLevel); + virtual int getTickDelay(Level* level); virtual void onPlace(Level* level, int x, int y, int z); private: @@ -36,31 +34,30 @@ private: public: virtual Icon* getTexture(int face, int data); - //@Override - void registerIcons(IconRegister* iconRegister); + virtual void registerIcons(IconRegister* iconRegister); virtual bool TestUse(); virtual bool use(Level* level, int x, int y, int z, std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param -private: - void fireArrow(Level* level, int x, int y, int z, Random* random); +protected: + virtual void dispenseFrom(Level* level, int x, int y, int z); + virtual DispenseItemBehavior* getDispenseMethod( + std::shared_ptr item); public: virtual void neighborChanged(Level* level, int x, int y, int z, int type); virtual void tick(Level* level, int x, int y, int z, Random* random); virtual std::shared_ptr newTileEntity(Level* level); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); -private: - static void throwItem(Level* level, std::shared_ptr item, - Random* random, int accuracy, int xd, int zd, - double xp, double yp, double zp); - static int dispenseItem(std::shared_ptr trap, - Level* level, std::shared_ptr item, - Random* random, int x, int y, int z, int xd, int zd, - double xp, double yp, double zp); + static Position* getDispensePosition(BlockSource* source); + static FacingEnum* getFacing(int data); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/DoorTile.cpp b/Minecraft.World/Blocks/DoorTile.cpp index 3552377b6..11378ce8a 100644 --- a/Minecraft.World/Blocks/DoorTile.cpp +++ b/Minecraft.World/Blocks/DoorTile.cpp @@ -11,9 +11,8 @@ const std::wstring DoorTile::TEXTURES[] = { L"doorWood_lower", L"doorWood_upper", L"doorIron_lower", L"doorIron_upper"}; -DoorTile::DoorTile(int id, Material* material) : Tile(id, material, false) { - icons = NULL; - +DoorTile::DoorTile(int id, Material* material) + : Tile(id, material, false) { if (material == Material::metal) { texBase = 2; } else { @@ -25,10 +24,13 @@ DoorTile::DoorTile(int id, Material* material) : Tile(id, material, false) { Tile::setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r); } -Icon* DoorTile::getTexture(int face, int data) { return icons[texBase]; } +Icon* DoorTile::getTexture(int face, int data) { + return iconBottom[TEXTURE_NORMAL]; +} Icon* DoorTile::getTexture(LevelSource* level, int x, int y, int z, int face) { - if (face == Facing::UP || face == Facing::DOWN) return icons[texBase]; + if (face == Facing::UP || face == Facing::DOWN) + return iconBottom[TEXTURE_NORMAL]; int compositeData = getCompositeData(level, x, y, z); int dir = compositeData & C_DIR_MASK; @@ -57,18 +59,22 @@ Icon* DoorTile::getTexture(LevelSource* level, int x, int y, int z, int face) { if ((compositeData & C_RIGHT_HINGE_MASK) != 0) flip = !flip; } - return icons[texBase + (flip ? DOOR_TILE_TEXTURE_COUNT : 0) + - (upper ? 1 : 0)]; + if (upper) { + return iconTop[flip ? TEXTURE_FLIPPED : TEXTURE_NORMAL]; + } else { + return iconBottom[flip ? TEXTURE_FLIPPED : TEXTURE_NORMAL]; + } } void DoorTile::registerIcons(IconRegister* iconRegister) { - icons = new Icon*[DOOR_TILE_TEXTURE_COUNT * 2]; - - for (int i = 0; i < DOOR_TILE_TEXTURE_COUNT; i++) { - icons[i] = iconRegister->registerIcon(TEXTURES[i]); - icons[i + DOOR_TILE_TEXTURE_COUNT] = - new FlippedIcon(icons[i], true, false); - } + iconTop[TEXTURE_NORMAL] = + iconRegister->registerIcon(getIconName() + L"_upper"); + iconBottom[TEXTURE_NORMAL] = + iconRegister->registerIcon(getIconName() + L"_lower"); + iconTop[TEXTURE_FLIPPED] = + new FlippedIcon(iconTop[TEXTURE_NORMAL], true, false); + iconBottom[TEXTURE_FLIPPED] = + new FlippedIcon(iconBottom[TEXTURE_NORMAL], true, false); } bool DoorTile::blocksLight() { return false; } @@ -157,7 +163,7 @@ void DoorTile::attack(Level* level, int x, int y, int z, } // 4J-PB - Adding a TestUse for tooltip display -bool DoorTile::TestUse() { return true; } +bool DoorTile::TestUse() { return id == Tile::door_wood_Id; } bool DoorTile::use(Level* level, int x, int y, int z, std::shared_ptr player, int clickedFace, @@ -178,10 +184,10 @@ bool DoorTile::use(Level* level, int x, int y, int z, int lowerData = compositeData & C_LOWER_DATA_MASK; lowerData ^= 4; if ((compositeData & C_IS_UPPER_MASK) == 0) { - level->setData(x, y, z, lowerData); //, Tile.UPDATE_CLIENTS); + level->setData(x, y, z, lowerData, Tile::UPDATE_CLIENTS); level->setTilesDirty(x, y, z, x, y, z); } else { - level->setData(x, y - 1, z, lowerData); //, Tile.UPDATE_CLIENTS); + level->setData(x, y - 1, z, lowerData, Tile::UPDATE_CLIENTS); level->setTilesDirty(x, y - 1, z, x, y, z); } @@ -197,10 +203,10 @@ void DoorTile::setOpen(Level* level, int x, int y, int z, bool shouldOpen) { int lowerData = compositeData & C_LOWER_DATA_MASK; lowerData ^= 4; if ((compositeData & C_IS_UPPER_MASK) == 0) { - level->setData(x, y, z, lowerData); //, Tile.UPDATE_CLIENTS); + level->setData(x, y, z, lowerData, Tile::UPDATE_CLIENTS); level->setTilesDirty(x, y, z, x, y, z); } else { - level->setData(x, y - 1, z, lowerData); //, Tile.UPDATE_CLIENTS); + level->setData(x, y - 1, z, lowerData, Tile::UPDATE_CLIENTS); level->setTilesDirty(x, y - 1, z, x, y, z); } @@ -212,14 +218,14 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) { if ((data & UPPER_BIT) == 0) { bool spawn = false; if (level->getTile(x, y + 1, z) != id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); spawn = true; } if (!level->isSolidBlockingTile(x, y - 1, z)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); spawn = true; if (level->getTile(x, y + 1, z) == id) { - level->setTile(x, y + 1, z, 0); + level->removeTile(x, y + 1, z); } } if (spawn) { @@ -236,7 +242,7 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) { } } else { if (level->getTile(x, y - 1, z) != id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } if (type > 0 && type != id) { neighborChanged(level, x, y - 1, z, type); @@ -291,3 +297,14 @@ int DoorTile::cloneTileId(Level* level, int x, int y, int z) { return material == Material::metal ? Item::door_iron_Id : Item::door_wood_Id; } + +void DoorTile::playerWillDestroy(Level* level, int x, int y, int z, int data, + std::shared_ptr player) { + if (player->abilities.instabuild) { + if ((data & UPPER_BIT) != 0) { + if (level->getTile(x, y - 1, z) == id) { + level->removeTile(x, y - 1, z); + } + } + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/DoorTile.h b/Minecraft.World/Blocks/DoorTile.h index 618a72a3f..1c9abde7b 100644 --- a/Minecraft.World/Blocks/DoorTile.h +++ b/Minecraft.World/Blocks/DoorTile.h @@ -10,6 +10,10 @@ class DoorTile : public Tile { friend class Tile; friend class ChunkRebuildData; +private: + static const int TEXTURE_NORMAL = 0; + static const int TEXTURE_FLIPPED = 1; + public: static const int UPPER_BIT = 8; static const int C_DIR_MASK = 3; @@ -22,17 +26,16 @@ private: static const int DOOR_TILE_TEXTURE_COUNT = 4; static const std::wstring TEXTURES[]; int texBase; - Icon** icons; + Icon* iconTop[2]; + Icon* iconBottom[2]; protected: DoorTile(int id, Material* material); public: virtual Icon* getTexture(int face, int data); - //@Override - Icon* getTexture(LevelSource* level, int x, int y, int z, int face); - //@Override - void registerIcons(IconRegister* iconRegister); + virtual Icon* getTexture(LevelSource* level, int x, int y, int z, int face); + virtual void registerIcons(IconRegister* iconRegister); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); @@ -68,4 +71,6 @@ public: virtual int getPistonPushReaction(); int getCompositeData(LevelSource* level, int x, int y, int z); virtual int cloneTileId(Level* level, int x, int y, int z); + virtual void playerWillDestroy(Level* level, int x, int y, int z, int data, + std::shared_ptr player); }; diff --git a/Minecraft.World/Blocks/DropperTile.cpp b/Minecraft.World/Blocks/DropperTile.cpp new file mode 100644 index 000000000..a25d620c4 --- /dev/null +++ b/Minecraft.World/Blocks/DropperTile.cpp @@ -0,0 +1,68 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.core.h" +#include "DropperTile.h" + +DropperTile::DropperTile(int id) : DispenserTile(id) { + DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(); +} + +void DropperTile::registerIcons(IconRegister* iconRegister) { + icon = iconRegister->registerIcon(L"furnace_side"); + iconTop = iconRegister->registerIcon(L"furnace_top"); + iconFront = + iconRegister->registerIcon(getIconName() + L"_front_horizontal"); + iconFrontVertical = + iconRegister->registerIcon(getIconName() + L"_front_vertical"); +} + +DispenseItemBehavior* DropperTile::getDispenseMethod( + std::shared_ptr item) { + return DISPENSE_BEHAVIOUR; +} + +std::shared_ptr DropperTile::newTileEntity(Level* level) { + return std::shared_ptr(new DropperTileEntity()); +} + +void DropperTile::dispenseFrom(Level* level, int x, int y, int z) { + BlockSourceImpl source(level, x, y, z); + std::shared_ptr trap = + std::dynamic_pointer_cast(source.getEntity()); + if (trap == NULL) return; + + int slot = trap->getRandomSlot(); + if (slot < 0) { + level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); + } else { + std::shared_ptr item = trap->getItem(slot); + int face = level->getData(x, y, z) & DispenserTile::FACING_MASK; + std::shared_ptr into = HopperTileEntity::getContainerAt( + level, x + Facing::STEP_X[face], y + Facing::STEP_Y[face], + z + Facing::STEP_Z[face]); + std::shared_ptr remaining = nullptr; + + if (into != NULL) { + remaining = + HopperTileEntity::addItem(into.get(), item->copy()->remove(1), + Facing::OPPOSITE_FACING[face]); + + if (remaining == NULL) { + remaining = item->copy(); + if (--remaining->count == 0) remaining = nullptr; + } else { + // placing one item failed, so restore original count + remaining = item->copy(); + } + } else { + remaining = DISPENSE_BEHAVIOUR->dispense(&source, item); + if (remaining != NULL && remaining->count == 0) remaining = nullptr; + } + + trap->setItem(slot, remaining); + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/DropperTile.h b/Minecraft.World/Blocks/DropperTile.h new file mode 100644 index 000000000..01af4a3b8 --- /dev/null +++ b/Minecraft.World/Blocks/DropperTile.h @@ -0,0 +1,23 @@ +#pragma once + +#include "DispenserTile.h" + +class DropperTile : public DispenserTile { +private: + DispenseItemBehavior* DISPENSE_BEHAVIOUR; + +public: + DropperTile(int id); + + virtual void registerIcons(IconRegister* iconRegister); + +protected: + virtual DispenseItemBehavior* getDispenseMethod( + std::shared_ptr item); + +public: + virtual std::shared_ptr newTileEntity(Level* level); + +protected: + virtual void dispenseFrom(Level* level, int x, int y, int z); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/EggTile.cpp b/Minecraft.World/Blocks/EggTile.cpp index be52a29fc..67fd2e1e9 100644 --- a/Minecraft.World/Blocks/EggTile.cpp +++ b/Minecraft.World/Blocks/EggTile.cpp @@ -7,11 +7,11 @@ EggTile::EggTile(int id) : Tile(id, Material::egg, false) {} void EggTile::onPlace(Level* level, int x, int y, int z) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } void EggTile::neighborChanged(Level* level, int x, int y, int z, int type) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } void EggTile::tick(Level* level, int x, int y, int z, Random* random) { @@ -23,10 +23,10 @@ void EggTile::checkSlide(Level* level, int x, int y, int z) { int r = 32; if (HeavyTile::instaFall || !level->hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); while (HeavyTile::isFree(level, x, y - 1, z) && y > 0) y--; if (y > 0) { - level->setTile(x, y, z, id); + level->setTileAndData(x, y, z, id, 0, Tile::UPDATE_CLIENTS); } } else { std::shared_ptr e = std::shared_ptr( @@ -64,8 +64,9 @@ void EggTile::teleport(Level* level, int x, int y, int z) { // isn't present. Don't set tiles on client, and don't create // particles on the server (matches later change in Java) if (!level->isClientSide) { - level->setTileAndData(xt, yt, zt, id, level->getData(x, y, z)); - level->setTile(x, y, z, 0); + level->setTileAndData(xt, yt, zt, id, level->getData(x, y, z), + Tile::UPDATE_CLIENTS); + level->removeTile(x, y, z); // 4J Stu - The PC version is wrong as the particles calculated // on the client side will point towards a different location to @@ -91,18 +92,19 @@ void EggTile::teleport(Level* level, int x, int y, int z) { // for (int j = 0; j < count; j++) // { // double d = level->random->nextDouble(); // j < - //count / 2 ? 0 : + // count / 2 ? 0 : //// 1; // float xa = (level->random->nextFloat() - 0.5f) * - //0.2f; float ya = (level->random->nextFloat() - 0.5f) * 0.2f; float - //za = (level->random->nextFloat() - 0.5f) * 0.2f; + // 0.2f; float ya = (level->random->nextFloat() - + // 0.5f) * 0.2f; float za = + // (level->random->nextFloat() - 0.5f) * 0.2f; // double _x = xt + (x - xt) * d + - //(level->random->nextDouble() - 0.5) * 1 + 0.5f; double _y = yt + - //(y - yt) * d + level->random->nextDouble() * 1 - 0.5f; double _z = - //zt + (z - zt) * d + (level->random->nextDouble() - 0.5) * 1 + - //0.5f; level->addParticle(eParticleType_ender, _x, _y, _z, xa, ya, - //za); + //(level->random->nextDouble() - 0.5) * 1 + 0.5f; + // double _y = yt + (y - yt) * d + level->random->nextDouble() * 1 - + // 0.5f; double _z = zt + (z - zt) * d + + // (level->random->nextDouble() - 0.5) * 1 + 0.5f; + // level->addParticle(eParticleType_ender, _x, _y, _z, xa, ya, za); // } // } return; @@ -110,7 +112,7 @@ void EggTile::teleport(Level* level, int x, int y, int z) { } } -int EggTile::getTickDelay() { return 3; } +int EggTile::getTickDelay(Level* level) { return 5; } bool EggTile::blocksLight() { return false; } @@ -118,6 +120,11 @@ bool EggTile::isSolidRender(bool isServerLevel) { return false; } bool EggTile::isCubeShaped() { return false; } +bool EggTile::shouldRenderFace(LevelSource* level, int x, int y, int z, + int face) { + return true; +} + int EggTile::getRenderShape() { return Tile::SHAPE_EGG; } int EggTile::cloneTileId(Level* level, int x, int y, int z) { return 0; } @@ -147,9 +154,4 @@ void EggTile::generateTeleportParticles(Level* level, int xt, int yt, int zt, zt + deltaZ * d + (level->random->nextDouble() - 0.5) * 1 + 0.5f; level->addParticle(eParticleType_ender, _x, _y, _z, xa, ya, za); } -} - -bool EggTile::shouldRenderFace(LevelSource* level, int x, int y, int z, - int face) { - return true; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/EggTile.h b/Minecraft.World/Blocks/EggTile.h index 7984a7cdf..873ef6267 100644 --- a/Minecraft.World/Blocks/EggTile.h +++ b/Minecraft.World/Blocks/EggTile.h @@ -23,7 +23,7 @@ private: void teleport(Level* level, int x, int y, int z); public: - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); diff --git a/Minecraft.World/Blocks/EnchantmentTableTile.cpp b/Minecraft.World/Blocks/EnchantmentTableTile.cpp index 8c97dc3b5..d337dd0ee 100644 --- a/Minecraft.World/Blocks/EnchantmentTableTile.cpp +++ b/Minecraft.World/Blocks/EnchantmentTableTile.cpp @@ -10,7 +10,7 @@ const std::wstring EnchantmentTableTile::TEXTURE_TOP = L"enchantment_top"; const std::wstring EnchantmentTableTile::TEXTURE_BOTTOM = L"enchantment_bottom"; EnchantmentTableTile::EnchantmentTableTile(int id) - : EntityTile(id, Material::stone, false) { + : BaseEntityTile(id, Material::stone, false) { updateDefaultShape(); setLightBlock(0); @@ -27,7 +27,7 @@ bool EnchantmentTableTile::isCubeShaped() { return false; } void EnchantmentTableTile::animateTick(Level* level, int x, int y, int z, Random* random) { - EntityTile::animateTick(level, x, y, z, random); + BaseEntityTile::animateTick(level, x, y, z, random); for (int xx = x - 2; xx <= x + 2; xx++) { for (int zz = z - 2; zz <= z + 2; zz++) { @@ -74,10 +74,25 @@ bool EnchantmentTableTile::use( if (level->isClientSide) { return true; } - player->startEnchanting(x, y, z); + std::shared_ptr table = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + player->startEnchanting(x, y, z, + table->hasCustomName() ? table->getName() : L""); return true; } +void EnchantmentTableTile::setPlacedBy( + Level* level, int x, int y, int z, std::shared_ptr by, + std::shared_ptr itemInstance) { + BaseEntityTile::setPlacedBy(level, x, y, z, by, itemInstance); + if (itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->setCustomName(itemInstance->getHoverName()); + } +} + void EnchantmentTableTile::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(TEXTURE_SIDE); iconTop = iconRegister->registerIcon(TEXTURE_TOP); diff --git a/Minecraft.World/Blocks/EnchantmentTableTile.h b/Minecraft.World/Blocks/EnchantmentTableTile.h index ffff6ed29..ee61cd48f 100644 --- a/Minecraft.World/Blocks/EnchantmentTableTile.h +++ b/Minecraft.World/Blocks/EnchantmentTableTile.h @@ -1,8 +1,8 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class ChunkRebuildData; -class EnchantmentTableTile : public EntityTile { +class EnchantmentTableTile : public BaseEntityTile { friend class ChunkRebuildData; public: @@ -18,14 +18,17 @@ public: EnchantmentTableTile(int id); virtual void updateDefaultShape(); // 4J Added override - bool isCubeShaped(); - void animateTick(Level* level, int x, int y, int z, Random* random); - bool isSolidRender(bool isServerLevel = false); - Icon* getTexture(int face, int data); - std::shared_ptr newTileEntity(Level* level); - bool use(Level* level, int x, int y, int z, std::shared_ptr player, - int clickedFace, float clickX, float clickY, float clickZ, - bool soundOnly = false); // 4J added soundOnly param - //@Override - void registerIcons(IconRegister* iconRegister); + virtual bool isCubeShaped(); + virtual void animateTick(Level* level, int x, int y, int z, Random* random); + virtual bool isSolidRender(bool isServerLevel = false); + virtual Icon* getTexture(int face, int data); + virtual std::shared_ptr newTileEntity(Level* level); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); // 4J added soundOnly param + virtual void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); + virtual void registerIcons(IconRegister* iconRegister); }; diff --git a/Minecraft.World/Blocks/EnderChestTile.cpp b/Minecraft.World/Blocks/EnderChestTile.cpp index 0c5093308..5a1b60f15 100644 --- a/Minecraft.World/Blocks/EnderChestTile.cpp +++ b/Minecraft.World/Blocks/EnderChestTile.cpp @@ -8,7 +8,7 @@ #include "EnderChestTile.h" EnderChestTile::EnderChestTile(int id) - : EntityTile(id, Material::stone, false) { + : BaseEntityTile(id, Material::stone, false) { updateDefaultShape(); } @@ -33,7 +33,8 @@ int EnderChestTile::getResourceCount(Random* random) { return 8; } bool EnderChestTile::isSilkTouchable() { return true; } void EnderChestTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int facing = 0; int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5f)) & 3; @@ -42,7 +43,7 @@ void EnderChestTile::setPlacedBy(Level* level, int x, int y, int z, if (dir == 2) facing = Facing::SOUTH; if (dir == 3) facing = Facing::WEST; - level->setData(x, y, z, facing); + level->setData(x, y, z, facing, Tile::UPDATE_CLIENTS); } bool EnderChestTile::use(Level* level, int x, int y, int z, diff --git a/Minecraft.World/Blocks/EnderChestTile.h b/Minecraft.World/Blocks/EnderChestTile.h index 369d97f03..25c00227f 100644 --- a/Minecraft.World/Blocks/EnderChestTile.h +++ b/Minecraft.World/Blocks/EnderChestTile.h @@ -1,9 +1,9 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" #include "ChestTile.h" -class EnderChestTile : public EntityTile { +class EnderChestTile : public BaseEntityTile { public: static const int EVENT_SET_OPEN_COUNT = ChestTile::EVENT_SET_OPEN_COUNT; @@ -21,7 +21,8 @@ protected: public: void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); bool use(Level* level, int x, int y, int z, std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); diff --git a/Minecraft.World/Blocks/FallingTile.cpp b/Minecraft.World/Blocks/FallingTile.cpp index 89e96dc39..a57aa58d2 100644 --- a/Minecraft.World/Blocks/FallingTile.cpp +++ b/Minecraft.World/Blocks/FallingTile.cpp @@ -21,6 +21,7 @@ void FallingTile::_init() { hurtEntities = false; fallDamageMax = 40; fallDamageAmount = 2; + tileData = NULL; // 4J Added so that client-side falling tiles can fall through blocks // This fixes a bug on the host where the tile update from the server comes @@ -58,6 +59,8 @@ FallingTile::FallingTile(Level* level, double x, double y, double z, int tile, zOld = z; } +FallingTile::~FallingTile() { delete tileData; } + bool FallingTile::makeStepSound() { return false; } void FallingTile::defineSynchedData() {} @@ -87,7 +90,7 @@ void FallingTile::tick() { int zt = Mth::floor(z); if (time == 1) { if (level->getTile(xt, yt, zt) == tile) { - level->setTile(xt, yt, zt, 0); + level->removeTile(xt, yt, zt); } else { remove(); return; @@ -99,17 +102,40 @@ void FallingTile::tick() { zd *= 0.7f; yd *= -0.5f; - // if (HeavyTile.isFree(level, xt, yt, zt)) { if (level->getTile(xt, yt, zt) != Tile::pistonMovingPiece_Id) { remove(); if (!cancelDrop && - level->mayPlace(tile, xt, yt, zt, true, 1, nullptr) && + level->mayPlace(tile, xt, yt, zt, true, 1, nullptr, + nullptr) && !HeavyTile::isFree(level, xt, yt - 1, zt) && - level->setTileAndData(xt, yt, zt, tile, data)) { + level->setTileAndData(xt, yt, zt, tile, data, + Tile::UPDATE_ALL)) { HeavyTile* hv = dynamic_cast(Tile::tiles[tile]); if (hv) { hv->onLand(level, xt, yt, zt, data); } + if (tileData != NULL && Tile::tiles[tile]->isEntityTile()) { + std::shared_ptr tileEntity = + level->getTileEntity(xt, yt, zt); + + if (tileEntity != NULL) { + CompoundTag* swap = new CompoundTag(); + tileEntity->save(swap); + std::vector* allTags = tileData->getAllTags(); + for (AUTO_VAR(it, allTags->begin()); + it != allTags->end(); ++it) { + Tag* tag = *it; + if (tag->getName().compare(L"x") == 0 || + tag->getName().compare(L"y") == 0 || + tag->getName().compare(L"z") == 0) + continue; + swap->put(tag->getName(), tag->copy()); + } + delete allTags; + tileEntity->load(swap); + tileEntity->setChanged(); + } + } } else { if (dropItem && !cancelDrop) spawnAtLocation( @@ -123,7 +149,12 @@ void FallingTile::tick() { } else if ((time > 20 * 5 && !level->isClientSide && (yt < 1 || yt > Level::maxBuildHeight)) || (time > 20 * 30)) { - if (dropItem) spawnAtLocation(tile, 1); + if (dropItem) + spawnAtLocation( + std::shared_ptr(new ItemInstance( + tile, 1, + Tile::tiles[tile]->getSpawnResourcesAuxValue(data))), + 0); remove(); } } @@ -133,17 +164,21 @@ void FallingTile::causeFallDamage(float distance) { if (hurtEntities) { int dmg = Mth::ceil(distance - 1); if (dmg > 0) { + // 4J: Copy vector since it might be modified when we hurt the + // entities (invalidating our iterator) std::vector >* entities = - level->getEntities(shared_from_this(), bb); + new std::vector >( + *level->getEntities(shared_from_this(), bb)); DamageSource* source = tile == Tile::anvil_Id ? DamageSource::anvil : DamageSource::fallingBlock; - // for (Entity entity : entities) for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { (*it)->hurt(source, std::min(Mth::floor(dmg * fallDamageAmount), fallDamageMax)); } + delete entities; + if (tile == Tile::anvil_Id && random->nextFloat() < 0.05f + (dmg * 0.05)) { int damage = data >> 2; @@ -161,16 +196,22 @@ void FallingTile::causeFallDamage(float distance) { void FallingTile::addAdditonalSaveData(CompoundTag* tag) { tag->putByte(L"Tile", (uint8_t)tile); + tag->putInt(L"TileID", tile); tag->putByte(L"Data", (uint8_t)data); tag->putByte(L"Time", (uint8_t)time); tag->putBoolean(L"DropItem", dropItem); tag->putBoolean(L"HurtEntities", hurtEntities); tag->putFloat(L"FallHurtAmount", fallDamageAmount); tag->putInt(L"FallHurtMax", fallDamageMax); + if (tileData != NULL) tag->putCompound(L"TileEntityData", tileData); } void FallingTile::readAdditionalSaveData(CompoundTag* tag) { - tile = tag->getByte(L"Tile") & 0xff; + if (tag->contains(L"TileID")) { + tile = tag->getInt(L"TileID"); + } else { + tile = tag->getByte(L"Tile") & 0xff; + } data = tag->getByte(L"Data") & 0xff; time = tag->getByte(L"Time") & 0xff; @@ -186,6 +227,10 @@ void FallingTile::readAdditionalSaveData(CompoundTag* tag) { dropItem = tag->getBoolean(L"DropItem"); } + if (tag->contains(L"TileEntityData")) { + tileData = tag->getCompound(L"TileEntityData"); + } + if (tile == 0) { tile = Tile::sand_Id; } diff --git a/Minecraft.World/Blocks/FallingTile.h b/Minecraft.World/Blocks/FallingTile.h index 165c13abc..d5528412c 100644 --- a/Minecraft.World/Blocks/FallingTile.h +++ b/Minecraft.World/Blocks/FallingTile.h @@ -24,9 +24,12 @@ private: void _init(); public: + CompoundTag* tileData; + FallingTile(Level* level); FallingTile(Level* level, double x, double y, double z, int tile, int data = 0); + ~FallingTile(); protected: virtual bool makeStepSound(); diff --git a/Minecraft.World/Blocks/FarmTile.cpp b/Minecraft.World/Blocks/FarmTile.cpp index 306cc22b7..dce769962 100644 --- a/Minecraft.World/Blocks/FarmTile.cpp +++ b/Minecraft.World/Blocks/FarmTile.cpp @@ -38,14 +38,14 @@ Icon* FarmTile::getTexture(int face, int data) { void FarmTile::tick(Level* level, int x, int y, int z, Random* random) { if (isNearWater(level, x, y, z) || level->isRainingAt(x, y + 1, z)) { - level->setData(x, y, z, 7); + level->setData(x, y, z, 7, Tile::UPDATE_CLIENTS); } else { int moisture = level->getData(x, y, z); if (moisture > 0) { - level->setData(x, y, z, moisture - 1); + level->setData(x, y, z, moisture - 1, Tile::UPDATE_CLIENTS); } else { if (!isUnderCrops(level, x, y, z)) { - level->setTile(x, y, z, Tile::dirt_Id); + level->setTileAndUpdate(x, y, z, Tile::dirt_Id); } } } @@ -58,12 +58,17 @@ void FarmTile::fallOn(Level* level, int x, int y, int z, // the client based on random values! if (!level->isClientSide && level->random->nextFloat() < (fallDistance - .5f)) { - // Fix for #60547 - TU7: Content: Gameplay: Players joining a game can - // destroy crops even with Trust Players option disabled. - std::shared_ptr player = - std::dynamic_pointer_cast(entity); - if (player == NULL || player->isAllowedToMine()) - level->setTile(x, y, z, Tile::dirt_Id); + if (entity->instanceof(eTYPE_PLAYER)) { + std::shared_ptr player = + std::dynamic_pointer_cast(entity); + if (!player->isAllowedToMine()) { + return; + } + } else if (!level->getGameRules()->getBoolean( + GameRules::RULE_MOBGRIEFING)) { + return; + } + level->setTileAndUpdate(x, y, z, Tile::dirt_Id); } } @@ -72,7 +77,7 @@ bool FarmTile::isUnderCrops(Level* level, int x, int y, int z) { for (int xx = x - r; xx <= x + r; xx++) for (int zz = z - r; zz <= z + r; zz++) { int tile = level->getTile(xx, y + 1, zz); - if (tile == Tile::crops_Id || tile == Tile::melonStem_Id || + if (tile == Tile::wheat_Id || tile == Tile::melonStem_Id || tile == Tile::pumpkinStem_Id || tile == Tile::potatoes_Id || tile == Tile::carrots_Id) { return true; @@ -96,7 +101,7 @@ void FarmTile::neighborChanged(Level* level, int x, int y, int z, int type) { Tile::neighborChanged(level, x, y, z, type); Material* above = level->getMaterial(x, y + 1, z); if (above->isSolid()) { - level->setTile(x, y, z, Tile::dirt_Id); + level->setTileAndUpdate(x, y, z, Tile::dirt_Id); } } diff --git a/Minecraft.World/Blocks/FenceGateTile.cpp b/Minecraft.World/Blocks/FenceGateTile.cpp index fc88d2ef7..4a9a11268 100644 --- a/Minecraft.World/Blocks/FenceGateTile.cpp +++ b/Minecraft.World/Blocks/FenceGateTile.cpp @@ -59,9 +59,10 @@ bool FenceGateTile::isPathfindable(LevelSource* level, int x, int y, int z) { int FenceGateTile::getRenderShape() { return Tile::SHAPE_FENCE_GATE; } void FenceGateTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3)) % 4; - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); } bool FenceGateTile::use(Level* level, int x, int y, int z, @@ -80,7 +81,7 @@ bool FenceGateTile::use(Level* level, int x, int y, int z, int data = level->getData(x, y, z); if (isOpen(data)) { - level->setData(x, y, z, data & ~OPEN_BIT); + level->setData(x, y, z, data & ~OPEN_BIT, Tile::UPDATE_CLIENTS); } else { // open the door from the player int dir = (((Mth::floor(player->yRot * 4 / (360) + 0.5)) & 3)) % 4; @@ -88,7 +89,7 @@ bool FenceGateTile::use(Level* level, int x, int y, int z, if (current == ((dir + 2) % 4)) { data = dir; } - level->setData(x, y, z, data | OPEN_BIT); + level->setData(x, y, z, data | OPEN_BIT, Tile::UPDATE_CLIENTS); } level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0); return true; @@ -104,10 +105,10 @@ void FenceGateTile::neighborChanged(Level* level, int x, int y, int z, if (signal || ((type > 0 && Tile::tiles[type]->isSignalSource()) || type == 0)) { if (signal && !isOpen(data)) { - level->setData(x, y, z, data | OPEN_BIT); + level->setData(x, y, z, data | OPEN_BIT, Tile::UPDATE_CLIENTS); level->levelEvent(nullptr, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0); } else if (!signal && isOpen(data)) { - level->setData(x, y, z, data & ~OPEN_BIT); + level->setData(x, y, z, data & ~OPEN_BIT, Tile::UPDATE_CLIENTS); level->levelEvent(nullptr, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0); } } @@ -122,4 +123,4 @@ void FenceGateTile::registerIcons(IconRegister* iconRegister) { bool FenceGateTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { return true; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/FenceGateTile.h b/Minecraft.World/Blocks/FenceGateTile.h index f453909a2..85767bf37 100644 --- a/Minecraft.World/Blocks/FenceGateTile.h +++ b/Minecraft.World/Blocks/FenceGateTile.h @@ -23,7 +23,8 @@ public: int face); virtual int getRenderShape(); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); virtual bool use(Level* level, int x, int y, int z, std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, diff --git a/Minecraft.World/Blocks/FenceTile.cpp b/Minecraft.World/Blocks/FenceTile.cpp index a22c54d30..bbdc24b61 100644 --- a/Minecraft.World/Blocks/FenceTile.cpp +++ b/Minecraft.World/Blocks/FenceTile.cpp @@ -1,6 +1,6 @@ #include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.level.h" -#include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.world.h" #include "FenceTile.h" @@ -9,7 +9,8 @@ FenceTile::FenceTile(int id, const std::wstring& texture, Material* material) this->texture = texture; } -AABB* FenceTile::getAABB(Level* level, int x, int y, int z) { +void FenceTile::addAABBs(Level* level, int x, int y, int z, AABB* box, + AABBList* boxes, std::shared_ptr source) { bool n = connectsTo(level, x, y, z - 1); bool s = connectsTo(level, x, y, z + 1); bool w = connectsTo(level, x - 1, y, z); @@ -26,14 +27,31 @@ AABB* FenceTile::getAABB(Level* level, int x, int y, int z) { if (s) { south = 1; } + if (n || s) { + setShape(west, 0, north, east, 1.5f, south); + Tile::addAABBs(level, x, y, z, box, boxes, source); + } + north = 6.0f / 16.0f; + south = 10.0f / 16.0f; if (w) { west = 0; } if (e) { east = 1; } + if (w || e || (!n && !s)) { + setShape(west, 0, north, east, 1.5f, south); + Tile::addAABBs(level, x, y, z, box, boxes, source); + } - return AABB::newTemp(x + west, y, z + north, x + east, y + 1.5f, z + south); + if (n) { + north = 0; + } + if (s) { + south = 1; + } + + setShape(west, 0, north, east, 1.0f, south); } void FenceTile::updateShape( @@ -67,8 +85,6 @@ void FenceTile::updateShape( setShape(west, 0, north, east, 1.0f, south); } -bool FenceTile::blocksLight() { return false; } - bool FenceTile::isSolidRender(bool isServerLevel) { return false; } bool FenceTile::isCubeShaped() { return false; } @@ -106,3 +122,13 @@ bool FenceTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { return true; } + +bool FenceTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, bool soundOnly) { + if (level->isClientSide) return true; + if (LeashItem::bindPlayerMobs(player, level, x, y, z)) { + return true; + } + return false; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/FenceTile.h b/Minecraft.World/Blocks/FenceTile.h index 030592f06..1645c9bb7 100644 --- a/Minecraft.World/Blocks/FenceTile.h +++ b/Minecraft.World/Blocks/FenceTile.h @@ -8,19 +8,23 @@ private: public: FenceTile(int id, const std::wstring& texture, Material* material); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual void addAABBs(Level* level, int x, int y, int z, AABB* box, + AABBList* boxes, std::shared_ptr source); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< TileEntity>()); // 4J added forceData, forceEntity param - virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); virtual bool isPathfindable(LevelSource* level, int x, int y, int z); virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face); virtual int getRenderShape(); - bool connectsTo(LevelSource* level, int x, int y, int z); + virtual bool connectsTo(LevelSource* level, int x, int y, int z); static bool isFence(int tile); - void registerIcons(IconRegister* iconRegister); + virtual void registerIcons(IconRegister* iconRegister); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/FireTile.cpp b/Minecraft.World/Blocks/FireTile.cpp index 79f0462f4..8b5d45b51 100644 --- a/Minecraft.World/Blocks/FireTile.cpp +++ b/Minecraft.World/Blocks/FireTile.cpp @@ -46,8 +46,10 @@ void FireTile::init() { setFlammable(Tile::bookshelf_Id, FLAME_EASY, BURN_MEDIUM); setFlammable(Tile::tnt_Id, FLAME_MEDIUM, BURN_INSTANT); setFlammable(Tile::tallgrass_Id, FLAME_INSTANT, BURN_INSTANT); - setFlammable(Tile::cloth_Id, FLAME_EASY, BURN_EASY); + setFlammable(Tile::wool_Id, FLAME_EASY, BURN_EASY); setFlammable(Tile::vine_Id, FLAME_MEDIUM, BURN_INSTANT); + setFlammable(Tile::coalBlock_Id, FLAME_HARD, BURN_HARD); + setFlammable(Tile::hayBlock_Id, FLAME_INSTANT, BURN_MEDIUM); } void FireTile::setFlammable(int id, int flame, int burn) { @@ -67,9 +69,13 @@ int FireTile::getRenderShape() { return Tile::SHAPE_FIRE; } int FireTile::getResourceCount(Random* random) { return 0; } -int FireTile::getTickDelay() { return 30; } +int FireTile::getTickDelay(Level* level) { return 30; } void FireTile::tick(Level* level, int x, int y, int z, Random* random) { + if (!level->getGameRules()->getBoolean(GameRules::RULE_DOFIRETICK)) { + return; + } + // 4J added - we don't want fire to do anything that might create new fire, // or destroy this fire, if we aren't actually tracking (for network) the // chunk this is in in the player chunk map. If we did change something in @@ -83,12 +89,12 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) { { if (!MinecraftServer::getInstance()->getPlayers()->isTrackingTile( x, y, z, level->dimension->id)) { - level->addToTickNextTick(x, y, z, id, getTickDelay() * 5); + level->addToTickNextTick(x, y, z, id, getTickDelay(level) * 5); return; } } - bool infiniBurn = level->getTile(x, y - 1, z) == Tile::hellRock_Id; + bool infiniBurn = level->getTile(x, y - 1, z) == Tile::netherRack_Id; if (level->dimension->id == 1) // 4J - was == instanceof TheEndDimension { if (level->getTile(x, y - 1, z) == Tile::unbreakable_Id) @@ -96,7 +102,7 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) { } if (!mayPlace(level, x, y, z)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } if (!infiniBurn && level->isRaining()) { @@ -104,26 +110,28 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) { level->isRainingAt(x + 1, y, z) || level->isRainingAt(x, y, z - 1) || level->isRainingAt(x, y, z + 1)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } } int age = level->getData(x, y, z); if (age < 15) { - level->setDataNoUpdate(x, y, z, age + random->nextInt(3) / 2); + level->setData(x, y, z, age + random->nextInt(3) / 2, + Tile::UPDATE_NONE); } - level->addToTickNextTick(x, y, z, id, getTickDelay() + random->nextInt(10)); + level->addToTickNextTick(x, y, z, id, + getTickDelay(level) + random->nextInt(10)); if (!infiniBurn && !isValidFireLocation(level, x, y, z)) { if (!level->isTopSolidBlocking(x, y - 1, z) || age > 3) - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } if (!infiniBurn && !canBurn(level, x, y - 1, z)) { if (age == 15 && random->nextInt(4) == 0) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } } @@ -152,24 +160,22 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) { int fodds = getFireOdds(level, xx, yy, zz); if (fodds > 0) { - int odds = (fodds + 40) / (age + 30); + int odds = + (fodds + 40 + (level->difficulty * 7)) / (age + 30); if (isHumid) { odds /= 2; } if (odds > 0 && random->nextInt(rate) <= odds) { - if ((level->isRaining() && - level->isRainingAt(xx, yy, zz)) || - level->isRainingAt(xx - 1, yy, z) || - level->isRainingAt(xx + 1, yy, zz) || - level->isRainingAt(xx, yy, zz - 1) || - level->isRainingAt(xx, yy, zz + 1)) { - // DO NOTHING, rain! - - } else { + if (!(level->isRaining() && + level->isRainingAt(xx, yy, zz) || + level->isRainingAt(xx - 1, yy, z) || + level->isRainingAt(xx + 1, yy, zz) || + level->isRainingAt(xx, yy, zz - 1) || + level->isRainingAt(xx, yy, zz + 1))) { int tAge = age + random->nextInt(5) / 4; if (tAge > 15) tAge = 15; - level->setTileAndData(xx, yy, zz, this->id, - tAge); + level->setTileAndData(xx, yy, zz, id, tAge, + Tile::UPDATE_ALL); } } } @@ -179,6 +185,8 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) { } } +bool FireTile::canInstantlyTick() { return false; } + void FireTile::checkBurnOut(Level* level, int x, int y, int z, int chance, Random* random, int age) { int odds = burnOdds[level->getTile(x, y, z)]; @@ -188,9 +196,9 @@ void FireTile::checkBurnOut(Level* level, int x, int y, int z, int chance, app.GetGameHostOption(eGameHostOption_FireSpreads)) { int tAge = age + random->nextInt(5) / 4; if (tAge > 15) tAge = 15; - level->setTileAndData(x, y, z, this->id, tAge); + level->setTileAndData(x, y, z, id, tAge, Tile::UPDATE_ALL); } else { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } if (wasTnt) { Tile::tnt->destroy(level, x, y, z, TntTile::EXPLODE_BIT); @@ -243,7 +251,7 @@ bool FireTile::mayPlace(Level* level, int x, int y, int z) { void FireTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!level->isTopSolidBlocking(x, y - 1, z) && !isValidFireLocation(level, x, y, z)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } } @@ -257,11 +265,11 @@ void FireTile::onPlace(Level* level, int x, int y, int z) { } if (!level->isTopSolidBlocking(x, y - 1, z) && !isValidFireLocation(level, x, y, z)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } level->addToTickNextTick(x, y, z, id, - getTickDelay() + level->random->nextInt(10)); + getTickDelay(level) + level->random->nextInt(10)); } bool FireTile::isFlammable(int tile) { return flameOdds[tile] > 0; } @@ -270,7 +278,7 @@ void FireTile::animateTick(Level* level, int x, int y, int z, Random* random) { if (random->nextInt(24) == 0) { level->playLocalSound(x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_FIRE_FIRE, 1 + random->nextFloat(), - random->nextFloat() * 0.7f + 0.3f); + random->nextFloat() * 0.7f + 0.3f, false); } if (level->isTopSolidBlocking(x, y - 1, z) || diff --git a/Minecraft.World/Blocks/FireTile.h b/Minecraft.World/Blocks/FireTile.h index 8091e5549..260e98d97 100644 --- a/Minecraft.World/Blocks/FireTile.h +++ b/Minecraft.World/Blocks/FireTile.h @@ -45,8 +45,9 @@ public: virtual bool isCubeShaped(); virtual int getRenderShape(); virtual int getResourceCount(Random* random); - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual bool canInstantlyTick(); private: void checkBurnOut(Level* level, int x, int y, int z, int chance, diff --git a/Minecraft.World/Blocks/FlowerPotTile.cpp b/Minecraft.World/Blocks/FlowerPotTile.cpp index d9b06d775..118ae8948 100644 --- a/Minecraft.World/Blocks/FlowerPotTile.cpp +++ b/Minecraft.World/Blocks/FlowerPotTile.cpp @@ -5,7 +5,8 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "FlowerPotTile.h" -FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, false) { +FlowerPotTile::FlowerPotTile(int id) + : Tile(id, Material::decoration, false) { updateDefaultShape(); sendTileData(); } @@ -32,7 +33,7 @@ bool FlowerPotTile::use(Level* level, int x, int y, int z, int type = getTypeFromItem(item); if (type > 0) { - level->setData(x, y, z, type); + level->setData(x, y, z, type, Tile::UPDATE_CLIENTS); if (!player->abilities.instabuild) { if (--item->count <= 0) { @@ -81,7 +82,7 @@ void FlowerPotTile::neighborChanged(Level* level, int x, int y, int z, if (!level->isTopSolidBlocking(x, y - 1, z)) { spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } @@ -111,10 +112,10 @@ std::shared_ptr FlowerPotTile::getItemFromType(int type) { new ItemInstance(Tile::cactus)); case TYPE_MUSHROOM_BROWN: return std::shared_ptr( - new ItemInstance(Tile::mushroom1)); + new ItemInstance(Tile::mushroom_brown)); case TYPE_MUSHROOM_RED: return std::shared_ptr( - new ItemInstance(Tile::mushroom2)); + new ItemInstance(Tile::mushroom_red)); case TYPE_DEAD_BUSH: return std::shared_ptr( new ItemInstance(Tile::deadBush)); @@ -144,8 +145,8 @@ int FlowerPotTile::getTypeFromItem(std::shared_ptr item) { if (id == Tile::rose_Id) return TYPE_FLOWER_RED; if (id == Tile::flower_Id) return TYPE_FLOWER_YELLOW; if (id == Tile::cactus_Id) return TYPE_CACTUS; - if (id == Tile::mushroom1_Id) return TYPE_MUSHROOM_BROWN; - if (id == Tile::mushroom2_Id) return TYPE_MUSHROOM_RED; + if (id == Tile::mushroom_brown_Id) return TYPE_MUSHROOM_BROWN; + if (id == Tile::mushroom_red_Id) return TYPE_MUSHROOM_RED; if (id == Tile::deadBush_Id) return TYPE_DEAD_BUSH; if (id == Tile::sapling_Id) { @@ -169,4 +170,4 @@ int FlowerPotTile::getTypeFromItem(std::shared_ptr item) { } return 0; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/FurnaceTile.cpp b/Minecraft.World/Blocks/FurnaceTile.cpp index 49638f0a7..296fab281 100644 --- a/Minecraft.World/Blocks/FurnaceTile.cpp +++ b/Minecraft.World/Blocks/FurnaceTile.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.inventory.h" #include "../Headers/net.minecraft.world.level.tile.entity.h" #include "../Headers/net.minecraft.world.h" #include "FurnaceTile.h" @@ -11,7 +12,8 @@ bool FurnaceTile::noDrop = false; -FurnaceTile::FurnaceTile(int id, bool lit) : EntityTile(id, Material::stone) { +FurnaceTile::FurnaceTile(int id, bool lit) + : BaseEntityTile(id, Material::stone) { random = new Random(); this->lit = lit; @@ -24,7 +26,7 @@ int FurnaceTile::getResource(int data, Random* random, int playerBonusLevel) { } void FurnaceTile::onPlace(Level* level, int x, int y, int z) { - EntityTile::onPlace(level, x, y, z); + BaseEntityTile::onPlace(level, x, y, z); recalcLockDir(level, x, y, z); } @@ -43,7 +45,7 @@ void FurnaceTile::recalcLockDir(Level* level, int x, int y, int z) { if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2; if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5; if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4; - level->setData(x, y, z, lockDir); + level->setData(x, y, z, lockDir, Tile::UPDATE_CLIENTS); } Icon* FurnaceTile::getTexture(int face, int data) { @@ -114,12 +116,12 @@ void FurnaceTile::setLit(bool lit, Level* level, int x, int y, int z) { noDrop = true; if (lit) - level->setTile(x, y, z, Tile::furnace_lit_Id); + level->setTileAndUpdate(x, y, z, Tile::furnace_lit_Id); else - level->setTile(x, y, z, Tile::furnace_Id); + level->setTileAndUpdate(x, y, z, Tile::furnace_Id); noDrop = false; - level->setData(x, y, z, data); + level->setData(x, y, z, data, Tile::UPDATE_CLIENTS); if (te != NULL) { te->clearRemoved(); level->setTileEntity(x, y, z, te); @@ -131,13 +133,20 @@ std::shared_ptr FurnaceTile::newTileEntity(Level* level) { } void FurnaceTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3; - if (dir == 0) level->setData(x, y, z, Facing::NORTH); - if (dir == 1) level->setData(x, y, z, Facing::EAST); - if (dir == 2) level->setData(x, y, z, Facing::SOUTH); - if (dir == 3) level->setData(x, y, z, Facing::WEST); + if (dir == 0) level->setData(x, y, z, Facing::NORTH, Tile::UPDATE_CLIENTS); + if (dir == 1) level->setData(x, y, z, Facing::EAST, Tile::UPDATE_CLIENTS); + if (dir == 2) level->setData(x, y, z, Facing::SOUTH, Tile::UPDATE_CLIENTS); + if (dir == 3) level->setData(x, y, z, Facing::WEST, Tile::UPDATE_CLIENTS); + + if (itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->setCustomName(itemInstance->getHoverName()); + } } void FurnaceTile::onRemove(Level* level, int x, int y, int z, int id, @@ -192,7 +201,20 @@ void FurnaceTile::onRemove(Level* level, int x, int y, int z, int id, container->setItem(i, nullptr); } } + level->updateNeighbourForOutputSignal(x, y, z, id); } } - EntityTile::onRemove(level, x, y, z, id, data); + BaseEntityTile::onRemove(level, x, y, z, id, data); } + +bool FurnaceTile::hasAnalogOutputSignal() { return true; } + +int FurnaceTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + return AbstractContainerMenu::getRedstoneSignalFromContainer( + std::dynamic_pointer_cast(level->getTileEntity(x, y, z))); +} + +int FurnaceTile::cloneTileId(Level* level, int x, int y, int z) { + return Tile::furnace_Id; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/FurnaceTile.h b/Minecraft.World/Blocks/FurnaceTile.h index c48d16105..9ca91c1bf 100644 --- a/Minecraft.World/Blocks/FurnaceTile.h +++ b/Minecraft.World/Blocks/FurnaceTile.h @@ -1,12 +1,12 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class Mob; class Player; class Random; class ChunkRebuildData; -class FurnaceTile : public EntityTile { +class FurnaceTile : public BaseEntityTile { friend class Tile; friend class ChunkRebuildData; @@ -44,6 +44,12 @@ protected: public: virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + virtual int cloneTileId(Level* level, int x, int y, int z); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/GlowstoneTile.cpp b/Minecraft.World/Blocks/GlowstoneTile.cpp new file mode 100644 index 000000000..ced4026bd --- /dev/null +++ b/Minecraft.World/Blocks/GlowstoneTile.cpp @@ -0,0 +1,19 @@ +#include "../Platform/stdafx.h" +#include "GlowstoneTile.h" +#include "../Headers/net.minecraft.world.item.h" + +Glowstonetile::Glowstonetile(int id, Material* material) : Tile(id, material) {} + +int Glowstonetile::getResourceCountForLootBonus(int bonusLevel, + Random* random) { + return Mth::clamp( + getResourceCount(random) + random->nextInt(bonusLevel + 1), 1, 4); +} + +int Glowstonetile::getResourceCount(Random* random) { + return 2 + random->nextInt(3); +} + +int Glowstonetile::getResource(int data, Random* random, int playerBonusLevel) { + return Item::yellowDust->id; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/LightGemTile.h b/Minecraft.World/Blocks/GlowstoneTile.h similarity index 75% rename from Minecraft.World/Blocks/LightGemTile.h rename to Minecraft.World/Blocks/GlowstoneTile.h index f6d50d463..373c63dd4 100644 --- a/Minecraft.World/Blocks/LightGemTile.h +++ b/Minecraft.World/Blocks/GlowstoneTile.h @@ -3,9 +3,9 @@ class Random; -class LightGemTile : public Tile { +class Glowstonetile : public Tile { public: - LightGemTile(int id, Material* material); + Glowstonetile(int id, Material* material); virtual int getResourceCountForLootBonus(int bonusLevel, Random* random); virtual int getResourceCount(Random* random); virtual int getResource(int data, Random* random, int playerBonusLevel); diff --git a/Minecraft.World/Blocks/GrassTile.cpp b/Minecraft.World/Blocks/GrassTile.cpp index 5494b429f..01f95c9a7 100644 --- a/Minecraft.World/Blocks/GrassTile.cpp +++ b/Minecraft.World/Blocks/GrassTile.cpp @@ -87,7 +87,7 @@ void GrassTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getRawBrightness(x, y + 1, z) < MIN_BRIGHTNESS && Tile::lightBlock[level->getTile(x, y + 1, z)] > 2) { - level->setTile(x, y, z, Tile::dirt_Id); + level->setTileAndUpdate(x, y, z, Tile::dirt_Id); } else { if (level->getRawBrightness(x, y + 1, z) >= Level::MAX_BRIGHTNESS - 6) { for (int i = 0; i < 4; i++) { @@ -98,7 +98,7 @@ void GrassTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getTile(xt, yt, zt) == Tile::dirt_Id && level->getRawBrightness(xt, yt + 1, zt) >= MIN_BRIGHTNESS && Tile::lightBlock[above] <= 2) { - level->setTile(xt, yt, zt, Tile::grass_Id); + level->setTileAndUpdate(xt, yt, zt, Tile::grass_Id); } } } diff --git a/Minecraft.World/Blocks/GravelTile.cpp b/Minecraft.World/Blocks/GravelTile.cpp index 4441a5639..c67d89c6b 100644 --- a/Minecraft.World/Blocks/GravelTile.cpp +++ b/Minecraft.World/Blocks/GravelTile.cpp @@ -5,6 +5,7 @@ GravelTile::GravelTile(int type) : HeavyTile(type) {} int GravelTile::getResource(int data, Random* random, int playerBonusLevel) { + if (playerBonusLevel > 3) playerBonusLevel = 3; if (random->nextInt(10 - playerBonusLevel * 3) == 0) return Item::flint->id; return id; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/HalfSlabTile.cpp b/Minecraft.World/Blocks/HalfSlabTile.cpp index b9272322f..7cb6e3eab 100644 --- a/Minecraft.World/Blocks/HalfSlabTile.cpp +++ b/Minecraft.World/Blocks/HalfSlabTile.cpp @@ -6,16 +6,6 @@ #include "../Headers/net.minecraft.stats.h" #include "../Util/Facing.h" -/*package net.minecraft.world.level.tile; - -import java.util.*; - -import net.minecraft.Facing; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.*; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.AABB;*/ - HalfSlabTile::HalfSlabTile(int id, bool fullSize, Material* material) : Tile(id, material, fullSize) { this->fullSize = fullSize; @@ -119,3 +109,20 @@ bool HalfSlabTile::shouldRenderFace(LevelSource* level, int x, int y, int z, bool HalfSlabTile::isHalfSlab(int tileId) { return tileId == Tile::stoneSlabHalf_Id || tileId == Tile::woodSlabHalf_Id; } + +int HalfSlabTile::cloneTileData(Level* level, int x, int y, int z) { + return Tile::cloneTileData(level, x, y, z) & TYPE_MASK; +} + +int HalfSlabTile::cloneTileId(Level* level, int x, int y, int z) { + if (isHalfSlab(id)) { + return id; + } + if (id == Tile::stoneSlab_Id) { + return Tile::stoneSlabHalf_Id; + } + if (id == Tile::woodSlab_Id) { + return Tile::woodSlabHalf_Id; + } + return Tile::stoneSlabHalf_Id; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/HalfSlabTile.h b/Minecraft.World/Blocks/HalfSlabTile.h index 67ca7cd2e..d2e87a648 100644 --- a/Minecraft.World/Blocks/HalfSlabTile.h +++ b/Minecraft.World/Blocks/HalfSlabTile.h @@ -34,4 +34,7 @@ private: public: virtual int getAuxName(int auxValue) = 0; + + virtual int cloneTileData(Level* level, int x, int y, int z); + virtual int cloneTileId(Level* level, int x, int y, int z); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/HalfTransparentTile.cpp b/Minecraft.World/Blocks/HalfTransparentTile.cpp index 762e0ba11..81a60b33d 100644 --- a/Minecraft.World/Blocks/HalfTransparentTile.cpp +++ b/Minecraft.World/Blocks/HalfTransparentTile.cpp @@ -23,4 +23,4 @@ bool HalfTransparentTile::blocksLight() { return false; } void HalfTransparentTile::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(texture); -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/HalfTransparentTile.h b/Minecraft.World/Blocks/HalfTransparentTile.h index 062f2d6dd..bb0a5550b 100644 --- a/Minecraft.World/Blocks/HalfTransparentTile.h +++ b/Minecraft.World/Blocks/HalfTransparentTile.h @@ -19,5 +19,5 @@ public: virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face); virtual bool blocksLight(); - void registerIcons(IconRegister* iconRegister); + virtual void registerIcons(IconRegister* iconRegister); }; diff --git a/Minecraft.World/Blocks/HayBlockTile.cpp b/Minecraft.World/Blocks/HayBlockTile.cpp new file mode 100644 index 000000000..9ceba51d8 --- /dev/null +++ b/Minecraft.World/Blocks/HayBlockTile.cpp @@ -0,0 +1,14 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.h" +#include "HayBlockTile.h" + +HayBlockTile::HayBlockTile(int id) : RotatedPillarTile(id, Material::grass) {} + +int HayBlockTile::getRenderShape() { return SHAPE_TREE; } + +Icon* HayBlockTile::getTypeTexture(int type) { return icon; } + +void HayBlockTile::registerIcons(IconRegister* iconRegister) { + iconTop = iconRegister->registerIcon(getIconName() + L"_top"); + icon = iconRegister->registerIcon(getIconName() + L"_side"); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/HayBlockTile.h b/Minecraft.World/Blocks/HayBlockTile.h new file mode 100644 index 000000000..8ca1d4b53 --- /dev/null +++ b/Minecraft.World/Blocks/HayBlockTile.h @@ -0,0 +1,18 @@ +#pragma once + +#include "RotatedPillarTile.h" + +class HayBlockTile : public RotatedPillarTile { + friend class ChunkRebuildData; + +public: + HayBlockTile(int id); + + int getRenderShape(); + +protected: + Icon* getTypeTexture(int type); + +public: + void registerIcons(IconRegister* iconRegister); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/HeavyTile.cpp b/Minecraft.World/Blocks/HeavyTile.cpp index f03f37410..9b06fbcd2 100644 --- a/Minecraft.World/Blocks/HeavyTile.cpp +++ b/Minecraft.World/Blocks/HeavyTile.cpp @@ -13,11 +13,11 @@ HeavyTile::HeavyTile(int type, Material* material, bool isSolidRender) : Tile(type, material, isSolidRender) {} void HeavyTile::onPlace(Level* level, int x, int y, int z) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } void HeavyTile::neighborChanged(Level* level, int x, int y, int z, int type) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } void HeavyTile::tick(Level* level, int x, int y, int z, Random* random) { @@ -35,16 +35,16 @@ void HeavyTile::checkSlide(Level* level, int x, int y, int z) { if (instaFall || !level->hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); while (isFree(level, x, y - 1, z) && y > 0) y--; if (y > 0) { - level->setTile(x, y, z, id); + level->setTileAndUpdate(x, y, z, id); } } else if (!level->isClientSide) { // 4J added - don't do anything just now if we can't create any new // falling tiles if (!level->newFallingTileAllowed()) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); return; } @@ -59,7 +59,7 @@ void HeavyTile::checkSlide(Level* level, int x, int y, int z) { void HeavyTile::falling(std::shared_ptr entity) {} -int HeavyTile::getTickDelay() { return 5; } +int HeavyTile::getTickDelay(Level* level) { return 2; } bool HeavyTile::isFree(Level* level, int x, int y, int z) { int t = level->getTile(x, y, z); diff --git a/Minecraft.World/Blocks/HeavyTile.h b/Minecraft.World/Blocks/HeavyTile.h index a75421846..1c68de588 100644 --- a/Minecraft.World/Blocks/HeavyTile.h +++ b/Minecraft.World/Blocks/HeavyTile.h @@ -22,7 +22,7 @@ protected: virtual void falling(std::shared_ptr entity); public: - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); static bool isFree(Level* level, int x, int y, int z); virtual void onLand(Level* level, int xt, int yt, int zt, int data); }; diff --git a/Minecraft.World/Blocks/HellStoneTile.cpp b/Minecraft.World/Blocks/HellStoneTile.cpp deleted file mode 100644 index d02a3c920..000000000 --- a/Minecraft.World/Blocks/HellStoneTile.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "../Platform/stdafx.h" -#include "HellStoneTile.h" - -HellStoneTile::HellStoneTile(int id) : Tile(id, Material::stone) {} \ No newline at end of file diff --git a/Minecraft.World/Blocks/HellStoneTile.h b/Minecraft.World/Blocks/HellStoneTile.h deleted file mode 100644 index 7bc3874e0..000000000 --- a/Minecraft.World/Blocks/HellStoneTile.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "Tile.h" - -class HellStoneTile : public Tile { -public: - HellStoneTile(int id); -}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/HopperTile.cpp b/Minecraft.World/Blocks/HopperTile.cpp new file mode 100644 index 000000000..a4c6f4319 --- /dev/null +++ b/Minecraft.World/Blocks/HopperTile.cpp @@ -0,0 +1,189 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.entity.item.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.inventory.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "../Headers/net.minecraft.world.h" +#include "HopperTile.h" + +const std::wstring HopperTile::TEXTURE_OUTSIDE = L"hopper_outside"; +const std::wstring HopperTile::TEXTURE_INSIDE = L"hopper_inside"; + +HopperTile::HopperTile(int id) + : BaseEntityTile(id, Material::metal, false) { + setShape(0, 0, 0, 1, 1, 1); +} + +void HopperTile::updateShape(LevelSource* level, int x, int y, int z, + int forceData, + std::shared_ptr forceEntity) { + setShape(0, 0, 0, 1, 1, 1); +} + +void HopperTile::addAABBs(Level* level, int x, int y, int z, AABB* box, + AABBList* boxes, std::shared_ptr source) { + setShape(0, 0, 0, 1, 10.0f / 16.0f, 1); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); + float thickness = 2.0f / 16.0f; + setShape(0, 0, 0, thickness, 1, 1); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); + setShape(0, 0, 0, 1, 1, thickness); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); + setShape(1 - thickness, 0, 0, 1, 1, 1); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); + setShape(0, 0, 1 - thickness, 1, 1, 1); + BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source); + + setShape(0, 0, 0, 1, 1, 1); +} + +int HopperTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, + int face, float clickX, float clickY, + float clickZ, int itemValue) { + int attached = Facing::OPPOSITE_FACING[face]; + if (attached == Facing::UP) attached = Facing::DOWN; + return attached; +} + +std::shared_ptr HopperTile::newTileEntity(Level* level) { + return std::shared_ptr(new HopperTileEntity()); +} + +void HopperTile::setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance) { + BaseEntityTile::setPlacedBy(level, x, y, z, by, itemInstance); + + if (itemInstance->hasCustomHoverName()) { + std::shared_ptr hopper = getHopper(level, x, y, z); + hopper->setCustomName(itemInstance->getHoverName()); + } +} + +void HopperTile::onPlace(Level* level, int x, int y, int z) { + BaseEntityTile::onPlace(level, x, y, z); + checkPoweredState(level, x, y, z); +} + +bool HopperTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, bool soundOnly) { + if (level->isClientSide) { + return true; + } + std::shared_ptr hopper = getHopper(level, x, y, z); + if (hopper != NULL) player->openHopper(hopper); + return true; +} + +void HopperTile::neighborChanged(Level* level, int x, int y, int z, int type) { + checkPoweredState(level, x, y, z); +} + +void HopperTile::checkPoweredState(Level* level, int x, int y, int z) { + int data = level->getData(x, y, z); + int attachedFace = getAttachedFace(data); + bool shouldBeOn = !level->hasNeighborSignal(x, y, z); + bool isOn = isTurnedOn(data); + + if (shouldBeOn != isOn) { + level->setData(x, y, z, attachedFace | (shouldBeOn ? 0 : MASK_TOGGLE), + UPDATE_NONE); + } +} + +void HopperTile::onRemove(Level* level, int x, int y, int z, int id, int data) { + std::shared_ptr container = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + if (container != NULL) { + for (int i = 0; i < container->getContainerSize(); i++) { + std::shared_ptr item = container->getItem(i); + if (item != NULL) { + float xo = random.nextFloat() * 0.8f + 0.1f; + float yo = random.nextFloat() * 0.8f + 0.1f; + float zo = random.nextFloat() * 0.8f + 0.1f; + + while (item->count > 0) { + int count = random.nextInt(21) + 10; + if (count > item->count) count = item->count; + item->count -= count; + + std::shared_ptr itemEntity = + std::shared_ptr(new ItemEntity( + level, x + xo, y + yo, z + zo, + std::shared_ptr(new ItemInstance( + item->id, count, item->getAuxValue())))); + + if (item->hasTag()) { + itemEntity->getItem()->setTag( + (CompoundTag*)item->getTag()->copy()); + } + + float pow = 0.05f; + itemEntity->xd = (float)random.nextGaussian() * pow; + itemEntity->yd = (float)random.nextGaussian() * pow + 0.2f; + itemEntity->zd = (float)random.nextGaussian() * pow; + level->addEntity(itemEntity); + } + } + } + level->updateNeighbourForOutputSignal(x, y, z, id); + } + + BaseEntityTile::onRemove(level, x, y, z, id, data); +} + +int HopperTile::getRenderShape() { return SHAPE_HOPPER; } + +bool HopperTile::isCubeShaped() { return false; } + +bool HopperTile::isSolidRender(bool isServerLevel /*= false*/) { return false; } + +bool HopperTile::shouldRenderFace(LevelSource* level, int x, int y, int z, + int face) { + return true; +} + +Icon* HopperTile::getTexture(int face, int data) { + if (face == Facing::UP) { + return hopperTopIcon; + } + return hopperIcon; +} + +int HopperTile::getAttachedFace(int data) { return data & MASK_ATTACHED; } + +bool HopperTile::isTurnedOn(int data) { + return (data & MASK_TOGGLE) != MASK_TOGGLE; +} + +bool HopperTile::hasAnalogOutputSignal() { return true; } + +int HopperTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + return AbstractContainerMenu::getRedstoneSignalFromContainer( + getHopper(level, x, y, z)); +} + +void HopperTile::registerIcons(IconRegister* iconRegister) { + hopperIcon = iconRegister->registerIcon(TEXTURE_OUTSIDE); + hopperTopIcon = iconRegister->registerIcon(L"hopper_top"); + hopperInnerIcon = iconRegister->registerIcon(TEXTURE_INSIDE); +} + +Icon* HopperTile::getTexture(const std::wstring& name) { + if (name.compare(TEXTURE_OUTSIDE) == 0) return Tile::hopper->hopperIcon; + if (name.compare(TEXTURE_INSIDE) == 0) return Tile::hopper->hopperInnerIcon; + return NULL; +} + +std::wstring HopperTile::getTileItemIconName() { return L"hopper"; } + +std::shared_ptr HopperTile::getHopper(LevelSource* level, + int x, int y, int z) { + return std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/HopperTile.h b/Minecraft.World/Blocks/HopperTile.h new file mode 100644 index 000000000..cf0a47cbf --- /dev/null +++ b/Minecraft.World/Blocks/HopperTile.h @@ -0,0 +1,70 @@ +#pragma once + +#include "BaseEntityTile.h" + +class HopperTileEntity; + +class HopperTile : public BaseEntityTile { + friend class ChunkRebuildData; + +private: + static const int MASK_TOGGLE = 0x8; + static const int MASK_ATTACHED = 0x7; + +public: + static const std::wstring TEXTURE_OUTSIDE; + static const std::wstring TEXTURE_INSIDE; + +private: + Random random; + +private: + Icon* hopperIcon; + Icon* hopperTopIcon; + Icon* hopperInnerIcon; + +public: + HopperTile(int id); + + virtual void updateShape(LevelSource* level, int x, int y, int z, + int forceData = -1, + std::shared_ptr forceEntity = + std::shared_ptr()); + virtual void addAABBs(Level* level, int x, int y, int z, AABB* box, + AABBList* boxes, std::shared_ptr source); + virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, + int face, float clickX, float clickY, + float clickZ, int itemValue); + virtual std::shared_ptr newTileEntity(Level* level); + virtual void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); + virtual void onPlace(Level* level, int x, int y, int z); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + +private: + virtual void checkPoweredState(Level* level, int x, int y, int z); + +public: + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + virtual int getRenderShape(); + virtual bool isCubeShaped(); + virtual bool isSolidRender(bool isServerLevel = false); + virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, + int face); + virtual Icon* getTexture(int face, int data); + static int getAttachedFace(int data); + static bool isTurnedOn(int data); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + virtual void registerIcons(IconRegister* iconRegister); + static Icon* getTexture(const std::wstring& name); + virtual std::wstring getTileItemIconName(); + static std::shared_ptr getHopper(LevelSource* level, + int x, int y, int z); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/HugeMushroomTile.cpp b/Minecraft.World/Blocks/HugeMushroomTile.cpp index 7bfbb4a26..039816c8e 100644 --- a/Minecraft.World/Blocks/HugeMushroomTile.cpp +++ b/Minecraft.World/Blocks/HugeMushroomTile.cpp @@ -2,10 +2,10 @@ #include "../Headers/net.minecraft.world.h" #include "HugeMushroomTile.h" -const std::wstring HugeMushroomTile::TEXTURE_STEM = L"mushroom_skin_stem"; -const std::wstring HugeMushroomTile::TEXTURE_INSIDE = L"mushroom_inside"; -const std::wstring HugeMushroomTile::TEXTURE_TYPE[] = {L"mushroom_skin_brown", - L"mushroom_skin_red"}; +const std::wstring HugeMushroomTile::TEXTURE_STEM = L"skin_stem"; +const std::wstring HugeMushroomTile::TEXTURE_INSIDE = L"inside"; +const std::wstring HugeMushroomTile::TEXTURE_TYPE[] = {L"skin_brown", + L"skin_red"}; HugeMushroomTile::HugeMushroomTile(int id, Material* material, int type) : Tile(id, material) { @@ -46,20 +46,22 @@ int HugeMushroomTile::getResourceCount(Random* random) { int HugeMushroomTile::getResource(int data, Random* random, int playerBonusLevel) { - return Tile::mushroom1_Id + type; + return Tile::mushroom_brown_Id + type; } int HugeMushroomTile::cloneTileId(Level* level, int x, int y, int z) { - return Tile::mushroom1_Id + type; + return Tile::mushroom_brown_Id + type; } void HugeMushroomTile::registerIcons(IconRegister* iconRegister) { icons = new Icon*[HUGE_MUSHROOM_TEXTURE_COUNT]; for (int i = 0; i < HUGE_MUSHROOM_TEXTURE_COUNT; i++) { - icons[i] = iconRegister->registerIcon(TEXTURE_TYPE[i]); + icons[i] = + iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_TYPE[i]); } - iconInside = iconRegister->registerIcon(TEXTURE_INSIDE); - iconStem = iconRegister->registerIcon(TEXTURE_STEM); + iconInside = + iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_INSIDE); + iconStem = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_STEM); } \ No newline at end of file diff --git a/Minecraft.World/Blocks/HugeMushroomTile.h b/Minecraft.World/Blocks/HugeMushroomTile.h index d5da64f59..5cb449008 100644 --- a/Minecraft.World/Blocks/HugeMushroomTile.h +++ b/Minecraft.World/Blocks/HugeMushroomTile.h @@ -6,6 +6,9 @@ class HugeMushroomTile : public Tile { friend class ChunkRebuildData; public: + static const int MUSHROOM_TYPE_BROWN = 0; + static const int MUSHROOM_TYPE_RED = 1; + static const std::wstring TEXTURE_STEM; static const std::wstring TEXTURE_INSIDE; diff --git a/Minecraft.World/Blocks/IceTile.cpp b/Minecraft.World/Blocks/IceTile.cpp index f3f3f4092..37c08ed2a 100644 --- a/Minecraft.World/Blocks/IceTile.cpp +++ b/Minecraft.World/Blocks/IceTile.cpp @@ -25,24 +25,22 @@ void IceTile::playerDestroy(Level* level, std::shared_ptr player, int x, GenericStats::param_blocksMined(id, data, 1)); player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); - if (isSilkTouchable() && - EnchantmentHelper::hasSilkTouch(player->inventory)) { + if (isSilkTouchable() && EnchantmentHelper::hasSilkTouch(player)) { std::shared_ptr item = getSilkTouchItemInstance(data); if (item != NULL) { popResource(level, x, y, z, item); } } else { if (level->dimension->ultraWarm) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } - int playerBonusLevel = - EnchantmentHelper::getDiggingLootBonus(player->inventory); + int playerBonusLevel = EnchantmentHelper::getDiggingLootBonus(player); spawnResources(level, x, y, z, data, playerBonusLevel); Material* below = level->getMaterial(x, y - 1, z); if (below->blocksMotion() || below->isLiquid()) { - level->setTile(x, y, z, Tile::water_Id); + level->setTileAndUpdate(x, y, z, Tile::water_Id); } } } @@ -53,11 +51,11 @@ void IceTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getBrightness(LightLayer::Block, x, y, z) > 11 - Tile::lightBlock[id]) { if (level->dimension->ultraWarm) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, Tile::calmWater_Id); + level->setTileAndUpdate(x, y, z, Tile::calmWater_Id); } } diff --git a/Minecraft.World/Blocks/JukeboxTile.cpp b/Minecraft.World/Blocks/JukeboxTile.cpp new file mode 100644 index 000000000..0abc7fbe1 --- /dev/null +++ b/Minecraft.World/Blocks/JukeboxTile.cpp @@ -0,0 +1,159 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.entity.item.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.h" +#include "JukeboxTile.h" +#include "../Level/Events/LevelEvent.h" + +JukeboxTile::Entity::Entity() : TileEntity() { record = nullptr; } + +void JukeboxTile::Entity::load(CompoundTag* tag) { + TileEntity::load(tag); + + if (tag->contains(L"RecordItem")) { + setRecord(ItemInstance::fromTag(tag->getCompound(L"RecordItem"))); + } else if (tag->getInt(L"Record") > 0) { + setRecord(std::shared_ptr( + new ItemInstance(tag->getInt(L"Record"), 1, 0))); + } +} + +void JukeboxTile::Entity::save(CompoundTag* tag) { + TileEntity::save(tag); + + if (getRecord() != NULL) { + tag->putCompound(L"RecordItem", getRecord()->save(new CompoundTag())); + + tag->putInt(L"Record", getRecord()->id); + } +} + +// 4J Added +std::shared_ptr JukeboxTile::Entity::clone() { + std::shared_ptr result = + std::shared_ptr(new JukeboxTile::Entity()); + TileEntity::clone(result); + + result->record = record; + + return result; +} + +std::shared_ptr JukeboxTile::Entity::getRecord() { + return record; +} + +void JukeboxTile::Entity::setRecord(std::shared_ptr record) { + this->record = record; + setChanged(); +} + +JukeboxTile::JukeboxTile(int id) : BaseEntityTile(id, Material::wood) { + iconTop = NULL; +} + +Icon* JukeboxTile::getTexture(int face, int data) { + if (face == Facing::UP) { + return iconTop; + } + return icon; +} + +// 4J-PB - Adding a TestUse for tooltip display +bool JukeboxTile::TestUse(Level* level, int x, int y, int z, + std::shared_ptr player) { + // if the jukebox is empty, return true + if (level->getData(x, y, z) == 0) return false; + return true; +} + +bool JukeboxTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly /*=false*/) // 4J added soundOnly param +{ + if (soundOnly) return false; + if (level->getData(x, y, z) == 0) return false; + dropRecording(level, x, y, z); + return true; +} + +void JukeboxTile::setRecord(Level* level, int x, int y, int z, + std::shared_ptr record) { + if (level->isClientSide) return; + + std::shared_ptr rte = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + rte->setRecord(record->copy()); + rte->setChanged(); + + level->setData(x, y, z, 1, Tile::UPDATE_CLIENTS); +} + +void JukeboxTile::dropRecording(Level* level, int x, int y, int z) { + if (level->isClientSide) return; + + std::shared_ptr rte = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)); + if (rte == NULL) return; + + std::shared_ptr oldRecord = rte->getRecord(); + if (oldRecord == NULL) return; + + level->levelEvent(LevelEvent::SOUND_PLAY_RECORDING, x, y, z, 0); + // 4J-PB- the level event will play the music + // level->playStreamingMusic(L"", x, y, z); + rte->setRecord(nullptr); + rte->setChanged(); + level->setData(x, y, z, 0, Tile::UPDATE_CLIENTS); + + float s = 0.7f; + double xo = level->random->nextFloat() * s + (1 - s) * 0.5; + double yo = level->random->nextFloat() * s + (1 - s) * 0.2 + 0.6; + double zo = level->random->nextFloat() * s + (1 - s) * 0.5; + + std::shared_ptr itemInstance = oldRecord->copy(); + + std::shared_ptr item = std::shared_ptr( + new ItemEntity(level, x + xo, y + yo, z + zo, itemInstance)); + item->throwTime = 10; + level->addEntity(item); +} + +void JukeboxTile::onRemove(Level* level, int x, int y, int z, int id, + int data) { + dropRecording(level, x, y, z); + Tile::onRemove(level, x, y, z, id, data); +} + +void JukeboxTile::spawnResources(Level* level, int x, int y, int z, int data, + float odds, int playerBonus) { + if (level->isClientSide) return; + Tile::spawnResources(level, x, y, z, data, odds, 0); +} + +std::shared_ptr JukeboxTile::newTileEntity(Level* level) { + return std::shared_ptr(new JukeboxTile::Entity()); +} + +void JukeboxTile::registerIcons(IconRegister* iconRegister) { + icon = iconRegister->registerIcon(getIconName() + L"_side"); + iconTop = iconRegister->registerIcon(getIconName() + L"_top"); +} + +bool JukeboxTile::hasAnalogOutputSignal() { return true; } + +int JukeboxTile::getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir) { + std::shared_ptr record = + std::dynamic_pointer_cast( + level->getTileEntity(x, y, z)) + ->getRecord(); + return record == NULL ? Redstone::SIGNAL_NONE + : record->id + 1 - Item::record_01_Id; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/JukeboxTile.h b/Minecraft.World/Blocks/JukeboxTile.h new file mode 100644 index 000000000..d3fa9603f --- /dev/null +++ b/Minecraft.World/Blocks/JukeboxTile.h @@ -0,0 +1,61 @@ +#pragma once + +#include "BaseEntityTile.h" +#include "../IO/NBT/CompoundTag.h" +#include "TileEntities/TileEntity.h" + +class CompoundTag; +class ChunkRebuildData; + +class JukeboxTile : public BaseEntityTile { + friend class Tile; + friend class ChunkRebuildData; + +public: + class Entity : public TileEntity { + public: + eINSTANCEOF GetType() { return eTYPE_RECORDPLAYERTILE; } + static TileEntity* create() { return new JukeboxTile::Entity(); } + + private: + std::shared_ptr record; + + public: + Entity(); + + virtual void load(CompoundTag* tag); + virtual void save(CompoundTag* tag); + virtual std::shared_ptr getRecord(); + virtual void setRecord(std::shared_ptr record); + + // 4J Added + std::shared_ptr clone(); + }; + +private: + Icon* iconTop; + +protected: + JukeboxTile(int id); + +public: + virtual Icon* getTexture(int face, int data); + virtual bool TestUse(Level* level, int x, int y, int z, + std::shared_ptr player); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); // 4J added soundOnly param + void setRecord(Level* level, int x, int y, int z, + std::shared_ptr record); + void dropRecording(Level* level, int x, int y, int z); + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + virtual void spawnResources(Level* level, int x, int y, int z, int data, + float odds, int playerBonus); + + virtual std::shared_ptr newTileEntity(Level* level); + virtual void registerIcons(IconRegister* iconRegister); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); +}; diff --git a/Minecraft.World/Blocks/LadderTile.cpp b/Minecraft.World/Blocks/LadderTile.cpp index 718b38861..ac0595ea5 100644 --- a/Minecraft.World/Blocks/LadderTile.cpp +++ b/Minecraft.World/Blocks/LadderTile.cpp @@ -2,7 +2,8 @@ #include "../Headers/net.minecraft.world.level.h" #include "LadderTile.h" -LadderTile::LadderTile(int id) : Tile(id, Material::decoration, false) {} +LadderTile::LadderTile(int id) + : Tile(id, Material::decoration, false) {} AABB* LadderTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); @@ -80,10 +81,10 @@ void LadderTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (face == 5 && level->isSolidBlockingTile(x - 1, y, z)) ok = true; if (!ok) { spawnResources(level, x, y, z, face, 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } Tile::neighborChanged(level, x, y, z, type); } -int LadderTile::getResourceCount(Random* random) { return 1; } +int LadderTile::getResourceCount(Random* random) { return 1; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/LeafTile.cpp b/Minecraft.World/Blocks/LeafTile.cpp index 437269be3..e4c158500 100644 --- a/Minecraft.World/Blocks/LeafTile.cpp +++ b/Minecraft.World/Blocks/LeafTile.cpp @@ -100,8 +100,9 @@ void LeafTile::onRemove(Level* level, int x, int y, int z, int id, int data) { if (t == Tile::leaves_Id) { int currentData = level->getData(x + xo, y + yo, z + zo); - level->setDataNoUpdate(x + xo, y + yo, z + zo, - currentData | UPDATE_LEAF_BIT); + level->setData(x + xo, y + yo, z + zo, + currentData | UPDATE_LEAF_BIT, + Tile::UPDATE_NONE); } } } @@ -113,7 +114,7 @@ void LeafTile::tick(Level* level, int x, int y, int z, Random* random) { int currentData = level->getData(x, y, z); if ((currentData & UPDATE_LEAF_BIT) != 0 && (currentData & PERSISTENT_LEAF_BIT) == 0) { - int r = LeafTile::REQUIRED_WOOD_RANGE; + int r = REQUIRED_WOOD_RANGE; int r2 = r + 1; int W = 32; @@ -143,7 +144,7 @@ void LeafTile::tick(Level* level, int x, int y, int z, Random* random) { (zo + WO)] = -1; } } - for (int i = 1; i <= LeafTile::REQUIRED_WOOD_RANGE; i++) { + for (int i = 1; i <= REQUIRED_WOOD_RANGE; i++) { for (int xo = -r; xo <= r; xo++) for (int yo = -r; yo <= r; yo++) for (int zo = -r; zo <= r; zo++) { @@ -192,7 +193,8 @@ void LeafTile::tick(Level* level, int x, int y, int z, Random* random) { int mid = checkBuffer[(WO)*WW + (WO)*W + (WO)]; if (mid >= 0) { - level->setDataNoUpdate(x, y, z, currentData & ~UPDATE_LEAF_BIT); + level->setData(x, y, z, currentData & ~UPDATE_LEAF_BIT, + Tile::UPDATE_NONE); } else { die(level, x, y, z); } @@ -212,7 +214,7 @@ void LeafTile::animateTick(Level* level, int x, int y, int z, Random* random) { void LeafTile::die(Level* level, int x, int y, int z) { Tile::spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } int LeafTile::getResourceCount(Random* random) { @@ -231,6 +233,12 @@ void LeafTile::spawnResources(Level* level, int x, int y, int z, int data, if ((data & LEAF_TYPE_MASK) == JUNGLE_LEAF) { chance = 40; } + if (playerBonusLevel > 0) { + chance -= 2 << playerBonusLevel; + if (chance < 10) { + chance = 10; + } + } if (level->random->nextInt(chance) == 0) { int type = getResource(data, level->random, playerBonusLevel); popResource(level, x, y, z, @@ -238,8 +246,15 @@ void LeafTile::spawnResources(Level* level, int x, int y, int z, int data, type, 1, getSpawnResourcesAuxValue(data)))); } + chance = 200; + if (playerBonusLevel > 0) { + chance -= 10 << playerBonusLevel; + if (chance < 40) { + chance = 40; + } + } if ((data & LEAF_TYPE_MASK) == NORMAL_LEAF && - level->random->nextInt(200) == 0) { + level->random->nextInt(chance) == 0) { popResource(level, x, y, z, std::shared_ptr( new ItemInstance(Item::apple_Id, 1, 0))); @@ -282,6 +297,9 @@ Icon* LeafTile::getTexture(int face, int data) { if ((data & LEAF_TYPE_MASK) == JUNGLE_LEAF) { return icons[fancyTextureSet][JUNGLE_LEAF]; } + if ((data & LEAF_TYPE_MASK) == BIRCH_LEAF) { + return icons[fancyTextureSet][BIRCH_LEAF]; + } return icons[fancyTextureSet][0]; } diff --git a/Minecraft.World/Blocks/LeverTile.cpp b/Minecraft.World/Blocks/LeverTile.cpp index 2523c36c7..e44a69ac3 100644 --- a/Minecraft.World/Blocks/LeverTile.cpp +++ b/Minecraft.World/Blocks/LeverTile.cpp @@ -1,10 +1,11 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.h" #include "LeverTile.h" -#include "../Util/SoundTypes.h" -LeverTile::LeverTile(int id) : Tile(id, Material::decoration, false) {} +LeverTile::LeverTile(int id) + : Tile(id, Material::decoration, false) {} AABB* LeverTile::getAABB(Level* level, int x, int y, int z) { return NULL; } @@ -17,12 +18,18 @@ bool LeverTile::isCubeShaped() { return false; } int LeverTile::getRenderShape() { return Tile::SHAPE_LEVER; } bool LeverTile::mayPlace(Level* level, int x, int y, int z, int face) { - if (face == 0 && level->isSolidBlockingTile(x, y + 1, z)) return true; - if (face == 1 && level->isTopSolidBlocking(x, y - 1, z)) return true; - if (face == 2 && level->isSolidBlockingTile(x, y, z + 1)) return true; - if (face == 3 && level->isSolidBlockingTile(x, y, z - 1)) return true; - if (face == 4 && level->isSolidBlockingTile(x + 1, y, z)) return true; - if (face == 5 && level->isSolidBlockingTile(x - 1, y, z)) return true; + if (face == Facing::DOWN && level->isSolidBlockingTile(x, y + 1, z)) + return true; + if (face == Facing::UP && level->isTopSolidBlocking(x, y - 1, z)) + return true; + if (face == Facing::NORTH && level->isSolidBlockingTile(x, y, z + 1)) + return true; + if (face == Facing::SOUTH && level->isSolidBlockingTile(x, y, z - 1)) + return true; + if (face == Facing::WEST && level->isSolidBlockingTile(x + 1, y, z)) + return true; + if (face == Facing::EAST && level->isSolidBlockingTile(x - 1, y, z)) + return true; return false; } @@ -68,6 +75,28 @@ int LeverTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, return dir + oldFlip; } +void LeverTile::setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance) { + int data = level->getData(x, y, z); + int dir = data & 7; + int flip = data & 8; + + if (dir == getLeverFacing(Facing::UP)) { + if ((Mth::floor(by->yRot * 4 / (360) + 0.5) & 1) == 0) { + level->setData(x, y, z, 5 | flip, Tile::UPDATE_CLIENTS); + } else { + level->setData(x, y, z, 6 | flip, Tile::UPDATE_CLIENTS); + } + } else if (dir == getLeverFacing(Facing::DOWN)) { + if ((Mth::floor(by->yRot * 4 / (360) + 0.5) & 1) == 0) { + level->setData(x, y, z, 7 | flip, Tile::UPDATE_CLIENTS); + } else { + level->setData(x, y, z, 0 | flip, Tile::UPDATE_CLIENTS); + } + } +} + int LeverTile::getLeverFacing(int facing) { switch (facing) { case Facing::DOWN: @@ -107,16 +136,16 @@ void LeverTile::neighborChanged(Level* level, int x, int y, int z, int type) { replace = true; if (replace) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); } } } bool LeverTile::checkCanSurvive(Level* level, int x, int y, int z) { if (!mayPlace(level, x, y, z)) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); return false; } return true; @@ -146,11 +175,6 @@ void LeverTile::updateShape( } } -void LeverTile::attack(Level* level, int x, int y, int z, - std::shared_ptr player) { - use(level, x, y, z, player, 0, 0, 0, 0); -} - // 4J-PB - Adding a TestUse for tooltip display bool LeverTile::TestUse() { return true; } @@ -182,7 +206,7 @@ bool LeverTile::use(Level* level, int x, int y, int z, int dir = data & 7; int open = 8 - (data & 8); - level->setData(x, y, z, dir + open); + level->setData(x, y, z, dir + open, Tile::UPDATE_ALL); level->setTilesDirty(x, y, z, x, y, z); level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_CLICK, 0.3f, @@ -227,25 +251,27 @@ void LeverTile::onRemove(Level* level, int x, int y, int z, int id, int data) { Tile::onRemove(level, x, y, z, id, data); } -bool LeverTile::getSignal(LevelSource* level, int x, int y, int z, int dir) { - return (level->getData(x, y, z) & 8) > 0; +int LeverTile::getSignal(LevelSource* level, int x, int y, int z, int dir) { + return (level->getData(x, y, z) & 8) > 0 ? Redstone::SIGNAL_MAX + : Redstone::SIGNAL_NONE; } -bool LeverTile::getDirectSignal(Level* level, int x, int y, int z, int dir) { +int LeverTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int dir) { int data = level->getData(x, y, z); - if ((data & 8) == 0) return false; + if ((data & 8) == 0) return Redstone::SIGNAL_NONE; int myDir = data & 7; - if (myDir == 0 && dir == 0) return true; - if (myDir == 7 && dir == 0) return true; - if (myDir == 6 && dir == 1) return true; - if (myDir == 5 && dir == 1) return true; - if (myDir == 4 && dir == 2) return true; - if (myDir == 3 && dir == 3) return true; - if (myDir == 2 && dir == 4) return true; - if (myDir == 1 && dir == 5) return true; + if (myDir == 0 && dir == 0) return Redstone::SIGNAL_MAX; + if (myDir == 7 && dir == 0) return Redstone::SIGNAL_MAX; + if (myDir == 6 && dir == 1) return Redstone::SIGNAL_MAX; + if (myDir == 5 && dir == 1) return Redstone::SIGNAL_MAX; + if (myDir == 4 && dir == 2) return Redstone::SIGNAL_MAX; + if (myDir == 3 && dir == 3) return Redstone::SIGNAL_MAX; + if (myDir == 2 && dir == 4) return Redstone::SIGNAL_MAX; + if (myDir == 1 && dir == 5) return Redstone::SIGNAL_MAX; - return false; + return Redstone::SIGNAL_NONE; } bool LeverTile::isSignalSource() { return true; } diff --git a/Minecraft.World/Blocks/LeverTile.h b/Minecraft.World/Blocks/LeverTile.h index 50af9b9b4..47a6b21cf 100644 --- a/Minecraft.World/Blocks/LeverTile.h +++ b/Minecraft.World/Blocks/LeverTile.h @@ -18,6 +18,9 @@ public: virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue); + virtual void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); static int getLeverFacing(int facing); virtual void neighborChanged(Level* level, int x, int y, int z, int type); @@ -29,15 +32,14 @@ public: LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< TileEntity>()); // 4J added forceData, forceEntity param - virtual void attack(Level* level, int x, int y, int z, - std::shared_ptr player); virtual bool TestUse(); virtual bool use(Level* level, int x, int y, int z, std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param virtual void onRemove(Level* level, int x, int y, int z, int id, int data); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); virtual bool isSignalSource(); }; diff --git a/Minecraft.World/Blocks/LightGemTile.cpp b/Minecraft.World/Blocks/LightGemTile.cpp deleted file mode 100644 index bd6a240c1..000000000 --- a/Minecraft.World/Blocks/LightGemTile.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "../Platform/stdafx.h" -#include "LightGemTile.h" -#include "../Headers/net.minecraft.world.item.h" - -LightGemTile::LightGemTile(int id, Material* material) : Tile(id, material) {} - -int LightGemTile::getResourceCountForLootBonus(int bonusLevel, Random* random) { - return Mth::clamp( - getResourceCount(random) + random->nextInt(bonusLevel + 1), 1, 4); -} - -int LightGemTile::getResourceCount(Random* random) { - return 2 + random->nextInt(3); -} - -int LightGemTile::getResource(int data, Random* random, int playerBonusLevel) { - return Item::yellowDust->id; -} \ No newline at end of file diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index f49c92cfb..214c8f62a 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "../Util/JavaMath.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.dimension.h" #include "../Headers/net.minecraft.world.level.biome.h" #include "../Headers/net.minecraft.world.h" #include "LiquidTile.h" @@ -12,7 +13,8 @@ const std::wstring LiquidTile::TEXTURE_WATER_STILL = L"water"; const std::wstring LiquidTile::TEXTURE_WATER_FLOW = L"water_flow"; const std::wstring LiquidTile::TEXTURE_LAVA_FLOW = L"lava_flow"; -LiquidTile::LiquidTile(int id, Material* material) : Tile(id, material, false) { +LiquidTile::LiquidTile(int id, Material* material) + : Tile(id, material, false) { float yo = 0; float e = 0; @@ -89,7 +91,7 @@ bool LiquidTile::mayPick(int data, bool liquid) { return liquid && data == 0; } bool LiquidTile::isSolidFace(LevelSource* level, int x, int y, int z, int face) { Material* m = level->getMaterial(x, y, z); - if (m == this->material) return false; + if (m == material) return false; if (face == Facing::UP) return true; if (m == Material::ice) return false; @@ -99,7 +101,7 @@ bool LiquidTile::isSolidFace(LevelSource* level, int x, int y, int z, bool LiquidTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { Material* m = level->getMaterial(x, y, z); - if (m == this->material) return false; + if (m == material) return false; if (face == Facing::UP) return true; if (m == Material::ice) return false; return Tile::shouldRenderFace(level, x, y, z, face); @@ -170,9 +172,15 @@ void LiquidTile::handleEntityInside(Level* level, int x, int y, int z, current->z += flow->z; } -int LiquidTile::getTickDelay() { +int LiquidTile::getTickDelay(Level* level) { if (material == Material::water) return 5; - if (material == Material::lava) return 30; + if (material == Material::lava) { + if (level->dimension->hasCeiling) { + return 10; + } else { + return 30; + } + } return 0; } @@ -213,8 +221,8 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, } // 4J-PB - this loop won't run! for (int i = 0; i < 0; i++) { // This was an attempt to add foam to - // the bottoms of waterfalls. It - // didn't went ok. + // the bottoms of waterfalls. It + // didn't went ok. int dir = random->nextInt(4); int xt = x; int zt = z; @@ -252,7 +260,7 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, level->playLocalSound(x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_LIQUID_WATER, random->nextFloat() * 0.25f + 0.75f, - random->nextFloat() * 1.0f + 0.5f); + random->nextFloat() * 1.0f + 0.5f, false); } } if (material == Material::lava) { @@ -268,13 +276,15 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, // 4J - new sound brought forward from 1.2.3 level->playLocalSound(xx, yy, zz, eSoundType_LIQUID_LAVA_POP, 0.2f + random->nextFloat() * 0.2f, - 0.9f + random->nextFloat() * 0.15f); + 0.9f + random->nextFloat() * 0.15f, + false); } // 4J - new sound brought forward from 1.2.3 if (random->nextInt(200) == 0) { level->playLocalSound(x, y, z, eSoundType_LIQUID_LAVA, 0.2f + random->nextFloat() * 0.2f, - 0.9f + random->nextFloat() * 0.15f); + 0.9f + random->nextFloat() * 0.15f, + false); } } } @@ -331,9 +341,9 @@ void LiquidTile::updateLiquid(Level* level, int x, int y, int z) { if (water) { int data = level->getData(x, y, z); if (data == 0) { - level->setTile(x, y, z, Tile::obsidian_Id); + level->setTileAndUpdate(x, y, z, Tile::obsidian_Id); } else if (data <= 4) { - level->setTile(x, y, z, Tile::stoneBrick_Id); + level->setTileAndUpdate(x, y, z, Tile::cobblestone_Id); } fizz(level, x, y, z); } diff --git a/Minecraft.World/Blocks/LiquidTile.h b/Minecraft.World/Blocks/LiquidTile.h index 1415a2c7e..24c3d8f17 100644 --- a/Minecraft.World/Blocks/LiquidTile.h +++ b/Minecraft.World/Blocks/LiquidTile.h @@ -51,7 +51,7 @@ private: public: virtual void handleEntityInside(Level* level, int x, int y, int z, std::shared_ptr e, Vec3* current); - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual int getLightColor( LevelSource* level, int x, int y, int z, int tileId = -1); // 4J - brought forward from 1.8.2 diff --git a/Minecraft.World/Blocks/LiquidTileDynamic.cpp b/Minecraft.World/Blocks/LiquidTileDynamic.cpp index 1e7a5cb1a..a2a3366b1 100644 --- a/Minecraft.World/Blocks/LiquidTileDynamic.cpp +++ b/Minecraft.World/Blocks/LiquidTileDynamic.cpp @@ -18,8 +18,7 @@ LiquidTileDynamic::~LiquidTileDynamic() { void LiquidTileDynamic::setStatic(Level* level, int x, int y, int z) { int d = level->getData(x, y, z); - level->setTileAndDataNoUpdate(x, y, z, id + 1, d); - level->setTilesDirty(x, y, z, x, y, z); + level->setTileAndData(x, y, z, id + 1, d, Tile::UPDATE_CLIENTS); } bool LiquidTileDynamic::isPathfindable(LevelSource* level, int x, int y, @@ -31,12 +30,15 @@ void LiquidTileDynamic::iterativeTick(Level* level, int x, int y, int z, Random* random) { m_tilesToTick.push_back(LiquidTickData(level, x, y, z, random)); - while (m_tilesToTick.size() > 0) { + int failsafe = 100; + while ((m_tilesToTick.size() > 0) && (failsafe > 0)) { LiquidTickData tickData = m_tilesToTick.front(); m_tilesToTick.pop_front(); mainTick(tickData.level, tickData.x, tickData.y, tickData.z, tickData.random); + failsafe--; } + m_tilesToTick.clear(); } void LiquidTileDynamic::tick(Level* level, int x, int y, int z, @@ -63,6 +65,7 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z, if (material == Material::lava && !level->dimension->ultraWarm) dropOff = 2; bool becomeStatic = true; + int tickDelay = getTickDelay(level); if (depth > 0) { int highest = -100; maxCount = 0; @@ -96,8 +99,7 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z, if (depth < 8 && newDepth < 8) { if (newDepth > depth) { if (random->nextInt(4) != 0) { - newDepth = depth; - becomeStatic = false; + tickDelay = tickDelay * 4; } } } @@ -109,10 +111,10 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z, } else { depth = newDepth; if (depth < 0) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } else { - level->setData(x, y, z, depth); - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->setData(x, y, z, depth, Tile::UPDATE_CLIENTS); + level->addToTickNextTick(x, y, z, id, tickDelay); level->updateNeighborsAt(x, y, z, id); } } @@ -122,7 +124,7 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z, if (canSpreadTo(level, x, y - 1, z)) { if (material == Material::lava) { if (level->getMaterial(x, y - 1, z) == Material::water) { - level->setTile(x, y - 1, z, Tile::rock_Id); + level->setTileAndUpdate(x, y - 1, z, Tile::stone_Id); fizz(level, x, y - 1, z); return; } @@ -161,7 +163,7 @@ void LiquidTileDynamic::trySpreadTo(Level* level, int x, int y, int z, } } } - level->setTileAndData(x, y, z, id, neighbor); + level->setTileAndData(x, y, z, id, neighbor, Tile::UPDATE_ALL); } } @@ -288,6 +290,8 @@ bool LiquidTileDynamic::canSpreadTo(Level* level, int x, int y, int z) { void LiquidTileDynamic::onPlace(Level* level, int x, int y, int z) { LiquidTile::onPlace(level, x, y, z); if (level->getTile(x, y, z) == id) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); } } + +bool LiquidTileDynamic::canInstantlyTick() { return true; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/LiquidTileDynamic.h b/Minecraft.World/Blocks/LiquidTileDynamic.h index 2de923941..48e769829 100644 --- a/Minecraft.World/Blocks/LiquidTileDynamic.h +++ b/Minecraft.World/Blocks/LiquidTileDynamic.h @@ -57,4 +57,5 @@ private: public: void onPlace(Level* level, int x, int y, int z); + bool canInstantlyTick(); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/LiquidTileStatic.cpp b/Minecraft.World/Blocks/LiquidTileStatic.cpp index 023bfb5cc..b1b75838b 100644 --- a/Minecraft.World/Blocks/LiquidTileStatic.cpp +++ b/Minecraft.World/Blocks/LiquidTileStatic.cpp @@ -23,11 +23,8 @@ void LiquidTileStatic::neighborChanged(Level* level, int x, int y, int z, void LiquidTileStatic::setDynamic(Level* level, int x, int y, int z) { int d = level->getData(x, y, z); - level->noNeighborUpdate = true; - level->setTileAndDataNoUpdate(x, y, z, id - 1, d); - level->setTilesDirty(x, y, z, x, y, z); - level->addToTickNextTick(x, y, z, id - 1, getTickDelay()); - level->noNeighborUpdate = false; + level->setTileAndData(x, y, z, id - 1, d, Tile::UPDATE_CLIENTS); + level->addToTickNextTick(x, y, z, id - 1, getTickDelay(level)); } void LiquidTileStatic::tick(Level* level, int x, int y, int z, Random* random) { @@ -45,7 +42,7 @@ void LiquidTileStatic::tick(Level* level, int x, int y, int z, Random* random) { isFlammable(level, x, y, z + 1) || isFlammable(level, x, y - 1, z) || isFlammable(level, x, y + 1, z)) { - level->setTile(x, y, z, Tile::fire_Id); + level->setTileAndUpdate(x, y, z, Tile::fire_Id); return; } } else if (Tile::tiles[t]->material->blocksMotion()) { @@ -60,7 +57,7 @@ void LiquidTileStatic::tick(Level* level, int x, int y, int z, Random* random) { z = oz + random->nextInt(3) - 1; if (level->isEmptyTile(x, y + 1, z) && isFlammable(level, x, y, z)) { - level->setTile(x, y + 1, z, Tile::fire_Id); + level->setTileAndUpdate(x, y + 1, z, Tile::fire_Id); } } } diff --git a/Minecraft.World/Blocks/LockedChestTile.cpp b/Minecraft.World/Blocks/LockedChestTile.cpp index 4b48cfa97..ff3ede66f 100644 --- a/Minecraft.World/Blocks/LockedChestTile.cpp +++ b/Minecraft.World/Blocks/LockedChestTile.cpp @@ -9,7 +9,7 @@ bool LockedChestTile::mayPlace(Level* level, int x, int y, int z) { } void LockedChestTile::tick(Level* level, int x, int y, int z, Random* random) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } void LockedChestTile::registerIcons(IconRegister* iconRegister) { diff --git a/Minecraft.World/Blocks/MelonTile.cpp b/Minecraft.World/Blocks/MelonTile.cpp index 9e29191d0..434ab847d 100644 --- a/Minecraft.World/Blocks/MelonTile.cpp +++ b/Minecraft.World/Blocks/MelonTile.cpp @@ -4,9 +4,6 @@ #include "../Headers/net.minecraft.world.h" #include "../Util/Facing.h" -const std::wstring MelonTile::TEX = L"melon_side"; -const std::wstring MelonTile::TEX_TOP = L"melon_top"; - MelonTile::MelonTile(int id) : Tile(id, Material::vegetable) { iconTop = NULL; } Icon* MelonTile::getTexture(int face, int data) { @@ -31,6 +28,6 @@ int MelonTile::getResourceCountForLootBonus(int bonusLevel, Random* random) { } void MelonTile::registerIcons(IconRegister* iconRegister) { - icon = iconRegister->registerIcon(TEX); - iconTop = iconRegister->registerIcon(TEX_TOP); + icon = iconRegister->registerIcon(getIconName() + L"_side"); + iconTop = iconRegister->registerIcon(getIconName() + L"_top"); } \ No newline at end of file diff --git a/Minecraft.World/Blocks/MelonTile.h b/Minecraft.World/Blocks/MelonTile.h index 457b602c1..6dd957bd0 100644 --- a/Minecraft.World/Blocks/MelonTile.h +++ b/Minecraft.World/Blocks/MelonTile.h @@ -6,9 +6,6 @@ class MelonTile : public Tile { friend class ChunkRebuildData; private: - static const std::wstring TEX; - static const std::wstring TEX_TOP; - Icon* iconTop; // 4J Stu - I don't know why this is protected in Java diff --git a/Minecraft.World/Blocks/MobSpawner.cpp b/Minecraft.World/Blocks/MobSpawner.cpp index eed1fe65e..61bbf1292 100644 --- a/Minecraft.World/Blocks/MobSpawner.cpp +++ b/Minecraft.World/Blocks/MobSpawner.cpp @@ -41,7 +41,7 @@ std::unordered_map #endif const int MobSpawner::tick(ServerLevel* level, bool spawnEnemies, - bool spawnFriendlies) { + bool spawnFriendlies, bool spawnPersistent) { #ifndef _CONTENT_PACKAGE #if 0 @@ -95,7 +95,7 @@ const int MobSpawner::tick(ServerLevel* level, bool spawnEnemies, #endif #endif - if (!spawnEnemies && !spawnFriendlies) { + if (!spawnEnemies && !spawnFriendlies && !spawnPersistent) { return 0; } MemSect(20); @@ -209,10 +209,18 @@ const int MobSpawner::tick(ServerLevel* level, bool spawnEnemies, for (unsigned int i = 0; i < MobCategory::values.length; i++) { MobCategory* mobCategory = MobCategory::values[i]; if ((mobCategory->isFriendly() && !spawnFriendlies) || - (!mobCategory->isFriendly() && !spawnEnemies)) { + (!mobCategory->isFriendly() && !spawnEnemies) || + (mobCategory->isPersistent() && !spawnPersistent)) { continue; } + // 4J - early out for non-main dimensions, if spawning anything friendly + if (mobCategory->isFriendly()) { + if (level->dimension->id != 0) { + continue; + } + } + // 4J - this is now quite different to the java version. We just have // global max counts for the level whereas the original has a max per // chunk that scales with the number of chunks to be polled. @@ -259,6 +267,7 @@ const int MobSpawner::tick(ServerLevel* level, bool spawnEnemies, int ss = 6; Biome::MobSpawnerData* currentMobType = NULL; + MobGroupData* groupData = NULL; for (int ll = 0; ll < 4; ll++) { x += @@ -315,12 +324,12 @@ const int MobSpawner::tick(ServerLevel* level, bool spawnEnemies, //(exception e) // { // // - //TODO 4J We can't print a stack trace, and the - //newInstance function doesn't throw an exception just - //now anyway + // TODO 4J We can't print a stack trace, and the + // newInstance function doesn't throw an exception just + // now anyway // //e.printStackTrace(); // return - //count; + // count; // } // 4J - If it is an animal or a monster, don't let any @@ -388,8 +397,7 @@ const int MobSpawner::tick(ServerLevel* level, bool spawnEnemies, // against // despawning level->addEntity(mob); - finalizeMobSettings(mob, level, xx, yy, zz); - mob->finalizeMobSpawn(); + groupData = mob->finalizeMobSpawn(groupData); // 4J - change here so that we can't ever make // more than the desired amount of entities in // each priority. In the original java version @@ -470,170 +478,6 @@ bool MobSpawner::isSpawnPositionOk(MobCategory* category, Level* level, int x, } } -void MobSpawner::finalizeMobSettings(std::shared_ptr mob, Level* level, - float xx, float yy, float zz) { - if (std::dynamic_pointer_cast(mob) != NULL && - level->random->nextInt(100) == 0) { - std::shared_ptr skeleton = - std::shared_ptr(new Skeleton(level)); - skeleton->moveTo(xx, yy, zz, mob->yRot, 0); - level->addEntity(skeleton); - skeleton->ride(mob); - } else if (std::dynamic_pointer_cast(mob) != NULL) { - (std::dynamic_pointer_cast(mob)) - ->setColor(Sheep::getSheepColor(level->random)); - } else if (std::dynamic_pointer_cast(mob) != NULL) { - if (level->random->nextInt(7) == 0) { - for (int kitten = 0; kitten < 2; kitten++) { - std::shared_ptr ozelot = - std::shared_ptr(new Ozelot(level)); - ozelot->moveTo(xx, yy, zz, mob->yRot, 0); - ozelot->setAge(-20 * 60 * 20); - level->addEntity(ozelot); - } - } - } -} - -// 4J Stu TODO This was an array of Class type. I haven't made a base Class type -// yet, but don't need to as this can be an array of Mob type? -eINSTANCEOF MobSpawner::bedEnemies[bedEnemyCount] = {eTYPE_SPIDER, eTYPE_ZOMBIE, - eTYPE_SKELETON}; - -bool MobSpawner::attackSleepingPlayers( - Level* level, std::vector >* players) { - bool somebodyWokeUp = false; - - PathFinder finder = PathFinder(level, true, false, false, true); - - AUTO_VAR(itEnd, players->end()); - for (AUTO_VAR(it, players->begin()); it != itEnd; it++) { - std::shared_ptr player = (*it); - - bool nextPlayer = false; - - for (int attemptCount = 0; attemptCount < 20 && !nextPlayer; - attemptCount++) { - // limit position within the range of the player - int x = Mth::floor(player->x) + level->random->nextInt(32) - - level->random->nextInt(32); - int z = Mth::floor(player->z) + level->random->nextInt(32) - - level->random->nextInt(32); - int yStart = Mth::floor(player->y) + level->random->nextInt(16) - - level->random->nextInt(16); - if (yStart < 1) { - yStart = 1; - } else if (yStart > Level::maxBuildHeight) { - yStart = Level::maxBuildHeight; - } - - { - int type = level->random->nextInt(bedEnemyCount); - int y = yStart; - - while (y > 2 && !level->isTopSolidBlocking(x, y - 1, z)) { - y--; - } - - while (!isSpawnPositionOk((MobCategory*)MobCategory::monster, - level, x, y, z) && - y < (yStart + 16) && y < Level::maxBuildHeight) { - y++; - } - if (y >= (yStart + 16) || y >= Level::maxBuildHeight) { - y = yStart; - continue; - } else { - float xx = x + 0.5f; - float yy = (float)y; - float zz = z + 0.5f; - - std::shared_ptr mob; - // 4J - removed try/catch - // try - // { - // mob = - // classes[type].getConstructor(Level.class).newInstance(level); - // 4J - there was a classes array here which duplicated the - // bedEnemies array but have removed it - mob = std::dynamic_pointer_cast( - EntityIO::newByEnumType(bedEnemies[type], level)); - // } - // catch (exception e) - // { - // // TODO 4J Stu - - //We can't print a stack trace, and newInstance doesn't - //currently throw an exception anyway - // //e.printStackTrace(); - // return - //somebodyWokeUp; - // } - - // System.out.println("Placing night mob"); - mob->moveTo(xx, yy, zz, level->random->nextFloat() * 360, - 0); - // check if the mob can spawn at this location - if (!mob->canSpawn()) { - continue; - } - Pos* bedPos = BedTile::findStandUpPosition( - level, Mth::floor(player->x), Mth::floor(player->y), - Mth::floor(player->z), 1); - if (bedPos == NULL) { - // an unlikely case where the bed is - // completely blocked - bedPos = new Pos(x, y + 1, z); - } - - // 4J Stu - TU-1 hotfix - // Fix for #13152 - If the player sleeps in a bed next to a - // wall in an enclosed, well lit area they will be awoken by - // a monster The pathfinder should attempt to get close to - // the position that we will move the mob to, instead of the - // player who could be next to a wall. Otherwise the paths - // gets to the other side of the the wall, then moves the - // mob inside the building - // Path *findPath = finder.findPath(mob.get(), - // player.get(), 32.0f); - Path* findPath = finder.findPath( - mob.get(), bedPos->x, bedPos->y, bedPos->z, 32.0f); - if (findPath != NULL && findPath->getSize() > 1) { - Node* last = findPath->last(); - - if (abs(last->x - bedPos->x) < 1.5 && - abs(last->z - bedPos->z) < 1.5 && - abs(last->y - bedPos->y) < 1.5) { - // System.out.println("Found path!"); - - mob->moveTo(bedPos->x + 0.5f, bedPos->y, - bedPos->z + 0.5f, 0, 0); - // the mob would maybe not be able to - // spawn here, but we ignore that now (we assume - // it walked here) - { - level->addEntity(mob); - finalizeMobSettings( - mob, level, bedPos->x + 0.5f, - (float)bedPos->y, bedPos->z + 0.5f); - mob->finalizeMobSpawn(); - player->stopSleepInBed(true, false, false); - // play a sound effect to scare the player - mob->playAmbientSound(); - somebodyWokeUp = true; - nextPlayer = true; - } - } - delete findPath; - } - delete bedPos; - } - } - } - } - - return somebodyWokeUp; -} - void MobSpawner::postProcessSpawnMobs(Level* level, Biome* biome, int xo, int zo, int cellWidth, int cellHeight, Random* random) { @@ -648,6 +492,7 @@ void MobSpawner::postProcessSpawnMobs(Level* level, Biome* biome, int xo, while (random->nextFloat() < biome->getCreatureProbability()) { Biome::MobSpawnerData *type = (Biome::MobSpawnerData *) WeighedRandom::getRandomItem(level->random, ((std::vector *)mobs)); + MobGroupData *groupData = NULL; int count = type->minCount + random->nextInt(1 + type->maxCount - type->minCount); int x = xo + random->nextInt(cellWidth); @@ -682,7 +527,7 @@ void MobSpawner::postProcessSpawnMobs(Level* level, Biome* biome, int xo, mob->setDespawnProtected(); level->addEntity(mob); - finalizeMobSettings(mob, level, xx, yy, zz); + groupData = mob->finalizeMobSpawn(groupData); success = true; } diff --git a/Minecraft.World/Blocks/MobSpawner.h b/Minecraft.World/Blocks/MobSpawner.h index 5a5659038..db129443d 100644 --- a/Minecraft.World/Blocks/MobSpawner.h +++ b/Minecraft.World/Blocks/MobSpawner.h @@ -27,20 +27,10 @@ private: public: static const int tick(ServerLevel* level, bool spawnEnemies, - bool spawnFriendlies); + bool spawnFriendlies, bool spawnPersistent); static bool isSpawnPositionOk(MobCategory* category, Level* level, int x, int y, int z); -private: - static void finalizeMobSettings(std::shared_ptr mob, Level* level, - float xx, float yy, float zz); - -protected: - // 4J Stu TODO This was an array of Class type. I haven't made a base Class - // type yet, but don't need to as this can be an array of Mob type? - static const int bedEnemyCount = 3; - static eINSTANCEOF bedEnemies[bedEnemyCount]; - public: static bool attackSleepingPlayers( Level* level, std::vector >* players); diff --git a/Minecraft.World/Blocks/MobSpawnerTile.cpp b/Minecraft.World/Blocks/MobSpawnerTile.cpp index 36d3c41e7..85af0b16d 100644 --- a/Minecraft.World/Blocks/MobSpawnerTile.cpp +++ b/Minecraft.World/Blocks/MobSpawnerTile.cpp @@ -4,7 +4,7 @@ #include "MobSpawnerTile.h" MobSpawnerTile::MobSpawnerTile(int id) - : EntityTile(id, Material::stone, false) {} + : BaseEntityTile(id, Material::stone, false) {} std::shared_ptr MobSpawnerTile::newTileEntity(Level* level) { return std::shared_ptr(new MobSpawnerTileEntity()); @@ -33,4 +33,4 @@ void MobSpawnerTile::spawnResources(Level* level, int x, int y, int z, int data, } } -int MobSpawnerTile::cloneTileId(Level* level, int x, int y, int z) { return 0; } +int MobSpawnerTile::cloneTileId(Level* level, int x, int y, int z) { return 0; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/MobSpawnerTile.h b/Minecraft.World/Blocks/MobSpawnerTile.h index a5c970555..487bf7bb4 100644 --- a/Minecraft.World/Blocks/MobSpawnerTile.h +++ b/Minecraft.World/Blocks/MobSpawnerTile.h @@ -1,9 +1,9 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class Random; -class MobSpawnerTile : public EntityTile { +class MobSpawnerTile : public BaseEntityTile { friend class Tile; protected: diff --git a/Minecraft.World/Blocks/MushroomPlantTile.cpp b/Minecraft.World/Blocks/MushroomPlantTile.cpp index d9f844dcb..c55636729 100644 --- a/Minecraft.World/Blocks/MushroomPlantTile.cpp +++ b/Minecraft.World/Blocks/MushroomPlantTile.cpp @@ -4,10 +4,9 @@ #include "../Headers/net.minecraft.world.h" #include "MushroomPlantTile.h" -Mushroom::Mushroom(int id, const std::wstring& texture) : Bush(id) { +Mushroom::Mushroom(int id) : Bush(id) { this->updateDefaultShape(); this->setTicking(true); - this->texture = texture; } // 4J Added override @@ -42,7 +41,7 @@ void Mushroom::tick(Level* level, int x, int y, int z, Random* random) { } if (level->isEmptyTile(x2, y2, z2) && canSurvive(level, x2, y2, z2)) { - level->setTile(x2, y2, z2, id); + level->setTileAndData(x2, y2, z2, id, 0, UPDATE_CLIENTS); } } } @@ -65,24 +64,20 @@ bool Mushroom::canSurvive(Level* level, int x, int y, int z) { bool Mushroom::growTree(Level* level, int x, int y, int z, Random* random) { int data = level->getData(x, y, z); - level->setTileNoUpdate(x, y, z, 0); + level->removeTile(x, y, z); Feature* f = NULL; - if (id == Tile::mushroom1_Id) { + if (id == Tile::mushroom_brown_Id) { f = new HugeMushroomFeature(0); - } else if (id == Tile::mushroom2_Id) { + } else if (id == Tile::mushroom_red_Id) { f = new HugeMushroomFeature(1); } if (f == NULL || !f->place(level, random, x, y, z)) { - level->setTileAndDataNoUpdate(x, y, z, this->id, data); + level->setTileAndData(x, y, z, id, data, Tile::UPDATE_ALL); if (f != NULL) delete f; return false; } if (f != NULL) delete f; return true; -} - -void Mushroom::registerIcons(IconRegister* iconRegister) { - icon = iconRegister->registerIcon(texture); -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/MushroomPlantTile.h b/Minecraft.World/Blocks/MushroomPlantTile.h index f190c0d50..ebc270b0a 100644 --- a/Minecraft.World/Blocks/MushroomPlantTile.h +++ b/Minecraft.World/Blocks/MushroomPlantTile.h @@ -6,11 +6,8 @@ class Random; class Mushroom : public Bush { friend class Tile; -private: - std::wstring texture; - protected: - Mushroom(int id, const std::wstring& texture); + Mushroom(int id); public: virtual void updateDefaultShape(); // 4J Added override @@ -23,5 +20,4 @@ protected: public: virtual bool canSurvive(Level* level, int x, int y, int z); bool growTree(Level* level, int x, int y, int z, Random* random); - void registerIcons(IconRegister* iconRegister); }; diff --git a/Minecraft.World/Blocks/MycelTile.cpp b/Minecraft.World/Blocks/MycelTile.cpp index 2f67be7fe..dc7cc96e3 100644 --- a/Minecraft.World/Blocks/MycelTile.cpp +++ b/Minecraft.World/Blocks/MycelTile.cpp @@ -37,7 +37,7 @@ void MycelTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getRawBrightness(x, y + 1, z) < MIN_BRIGHTNESS && Tile::lightBlock[level->getTile(x, y + 1, z)] > 2) { - level->setTile(x, y, z, Tile::dirt_Id); + level->setTileAndUpdate(x, y, z, Tile::dirt_Id); } else { if (level->getRawBrightness(x, y + 1, z) >= Level::MAX_BRIGHTNESS - 6) { for (int i = 0; i < 4; i++) { @@ -48,7 +48,7 @@ void MycelTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getTile(xt, yt, zt) == Tile::dirt_Id && level->getRawBrightness(xt, yt + 1, zt) >= MIN_BRIGHTNESS && Tile::lightBlock[above] <= 2) { - level->setTile(xt, yt, zt, id); + level->setTileAndUpdate(xt, yt, zt, id); } } } diff --git a/Minecraft.World/Blocks/NetherStalkTile.cpp b/Minecraft.World/Blocks/NetherStalkTile.cpp deleted file mode 100644 index 19b6aef74..000000000 --- a/Minecraft.World/Blocks/NetherStalkTile.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "../Platform/stdafx.h" -#include "NetherStalkTile.h" -#include "../Headers/net.minecraft.world.level.h" -#include "../Headers/net.minecraft.world.level.biome.h" -#include "../Headers/net.minecraft.world.item.h" -#include "../Headers/net.minecraft.world.h" - -const std::wstring NetherStalkTile::TEXTURE_NAMES[] = { - L"netherStalk_0", L"netherStalk_1", L"netherStalk_2"}; - -NetherStalkTile::NetherStalkTile(int id) : Bush(id) { - setTicking(true); - updateDefaultShape(); - - icons = NULL; -} - -// 4J Added override -void NetherStalkTile::updateDefaultShape() { - float ss = 0.5f; - this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss); -} - -bool NetherStalkTile::mayPlaceOn(int tile) { return tile == Tile::hellSand_Id; } - -// Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot -// be placed next to each other in the Nether -bool NetherStalkTile::canSurvive(Level* level, int x, int y, int z) { - return mayPlaceOn(level->getTile(x, y - 1, z)); -} - -void NetherStalkTile::tick(Level* level, int x, int y, int z, Random* random) { - int age = level->getData(x, y, z); - if (age < MAX_AGE) { - // Biome *biome = biomeSource->getBiome(x, z); - // if (dynamic_cast(biome) != NULL) - //{ - if (random->nextInt(10) == 0) { - age++; - level->setData(x, y, z, age); - } - //} - } - - Bush::tick(level, x, y, z, random); -} - -void NetherStalkTile::growCropsToMax(Level* level, int x, int y, int z) { - level->setData(x, y, z, MAX_AGE); -} - -Icon* NetherStalkTile::getTexture(int face, int data) { - if (data >= MAX_AGE) { - return icons[2]; - } - if (data > 0) { - return icons[1]; - } - return icons[0]; -} - -int NetherStalkTile::getRenderShape() { return Tile::SHAPE_ROWS; } - -void NetherStalkTile::spawnResources(Level* level, int x, int y, int z, - int data, float odds, int playerBonus) { - if (level->isClientSide) { - return; - } - int count = 1; - if (data >= MAX_AGE) { - count = 2 + level->random->nextInt(3); - if (playerBonus > 0) { - count += level->random->nextInt(playerBonus + 1); - } - } - for (int i = 0; i < count; i++) { - popResource(level, x, y, z, - std::shared_ptr( - new ItemInstance(Item::netherStalkSeeds))); - } -} - -int NetherStalkTile::getResource(int data, Random* random, - int playerBonusLevel) { - return 0; -} - -int NetherStalkTile::getResourceCount(Random* random) { return 0; } - -int NetherStalkTile::cloneTileId(Level* level, int x, int y, int z) { - return Item::netherStalkSeeds_Id; -} - -void NetherStalkTile::registerIcons(IconRegister* iconRegister) { - icons = new Icon*[NETHER_STALK_TEXTURE_COUNT]; - - for (int i = 0; i < NETHER_STALK_TEXTURE_COUNT; i++) { - icons[i] = iconRegister->registerIcon(TEXTURE_NAMES[i]); - } -} diff --git a/Minecraft.World/Blocks/NetherWartTile.cpp b/Minecraft.World/Blocks/NetherWartTile.cpp new file mode 100644 index 000000000..956d40ee9 --- /dev/null +++ b/Minecraft.World/Blocks/NetherWartTile.cpp @@ -0,0 +1,90 @@ +#include "../Platform/stdafx.h" +#include "NetherWartTile.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.biome.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.h" + +NetherWartTile::NetherWartTile(int id) : Bush(id) { + setTicking(true); + updateDefaultShape(); +} + +// 4J Added override +void NetherWartTile::updateDefaultShape() { + float ss = 0.5f; + setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss); +} + +bool NetherWartTile::mayPlaceOn(int tile) { return tile == Tile::soulsand_Id; } + +// Brought forward to fix #60073 - TU7: Content: Gameplay: Nether Warts cannot +// be placed next to each other in the Nether +bool NetherWartTile::canSurvive(Level* level, int x, int y, int z) { + return mayPlaceOn(level->getTile(x, y - 1, z)); +} + +void NetherWartTile::tick(Level* level, int x, int y, int z, Random* random) { + int age = level->getData(x, y, z); + if (age < MAX_AGE) { + if (random->nextInt(10) == 0) { + age++; + level->setData(x, y, z, age, Tile::UPDATE_CLIENTS); + } + } + + Bush::tick(level, x, y, z, random); +} + +void NetherWartTile::growCropsToMax(Level* level, int x, int y, int z) { + level->setData(x, y, z, MAX_AGE, Tile::UPDATE_CLIENTS); +} + +Icon* NetherWartTile::getTexture(int face, int data) { + if (data >= MAX_AGE) { + return icons[2]; + } + if (data > 0) { + return icons[1]; + } + return icons[0]; +} + +int NetherWartTile::getRenderShape() { return Tile::SHAPE_ROWS; } + +void NetherWartTile::spawnResources(Level* level, int x, int y, int z, int data, + float odds, int playerBonus) { + if (level->isClientSide) { + return; + } + int count = 1; + if (data >= MAX_AGE) { + count = 2 + level->random->nextInt(3); + if (playerBonus > 0) { + count += level->random->nextInt(playerBonus + 1); + } + } + for (int i = 0; i < count; i++) { + popResource(level, x, y, z, + std::shared_ptr( + new ItemInstance(Item::netherwart_seeds))); + } +} + +int NetherWartTile::getResource(int data, Random* random, + int playerBonusLevel) { + return 0; +} + +int NetherWartTile::getResourceCount(Random* random) { return 0; } + +int NetherWartTile::cloneTileId(Level* level, int x, int y, int z) { + return Item::netherwart_seeds_Id; +} + +void NetherWartTile::registerIcons(IconRegister* iconRegister) { + for (int i = 0; i < NETHER_STALK_TEXTURE_COUNT; i++) { + icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + + _toString(i)); + } +} diff --git a/Minecraft.World/Blocks/NetherStalkTile.h b/Minecraft.World/Blocks/NetherWartTile.h similarity index 89% rename from Minecraft.World/Blocks/NetherStalkTile.h rename to Minecraft.World/Blocks/NetherWartTile.h index 9f53ab663..8eeddc8cc 100644 --- a/Minecraft.World/Blocks/NetherStalkTile.h +++ b/Minecraft.World/Blocks/NetherWartTile.h @@ -2,19 +2,17 @@ #include "PlantTile.h" class ChunkRebuildData; -class NetherStalkTile : public Bush { +class NetherWartTile : public Bush { friend class ChunkRebuildData; private: static const int MAX_AGE = 3; static const int NETHER_STALK_TEXTURE_COUNT = 3; - static const std::wstring TEXTURE_NAMES[]; - - Icon** icons; + Icon* icons[NETHER_STALK_TEXTURE_COUNT]; public: - NetherStalkTile(int id); + NetherWartTile(int id); virtual void updateDefaultShape(); // 4J Added override virtual bool mayPlaceOn(int tile); diff --git a/Minecraft.World/Blocks/NetherrackTile.cpp b/Minecraft.World/Blocks/NetherrackTile.cpp new file mode 100644 index 000000000..a3f026497 --- /dev/null +++ b/Minecraft.World/Blocks/NetherrackTile.cpp @@ -0,0 +1,4 @@ +#include "../Platform/stdafx.h" +#include "NetherrackTile.h" + +NetherrackTile::NetherrackTile(int id) : Tile(id, Material::stone) {} \ No newline at end of file diff --git a/Minecraft.World/Blocks/NetherrackTile.h b/Minecraft.World/Blocks/NetherrackTile.h new file mode 100644 index 000000000..5514b6e9b --- /dev/null +++ b/Minecraft.World/Blocks/NetherrackTile.h @@ -0,0 +1,7 @@ +#pragma once +#include "Tile.h" + +class NetherrackTile : public Tile { +public: + NetherrackTile(int id); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/NotGateTile.cpp b/Minecraft.World/Blocks/NotGateTile.cpp index 89ecef92e..4d3ab5f7d 100644 --- a/Minecraft.World/Blocks/NotGateTile.cpp +++ b/Minecraft.World/Blocks/NotGateTile.cpp @@ -1,5 +1,6 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "NotGateTile.h" #include "../Util/SoundTypes.h" #include "../Headers/net.minecraft.world.h" @@ -25,7 +26,8 @@ bool NotGateTile::isToggledTooFrequently(Level* level, int x, int y, int z, if (recentToggles.find(level) == recentToggles.end()) { recentToggles[level] = new std::deque; } - if (add) recentToggles[level]->push_back(Toggle(x, y, z, level->getTime())); + if (add) + recentToggles[level]->push_back(Toggle(x, y, z, level->getGameTime())); int count = 0; AUTO_VAR(itEnd, recentToggles[level]->end()); @@ -45,7 +47,7 @@ NotGateTile::NotGateTile(int id, bool on) : TorchTile(id) { this->setTicking(true); } -int NotGateTile::getTickDelay() { return 2; } +int NotGateTile::getTickDelay(Level* level) { return 2; } void NotGateTile::onPlace(Level* level, int x, int y, int z) { if (level->getData(x, y, z) == 0) TorchTile::onPlace(level, x, y, z); @@ -71,28 +73,28 @@ void NotGateTile::onRemove(Level* level, int x, int y, int z, int id, } } -bool NotGateTile::getSignal(LevelSource* level, int x, int y, int z, int face) { - if (!on) return false; +int NotGateTile::getSignal(LevelSource* level, int x, int y, int z, int face) { + if (!on) return Redstone::SIGNAL_NONE; int dir = level->getData(x, y, z); - if (dir == 5 && face == 1) return false; - if (dir == 3 && face == 3) return false; - if (dir == 4 && face == 2) return false; - if (dir == 1 && face == 5) return false; - if (dir == 2 && face == 4) return false; + if (dir == 5 && face == 1) return Redstone::SIGNAL_NONE; + if (dir == 3 && face == 3) return Redstone::SIGNAL_NONE; + if (dir == 4 && face == 2) return Redstone::SIGNAL_NONE; + if (dir == 1 && face == 5) return Redstone::SIGNAL_NONE; + if (dir == 2 && face == 4) return Redstone::SIGNAL_NONE; - return true; + return Redstone::SIGNAL_MAX; } bool NotGateTile::hasNeighborSignal(Level* level, int x, int y, int z) { int dir = level->getData(x, y, z); - if (dir == 5 && level->getSignal(x, y - 1, z, 0)) return true; - if (dir == 3 && level->getSignal(x, y, z - 1, 2)) return true; - if (dir == 4 && level->getSignal(x, y, z + 1, 3)) return true; - if (dir == 1 && level->getSignal(x - 1, y, z, 4)) return true; - if (dir == 2 && level->getSignal(x + 1, y, z, 5)) return true; + if (dir == 5 && level->hasSignal(x, y - 1, z, 0)) return true; + if (dir == 3 && level->hasSignal(x, y, z - 1, 2)) return true; + if (dir == 4 && level->hasSignal(x, y, z + 1, 3)) return true; + if (dir == 1 && level->hasSignal(x - 1, y, z, 4)) return true; + if (dir == 2 && level->hasSignal(x + 1, y, z, 5)) return true; return false; } @@ -103,15 +105,16 @@ void NotGateTile::tick(Level* level, int x, int y, int z, Random* random) { if (recentToggles.find(level) != recentToggles.end()) { std::deque* toggles = recentToggles[level]; while (!toggles->empty() && - level->getTime() - toggles->front().when > RECENT_TOGGLE_TIMER) { + level->getGameTime() - toggles->front().when > + RECENT_TOGGLE_TIMER) { toggles->pop_front(); } } if (on) { if (neighborSignal) { - level->setTileAndData(x, y, z, Tile::notGate_off_Id, - level->getData(x, y, z)); + level->setTileAndData(x, y, z, Tile::redstoneTorch_off_Id, + level->getData(x, y, z), Tile::UPDATE_ALL); if (isToggledTooFrequently(level, x, y, z, true)) { app.DebugPrintf( @@ -136,8 +139,9 @@ void NotGateTile::tick(Level* level, int x, int y, int z, Random* random) { } else { if (!neighborSignal) { if (!isToggledTooFrequently(level, x, y, z, false)) { - level->setTileAndData(x, y, z, Tile::notGate_on_Id, - level->getData(x, y, z)); + level->setTileAndData(x, y, z, Tile::redstoneTorch_on_Id, + level->getData(x, y, z), + Tile::UPDATE_ALL); } else { app.DebugPrintf( "Torch at (%d,%d,%d) has toggled too many times\n", x, y, @@ -148,19 +152,26 @@ void NotGateTile::tick(Level* level, int x, int y, int z, Random* random) { } void NotGateTile::neighborChanged(Level* level, int x, int y, int z, int type) { - TorchTile::neighborChanged(level, x, y, z, type); - level->addToTickNextTick(x, y, z, id, getTickDelay()); + if (checkDoPop(level, x, y, z, type)) { + return; + } + + bool neighborSignal = hasNeighborSignal(level, x, y, z); + if ((on && neighborSignal) || (!on && !neighborSignal)) { + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); + } } -bool NotGateTile::getDirectSignal(Level* level, int x, int y, int z, int face) { +int NotGateTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int face) { if (face == 0) { return getSignal(level, x, y, z, face); } - return false; + return Redstone::SIGNAL_NONE; } int NotGateTile::getResource(int data, Random* random, int playerBonusLevel) { - return Tile::notGate_on_Id; + return Tile::redstoneTorch_on_Id; } bool NotGateTile::isSignalSource() { return true; } @@ -188,7 +199,7 @@ void NotGateTile::animateTick(Level* level, int xt, int yt, int zt, } int NotGateTile::cloneTileId(Level* level, int x, int y, int z) { - return Tile::notGate_on_Id; + return Tile::redstoneTorch_on_Id; } void NotGateTile::levelTimeChanged(Level* level, __int64 delta, @@ -202,10 +213,6 @@ void NotGateTile::levelTimeChanged(Level* level, __int64 delta, } } -void NotGateTile::registerIcons(IconRegister* iconRegister) { - if (on) { - icon = iconRegister->registerIcon(L"redtorch_lit"); - } else { - icon = iconRegister->registerIcon(L"redtorch"); - } +bool NotGateTile::isMatching(int id) { + return id == Tile::redstoneTorch_off_Id || id == Tile::redstoneTorch_on_Id; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/NotGateTile.h b/Minecraft.World/Blocks/NotGateTile.h index 4eca5ed1f..2db622d24 100644 --- a/Minecraft.World/Blocks/NotGateTile.h +++ b/Minecraft.World/Blocks/NotGateTile.h @@ -38,10 +38,10 @@ protected: NotGateTile(int id, bool on); public: - int getTickDelay(); + int getTickDelay(Level* level); void onPlace(Level* level, int x, int y, int z); void onRemove(Level* level, int x, int y, int z, int id, int data); - bool getSignal(LevelSource* level, int x, int y, int z, int face); + int getSignal(LevelSource* level, int x, int y, int z, int face); private: bool hasNeighborSignal(Level* level, int x, int y, int z); @@ -50,7 +50,7 @@ public: void tick(Level* level, int x, int y, int z, Random* random); void neighborChanged(Level* level, int x, int y, int z, int type); - bool getDirectSignal(Level* level, int x, int y, int z, int face); + int getDirectSignal(LevelSource* level, int x, int y, int z, int face); int getResource(int data, Random* random, int playerBonusLevel); bool isSignalSource(); @@ -59,6 +59,5 @@ public: void animateTick(Level* level, int xt, int yt, int zt, Random* random); int cloneTileId(Level* level, int x, int y, int z); void levelTimeChanged(Level* level, __int64 delta, __int64 newTime); - - void registerIcons(IconRegister* iconRegister); + bool isMatching(int id); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/MusicTile.cpp b/Minecraft.World/Blocks/NoteBlockTile.cpp similarity index 68% rename from Minecraft.World/Blocks/MusicTile.cpp rename to Minecraft.World/Blocks/NoteBlockTile.cpp index 09fae12e9..8592a2ce9 100644 --- a/Minecraft.World/Blocks/MusicTile.cpp +++ b/Minecraft.World/Blocks/NoteBlockTile.cpp @@ -1,12 +1,13 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.entity.h" -#include "MusicTile.h" +#include "NoteBlockTile.h" #include "../Util/SoundTypes.h" -MusicTile::MusicTile(int id) : EntityTile(id, Material::wood) {} +NoteBlockTile::NoteBlockTile(int id) : BaseEntityTile(id, Material::wood) {} -void MusicTile::neighborChanged(Level* level, int x, int y, int z, int type) { +void NoteBlockTile::neighborChanged(Level* level, int x, int y, int z, + int type) { app.DebugPrintf("-------- Neighbour changed type %d\n", type); bool signal = level->hasNeighborSignal(x, y, z); std::shared_ptr mte = @@ -23,12 +24,12 @@ void MusicTile::neighborChanged(Level* level, int x, int y, int z, int type) { } // 4J-PB - Adding a TestUse for tooltip display -bool MusicTile::TestUse() { return true; } +bool NoteBlockTile::TestUse() { return true; } -bool MusicTile::use(Level* level, int x, int y, int z, - std::shared_ptr player, int clickedFace, - float clickX, float clickY, float clickZ, - bool soundOnly /*=false*/) // 4J added soundOnly param +bool NoteBlockTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly /*=false*/) // 4J added soundOnly param { if (soundOnly) return false; if (level->isClientSide) return true; @@ -42,8 +43,8 @@ bool MusicTile::use(Level* level, int x, int y, int z, return true; } -void MusicTile::attack(Level* level, int x, int y, int z, - std::shared_ptr player) { +void NoteBlockTile::attack(Level* level, int x, int y, int z, + std::shared_ptr player) { if (level->isClientSide) return; std::shared_ptr mte = std::dynamic_pointer_cast( @@ -51,12 +52,12 @@ void MusicTile::attack(Level* level, int x, int y, int z, if (mte != NULL) mte->playNote(level, x, y, z); } -std::shared_ptr MusicTile::newTileEntity(Level* level) { +std::shared_ptr NoteBlockTile::newTileEntity(Level* level) { return std::shared_ptr(new MusicTileEntity()); } -void MusicTile::triggerEvent(Level* level, int x, int y, int z, int i, - int note) { +bool NoteBlockTile::triggerEvent(Level* level, int x, int y, int z, int i, + int note) { float pitch = (float)pow(2, (note - 12) / 12.0); int iSound; @@ -77,9 +78,11 @@ void MusicTile::triggerEvent(Level* level, int x, int y, int z, int i, iSound = eSoundType_NOTE_HARP; break; } - app.DebugPrintf("MusicTile::triggerEvent - playSound - pitch = %f\n", + app.DebugPrintf("NoteBlockTile::triggerEvent - playSound - pitch = %f\n", pitch); level->playSound(x + 0.5, y + 0.5, z + 0.5, iSound, 3, pitch); level->addParticle(eParticleType_note, x + 0.5, y + 1.2, z + 0.5, note / 24.0, 0, 0); + + return true; } diff --git a/Minecraft.World/Blocks/MusicTile.h b/Minecraft.World/Blocks/NoteBlockTile.h similarity index 79% rename from Minecraft.World/Blocks/MusicTile.h rename to Minecraft.World/Blocks/NoteBlockTile.h index 6e82ee1d4..672289ef0 100644 --- a/Minecraft.World/Blocks/MusicTile.h +++ b/Minecraft.World/Blocks/NoteBlockTile.h @@ -1,11 +1,11 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class Player; -class MusicTile : public EntityTile { +class NoteBlockTile : public BaseEntityTile { public: - MusicTile(int id); + NoteBlockTile(int id); virtual void neighborChanged(Level* level, int x, int y, int z, int type); virtual bool TestUse(); virtual bool use(Level* level, int x, int y, int z, @@ -15,6 +15,6 @@ public: virtual void attack(Level* level, int x, int y, int z, std::shared_ptr player); virtual std::shared_ptr newTileEntity(Level* level); - virtual void triggerEvent(Level* level, int x, int y, int z, int i, + virtual bool triggerEvent(Level* level, int x, int y, int z, int i, int note); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index 33b095150..97b906927 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -149,10 +149,11 @@ bool PistonBaseTile::use(Level* level, int x, int y, int z, } void PistonBaseTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int targetData = getNewFacing(level, x, y, z, std::dynamic_pointer_cast(by)); - level->setData(x, y, z, targetData); + level->setData(x, y, z, targetData, Tile::UPDATE_CLIENTS); if (!level->isClientSide && !ignoreUpdate()) { checkIfExtend(level, x, y, z); } @@ -183,11 +184,10 @@ void PistonBaseTile::checkIfExtend(Level* level, int x, int y, int z) { if (extend && !isExtended(data)) { if (canPush(level, x, y, z, facing)) { - // level->setDataNoUpdate(x, y, z, facing | EXTENDED_BIT); level->tileEvent(x, y, z, id, TRIGGER_EXTEND, facing); } } else if (!extend && isExtended(data)) { - // level->setDataNoUpdate(x, y, z, facing); + level->setData(x, y, z, facing, UPDATE_CLIENTS); level->tileEvent(x, y, z, id, TRIGGER_CONTRACT, facing); } } @@ -206,38 +206,43 @@ void PistonBaseTile::checkIfExtend(Level* level, int x, int y, int z) { bool PistonBaseTile::getNeighborSignal(Level* level, int x, int y, int z, int facing) { // check adjacent neighbors, but not in push direction - if (facing != Facing::DOWN && level->getSignal(x, y - 1, z, Facing::DOWN)) + if (facing != Facing::DOWN && level->hasSignal(x, y - 1, z, Facing::DOWN)) return true; - if (facing != Facing::UP && level->getSignal(x, y + 1, z, Facing::UP)) + if (facing != Facing::UP && level->hasSignal(x, y + 1, z, Facing::UP)) return true; - if (facing != Facing::NORTH && level->getSignal(x, y, z - 1, Facing::NORTH)) + if (facing != Facing::NORTH && level->hasSignal(x, y, z - 1, Facing::NORTH)) return true; - if (facing != Facing::SOUTH && level->getSignal(x, y, z + 1, Facing::SOUTH)) + if (facing != Facing::SOUTH && level->hasSignal(x, y, z + 1, Facing::SOUTH)) return true; - if (facing != Facing::EAST && level->getSignal(x + 1, y, z, Facing::EAST)) + if (facing != Facing::EAST && level->hasSignal(x + 1, y, z, Facing::EAST)) return true; - if (facing != Facing::WEST && level->getSignal(x - 1, y, z, Facing::WEST)) + if (facing != Facing::WEST && level->hasSignal(x - 1, y, z, Facing::WEST)) return true; // check signals above - if (level->getSignal(x, y, z, 0)) return true; - if (level->getSignal(x, y + 2, z, 1)) return true; - if (level->getSignal(x, y + 1, z - 1, 2)) return true; - if (level->getSignal(x, y + 1, z + 1, 3)) return true; - if (level->getSignal(x - 1, y + 1, z, 4)) return true; - if (level->getSignal(x + 1, y + 1, z, 5)) return true; + if (level->hasSignal(x, y, z, 0)) return true; + if (level->hasSignal(x, y + 2, z, 1)) return true; + if (level->hasSignal(x, y + 1, z - 1, 2)) return true; + if (level->hasSignal(x, y + 1, z + 1, 3)) return true; + if (level->hasSignal(x - 1, y + 1, z, 4)) return true; + if (level->hasSignal(x + 1, y + 1, z, 5)) return true; return false; } -void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, +bool PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, int facing) { ignoreUpdate(true); - if (param1 == TRIGGER_EXTEND) { - level->setDataNoUpdate(x, y, z, facing | EXTENDED_BIT); - } else { - level->setDataNoUpdate(x, y, z, facing); + if (!level->isClientSide) { + bool extend = getNeighborSignal(level, x, y, z, facing); + + if (extend && param1 == TRIGGER_CONTRACT) { + level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS); + return false; + } else if (!extend && param1 == TRIGGER_EXTEND) { + return false; + } } if (param1 == TRIGGER_EXTEND) { @@ -265,12 +270,13 @@ void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, // doesn't happen because the client does actually receive an update // for this tile from the host after the event has been processed on // the cient. - level->setData(x, y, z, facing | EXTENDED_BIT, true); + level->setData(x, y, z, facing | EXTENDED_BIT, Tile::UPDATE_CLIENTS, + true); level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_OUT, 0.5f, level->random->nextFloat() * 0.25f + 0.6f); } else { - level->setDataNoUpdate(x, y, z, facing); + return false; } PIXEndNamedEvent(); } else if (param1 == TRIGGER_CONTRACT) { @@ -286,8 +292,8 @@ void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, } stopSharingIfServer(level, x, y, z); // 4J added - level->setTileAndDataNoUpdate(x, y, z, Tile::pistonMovingPiece_Id, - facing); + level->setTileAndData(x, y, z, Tile::pistonMovingPiece_Id, facing, + Tile::UPDATE_ALL); level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity( id, facing, facing, false, true)); @@ -308,9 +314,9 @@ void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, if (block == Tile::pistonMovingPiece_Id) { PIXBeginNamedEvent(0, "Contract sticky phase B\n"); - // the block two steps away is a moving piston block piece, - // so replace it with the real data, since it's probably - // this piston which is changing too fast + // the block two steps away is a moving piston block piece, so + // replace it with the real data, since it's probably this + // piston which is changing too fast std::shared_ptr tileEntity = level->getTileEntity(twoX, twoY, twoZ); if (tileEntity != NULL && @@ -344,24 +350,24 @@ void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, y += Facing::STEP_Y[facing]; z += Facing::STEP_Z[facing]; - level->setTileAndDataNoUpdate( - x, y, z, Tile::pistonMovingPiece_Id, blockData); + level->setTileAndData(x, y, z, Tile::pistonMovingPiece_Id, + blockData, Tile::UPDATE_ALL); level->setTileEntity( x, y, z, PistonMovingPiece::newMovingPieceEntity( block, blockData, facing, false, false)); ignoreUpdate(false); - level->setTile(twoX, twoY, twoZ, 0); + level->removeTile(twoX, twoY, twoZ); ignoreUpdate(true); } else if (!pistonPiece) { stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added ignoreUpdate(false); - level->setTile(x + Facing::STEP_X[facing], - y + Facing::STEP_Y[facing], - z + Facing::STEP_Z[facing], 0); + level->removeTile(x + Facing::STEP_X[facing], + y + Facing::STEP_Y[facing], + z + Facing::STEP_Z[facing]); ignoreUpdate(true); } PIXEndNamedEvent(); @@ -370,9 +376,9 @@ void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added ignoreUpdate(false); - level->setTile(x + Facing::STEP_X[facing], - y + Facing::STEP_Y[facing], - z + Facing::STEP_Z[facing], 0); + level->removeTile(x + Facing::STEP_X[facing], + y + Facing::STEP_Y[facing], + z + Facing::STEP_Z[facing]); ignoreUpdate(true); } @@ -381,6 +387,8 @@ void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1, } ignoreUpdate(false); + + return true; } void PistonBaseTile::updateShape( @@ -437,7 +445,7 @@ int PistonBaseTile::getFacing(int data) { return data & 0x7; } bool PistonBaseTile::isExtended(int data) { return (data & EXTENDED_BIT) != 0; } int PistonBaseTile::getNewFacing(Level* level, int x, int y, int z, - std::shared_ptr player) { + std::shared_ptr player) { if (Mth::abs((float)player->x - x) < 2 && Mth::abs((float)player->z - z) < 2) { // If the player is above the block, the slot is on the top @@ -482,9 +490,12 @@ bool PistonBaseTile::isPushable(int block, Level* level, int cx, int cy, int cz, return false; } - if (!allowDestroyable && Tile::tiles[block]->getPistonPushReaction() == - Material::PUSH_DESTROY) { - return false; + if (Tile::tiles[block]->getPistonPushReaction() == + Material::PUSH_DESTROY) { + if (!allowDestroyable) { + return false; + } + return true; } } @@ -589,16 +600,16 @@ bool PistonBaseTile::createPush(Level* level, int sx, int sy, int sz, // this block is destroyed when pushed Tile::tiles[block]->spawnResources(level, cx, cy, cz, level->getData(cx, cy, cz), 0); - // setting the tile to air is actually superflous, but - // helps vs multiplayer problems + // setting the tile to air is actually superflous, but helps vs + // multiplayer problems stopSharingIfServer(level, cx, cy, cz); // 4J added - level->setTile(cx, cy, cz, 0); + level->removeTile(cx, cy, cz); break; } if (i == MAX_PUSH_DEPTH) { - // we've reached the maximum push depth - // without finding air or a breakable block + // we've reached the maximum push depth without finding air or a + // breakable block return false; } @@ -607,6 +618,12 @@ bool PistonBaseTile::createPush(Level* level, int sx, int sy, int sz, cz += Facing::STEP_Z[facing]; } + int ex = cx; + int ey = cy; + int ez = cz; + int count = 0; + int tiles[MAX_PUSH_DEPTH + 1]; + while (cx != sx || cy != sy || cz != sz) { int nx = cx - Facing::STEP_X[facing]; int ny = cy - Facing::STEP_Y[facing]; @@ -618,10 +635,10 @@ bool PistonBaseTile::createPush(Level* level, int sx, int sy, int sz, stopSharingIfServer(level, cx, cy, cz); // 4J added if (block == id && nx == sx && ny == sy && nz == sz) { - level->setTileAndDataNoUpdate( + level->setTileAndData( cx, cy, cz, Tile::pistonMovingPiece_Id, facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0), - false); + Tile::UPDATE_NONE); level->setTileEntity( cx, cy, cz, PistonMovingPiece::newMovingPieceEntity( @@ -629,12 +646,30 @@ bool PistonBaseTile::createPush(Level* level, int sx, int sy, int sz, facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0), facing, true, false)); } else { - level->setTileAndDataNoUpdate( - cx, cy, cz, Tile::pistonMovingPiece_Id, data, false); + level->setTileAndData(cx, cy, cz, Tile::pistonMovingPiece_Id, data, + Tile::UPDATE_NONE); level->setTileEntity(cx, cy, cz, PistonMovingPiece::newMovingPieceEntity( block, data, facing, true, false)); } + tiles[count++] = block; + + cx = nx; + cy = ny; + cz = nz; + } + + cx = ex; + cy = ey; + cz = ez; + count = 0; + + while (cx != sx || cy != sy || cz != sz) { + int nx = cx - Facing::STEP_X[facing]; + int ny = cy - Facing::STEP_Y[facing]; + int nz = cz - Facing::STEP_Z[facing]; + + level->updateNeighborsAt(nx, ny, nz, tiles[count++]); cx = nx; cy = ny; diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index a21998648..eb038e6ae 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -58,7 +58,8 @@ public: float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); virtual void neighborChanged(Level* level, int x, int y, int z, int type); virtual void onPlace(Level* level, int x, int y, int z); @@ -67,7 +68,7 @@ private: bool getNeighborSignal(Level* level, int x, int y, int z, int facing); public: - virtual void triggerEvent(Level* level, int x, int y, int z, int param1, + virtual bool triggerEvent(Level* level, int x, int y, int z, int param1, int facing); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, @@ -82,7 +83,7 @@ public: static int getFacing(int data); static bool isExtended(int data); static int getNewFacing(Level* level, int x, int y, int z, - std::shared_ptr player); + std::shared_ptr player); private: static bool isPushable(int block, Level* level, int cx, int cy, int cz, @@ -92,4 +93,4 @@ private: int z); // 4J added bool createPush(Level* level, int sx, int sy, int sz, int facing); -}; +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/PistonExtensionTile.cpp b/Minecraft.World/Blocks/PistonExtensionTile.cpp index b407b1d00..1f7b0d52e 100644 --- a/Minecraft.World/Blocks/PistonExtensionTile.cpp +++ b/Minecraft.World/Blocks/PistonExtensionTile.cpp @@ -21,6 +21,23 @@ void PistonExtensionTile::clearOverrideTopTexture() { this->overrideTopTexture = NULL; } +void PistonExtensionTile::playerWillDestroy(Level* level, int x, int y, int z, + int data, + std::shared_ptr player) { + if (player->abilities.instabuild) { + int facing = getFacing(data); + int tile = level->getTile(x - Facing::STEP_X[facing], + y - Facing::STEP_Y[facing], + z - Facing::STEP_Z[facing]); + if (tile == Tile::pistonBase_Id || tile == Tile::pistonStickyBase_Id) { + level->removeTile(x - Facing::STEP_X[facing], + y - Facing::STEP_Y[facing], + z - Facing::STEP_Z[facing]); + } + } + Tile::playerWillDestroy(level, x, y, z, data, player); +} + void PistonExtensionTile::onRemove(Level* level, int x, int y, int z, int id, int data) { Tile::onRemove(level, x, y, z, id, data); @@ -35,7 +52,7 @@ void PistonExtensionTile::onRemove(Level* level, int x, int y, int z, int id, data = level->getData(x, y, z); if (PistonBaseTile::isExtended(data)) { Tile::tiles[t]->spawnResources(level, x, y, z, data, 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } } @@ -181,7 +198,7 @@ void PistonExtensionTile::neighborChanged(Level* level, int x, int y, int z, level->getTile(x - Facing::STEP_X[facing], y - Facing::STEP_Y[facing], z - Facing::STEP_Z[facing]); if (tile != Tile::pistonBase_Id && tile != Tile::pistonStickyBase_Id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } else { Tile::tiles[tile]->neighborChanged(level, x - Facing::STEP_X[facing], y - Facing::STEP_Y[facing], @@ -192,5 +209,10 @@ void PistonExtensionTile::neighborChanged(Level* level, int x, int y, int z, int PistonExtensionTile::getFacing(int data) { return data & 0x7; } int PistonExtensionTile::cloneTileId(Level* level, int x, int y, int z) { + int data = level->getData(x, y, z); + if ((data & STICKY_BIT) != 0) { + return Tile::pistonStickyBase_Id; + } + return Tile::pistonBase_Id; return 0; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/PistonExtensionTile.h b/Minecraft.World/Blocks/PistonExtensionTile.h index ac0196e87..f38d101ce 100644 --- a/Minecraft.World/Blocks/PistonExtensionTile.h +++ b/Minecraft.World/Blocks/PistonExtensionTile.h @@ -11,11 +11,13 @@ private: public: PistonExtensionTile(int id); - void setOverrideTopTexture(Icon* overrideTopTexture); - void clearOverrideTopTexture(); - void onRemove(Level* level, int x, int y, int z, int id, int data); + virtual void setOverrideTopTexture(Icon* overrideTopTexture); + virtual void clearOverrideTopTexture(); + virtual void playerWillDestroy(Level* level, int x, int y, int z, int data, + std::shared_ptr player); + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); virtual Icon* getTexture(int face, int data); - void registerIcons(IconRegister* iconRegister); + virtual void registerIcons(IconRegister* iconRegister); virtual int getRenderShape(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp index 27587ceca..33364559c 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp @@ -7,7 +7,7 @@ #include "../Util/AABB.h" PistonMovingPiece::PistonMovingPiece(int id) - : EntityTile(id, Material::piston, false) { + : BaseEntityTile(id, Material::piston, false) { setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME); } @@ -24,7 +24,7 @@ void PistonMovingPiece::onRemove(Level* level, int x, int y, int z, int id, std::dynamic_pointer_cast(tileEntity) != NULL) { std::dynamic_pointer_cast(tileEntity)->finalTick(); } else { - EntityTile::onRemove(level, x, y, z, id, data); + BaseEntityTile::onRemove(level, x, y, z, id, data); } } @@ -52,7 +52,7 @@ bool PistonMovingPiece::use( // blocks in the world if (!level->isClientSide && level->getTileEntity(x, y, z) == NULL) { // this block is no longer valid - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return true; } return false; @@ -78,7 +78,8 @@ void PistonMovingPiece::spawnResources(Level* level, int x, int y, int z, void PistonMovingPiece::neighborChanged(Level* level, int x, int y, int z, int type) { - if (!level->isClientSide && level->getTileEntity(x, y, z) == NULL) { + if (!level->isClientSide) { + level->getTileEntity(x, y, z) == NULL; } } diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.h b/Minecraft.World/Blocks/PistonMovingTileEntity.h index 92f266681..530c6e87d 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.h +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.h @@ -1,9 +1,9 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class PistonPieceEntity; -class PistonMovingPiece : public EntityTile { +class PistonMovingPiece : public BaseEntityTile { public: PistonMovingPiece(int id); diff --git a/Minecraft.World/Blocks/PlantTile.cpp b/Minecraft.World/Blocks/PlantTile.cpp index 9b03d0449..ee3f09669 100644 --- a/Minecraft.World/Blocks/PlantTile.cpp +++ b/Minecraft.World/Blocks/PlantTile.cpp @@ -8,14 +8,16 @@ void Bush::_init() { updateDefaultShape(); } -Bush::Bush(int id, Material* material) : Tile(id, material, false) { _init(); } +Bush::Bush(int id, Material* material) : Tile(id, material, false) { + _init(); +} Bush::Bush(int id) : Tile(id, Material::plant, false) { _init(); } // 4J Added override void Bush::updateDefaultShape() { float ss = 0.2f; - this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, ss * 3, 0.5f + ss); + setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, ss * 3, 0.5f + ss); } bool Bush::mayPlace(Level* level, int x, int y, int z) { @@ -40,7 +42,7 @@ void Bush::tick(Level* level, int x, int y, int z, Random* random) { void Bush::checkAlive(Level* level, int x, int y, int z) { if (!canSurvive(level, x, y, z)) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->setTileAndData(x, y, z, 0, 0, UPDATE_CLIENTS); } } diff --git a/Minecraft.World/Blocks/PortalTile.cpp b/Minecraft.World/Blocks/PortalTile.cpp index 64a9ee0f2..994e79a24 100644 --- a/Minecraft.World/Blocks/PortalTile.cpp +++ b/Minecraft.World/Blocks/PortalTile.cpp @@ -23,10 +23,13 @@ void PortalTile::tick(Level* level, int x, int y, int z, Random* random) { } if (y0 > 0 && !level->isSolidBlockingTile(x, y0 + 1, z)) { // spawn a pig man here - int result = 0; - bool spawned = - MonsterPlacerItem::spawnMobAt(level, 57, x + .5, y0 + 1.1, - z + .5, &result) != NULL; + int iResult = 0; + std::shared_ptr entity = SpawnEggItem::spawnMobAt( + level, 57, x + .5, y0 + 1.1, z + .5, &iResult); + if (entity != NULL) { + entity->changingDimensionDelay = + entity->getDimensionChangingDelay(); + } } } } @@ -42,11 +45,11 @@ void PortalTile::updateShape( level->getTile(x + 1, y, z) == id) { float xr = 8 / 16.0f; float yr = 2 / 16.0f; - this->setShape(0.5f - xr, 0, 0.5f - yr, 0.5f + xr, 1, 0.5f + yr); + setShape(0.5f - xr, 0, 0.5f - yr, 0.5f + xr, 1, 0.5f + yr); } else { float xr = 2 / 16.0f; float yr = 8 / 16.0f; - this->setShape(0.5f - xr, 0, 0.5f - yr, 0.5f + xr, 1, 0.5f + yr); + setShape(0.5f - xr, 0, 0.5f - yr, 0.5f + xr, 1, 0.5f + yr); } } @@ -89,14 +92,12 @@ bool PortalTile::trySpawnPortal(Level* level, int x, int y, int z, if (!actuallySpawn) return true; - level->noNeighborUpdate = true; for (int xx = 0; xx < 2; xx++) { for (int yy = 0; yy < 3; yy++) { - level->setTile(x + xd * xx, y + yy, z + zd * xx, - Tile::portalTile_Id); + level->setTileAndData(x + xd * xx, y + yy, z + zd * xx, + Tile::portalTile_Id, 0, Tile::UPDATE_CLIENTS); } } - level->noNeighborUpdate = false; return true; } @@ -114,7 +115,7 @@ void PortalTile::neighborChanged(Level* level, int x, int y, int z, int type) { while (level->getTile(x, yBottom - 1, z) == id) yBottom--; if (level->getTile(x, yBottom - 1, z) != Tile::obsidian_Id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } @@ -123,7 +124,7 @@ void PortalTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (height != 3 || level->getTile(x, yBottom + height, z) != Tile::obsidian_Id) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } @@ -132,7 +133,7 @@ void PortalTile::neighborChanged(Level* level, int x, int y, int z, int type) { bool ns = level->getTile(x, y, z - 1) == id || level->getTile(x, y, z + 1) == id; if (we && ns) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } @@ -142,7 +143,7 @@ void PortalTile::neighborChanged(Level* level, int x, int y, int z, int type) { (level->getTile(x - xd, y, z - zd) == Tile::obsidian_Id && level->getTile(x + xd, y, z + zd) == id) // )) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } } @@ -178,6 +179,8 @@ int PortalTile::getRenderLayer() { return 1; } void PortalTile::entityInside(Level* level, int x, int y, int z, std::shared_ptr entity) { + if (entity->GetType() == eTYPE_EXPERIENCEORB) return; // 4J added + if (entity->riding == NULL && entity->rider.lock() == NULL) entity->handleInsidePortal(); } @@ -187,7 +190,7 @@ void PortalTile::animateTick(Level* level, int xt, int yt, int zt, if (random->nextInt(100) == 0) { level->playLocalSound(xt + 0.5, yt + 0.5, zt + 0.5, eSoundType_PORTAL_PORTAL, 0.5f, - random->nextFloat() * 0.4f + 0.8f); + random->nextFloat() * 0.4f + 0.8f, false); } for (int i = 0; i < 4; i++) { double x = xt + random->nextFloat(); diff --git a/Minecraft.World/Blocks/PotatoTile.cpp b/Minecraft.World/Blocks/PotatoTile.cpp index b96ea84c1..28ca09e94 100644 --- a/Minecraft.World/Blocks/PotatoTile.cpp +++ b/Minecraft.World/Blocks/PotatoTile.cpp @@ -39,6 +39,7 @@ void PotatoTile::spawnResources(Level* level, int x, int y, int z, int data, void PotatoTile::registerIcons(IconRegister* iconRegister) { for (int i = 0; i < 4; i++) { - icons[i] = iconRegister->registerIcon(L"potatoes_" + _toString(i)); + icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + + _toString(i)); } } \ No newline at end of file diff --git a/Minecraft.World/Blocks/PoweredMetalTile.cpp b/Minecraft.World/Blocks/PoweredMetalTile.cpp new file mode 100644 index 000000000..905774d05 --- /dev/null +++ b/Minecraft.World/Blocks/PoweredMetalTile.cpp @@ -0,0 +1,12 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "PoweredMetalTile.h" + +PoweredMetalTile::PoweredMetalTile(int id) : MetalTile(id) {} + +bool PoweredMetalTile::isSignalSource() { return true; } + +int PoweredMetalTile::getSignal(LevelSource* level, int x, int y, int z, + int dir) { + return Redstone::SIGNAL_MAX; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/PoweredMetalTile.h b/Minecraft.World/Blocks/PoweredMetalTile.h new file mode 100644 index 000000000..e50548e36 --- /dev/null +++ b/Minecraft.World/Blocks/PoweredMetalTile.h @@ -0,0 +1,11 @@ +#pragma once + +#include "MetalTile.h" + +class PoweredMetalTile : public MetalTile { +public: + PoweredMetalTile(int id); + + virtual bool isSignalSource(); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/PoweredRailTile.cpp b/Minecraft.World/Blocks/PoweredRailTile.cpp new file mode 100644 index 000000000..98f8c7769 --- /dev/null +++ b/Minecraft.World/Blocks/PoweredRailTile.cpp @@ -0,0 +1,153 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.world.level.h" +#include "PoweredRailTile.h" + +PoweredRailTile::PoweredRailTile(int id) : BaseRailTile(id, true) {} + +Icon* PoweredRailTile::getTexture(int face, int data) { + if ((data & RAIL_DATA_BIT) == 0) { + return icon; + } else { + return iconPowered; + } +} + +void PoweredRailTile::registerIcons(IconRegister* iconRegister) { + BaseRailTile::registerIcons(iconRegister); + iconPowered = iconRegister->registerIcon(getIconName() + L"_powered"); +} + +bool PoweredRailTile::findPoweredRailSignal(Level* level, int x, int y, int z, + int data, bool std::forward, + int searchDepth) { + if (searchDepth >= 8) { + return false; + } + + int dir = data & RAIL_DIRECTION_MASK; + + bool checkBelow = true; + switch (dir) { + case DIR_FLAT_Z: + if (std::forward) { + z++; + } else { + z--; + } + break; + case DIR_FLAT_X: + if (std::forward) { + x--; + } else { + x++; + } + break; + case 2: + if (std::forward) { + x--; + } else { + x++; + y++; + checkBelow = false; + } + dir = DIR_FLAT_X; + break; + case 3: + if (std::forward) { + x--; + y++; + checkBelow = false; + } else { + x++; + } + dir = DIR_FLAT_X; + break; + case 4: + if (std::forward) { + z++; + } else { + z--; + y++; + checkBelow = false; + } + dir = DIR_FLAT_Z; + break; + case 5: + if (std::forward) { + z++; + y++; + checkBelow = false; + } else { + z--; + } + dir = DIR_FLAT_Z; + break; + } + + if (isSameRailWithPower(level, x, y, z, std::forward, searchDepth, dir)) { + return true; + } + if (checkBelow && isSameRailWithPower(level, x, y - 1, z, std::forward, + searchDepth, dir)) { + return true; + } + return false; +} + +bool PoweredRailTile::isSameRailWithPower(Level* level, int x, int y, int z, + bool std::forward, int searchDepth, + int dir) { + int tile = level->getTile(x, y, z); + + if (tile == id) { + int tileData = level->getData(x, y, z); + int myDir = tileData & RAIL_DIRECTION_MASK; + + if (dir == DIR_FLAT_X && + (myDir == DIR_FLAT_Z || myDir == 4 || myDir == 5)) { + return false; + } + if (dir == DIR_FLAT_Z && + (myDir == DIR_FLAT_X || myDir == 2 || myDir == 3)) { + return false; + } + + if ((tileData & RAIL_DATA_BIT) != 0) { + if (level->hasNeighborSignal(x, y, z)) { + return true; + } else { + return findPoweredRailSignal(level, x, y, z, tileData, + std::forward, searchDepth + 1); + } + } + } + + return false; +} + +void PoweredRailTile::updateState(Level* level, int x, int y, int z, int data, + int dir, int type) { + bool signal = level->hasNeighborSignal(x, y, z); + signal = signal || findPoweredRailSignal(level, x, y, z, data, true, 0) || + findPoweredRailSignal(level, x, y, z, data, false, 0); + + bool changed = false; + if (signal && (data & RAIL_DATA_BIT) == 0) { + level->setData(x, y, z, dir | RAIL_DATA_BIT, Tile::UPDATE_ALL); + changed = true; + } else if (!signal && (data & RAIL_DATA_BIT) != 0) { + level->setData(x, y, z, dir, Tile::UPDATE_ALL); + changed = true; + } + + // usually the level only updates neighbors that are in the same + // y plane as the current tile, but sloped rails may need to + // update tiles above or below it as well + if (changed) { + level->updateNeighborsAt(x, y - 1, z, id); + if (dir == 2 || dir == 3 || dir == 4 || dir == 5) { + level->updateNeighborsAt(x, y + 1, z, id); + } + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/PoweredRailTile.h b/Minecraft.World/Blocks/PoweredRailTile.h new file mode 100644 index 000000000..e9b8832f5 --- /dev/null +++ b/Minecraft.World/Blocks/PoweredRailTile.h @@ -0,0 +1,26 @@ +#pragma once + +#include "BaseRailTile.h" + +class PoweredRailTile : public BaseRailTile { + friend class ChunkRebuildData; + +protected: + Icon* iconPowered; + +public: + PoweredRailTile(int id); + + virtual Icon* getTexture(int face, int data); + virtual void registerIcons(IconRegister* iconRegister); + +protected: + virtual bool findPoweredRailSignal(Level* level, int x, int y, int z, + int data, bool std::forward, + int searchDepth); + virtual bool isSameRailWithPower(Level* level, int x, int y, int z, + bool std::forward, int searchDepth, + int dir); + virtual void updateState(Level* level, int x, int y, int z, int data, + int dir, int type); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/PressurePlateTile.cpp b/Minecraft.World/Blocks/PressurePlateTile.cpp index 655d9bb74..ef1223bb3 100644 --- a/Minecraft.World/Blocks/PressurePlateTile.cpp +++ b/Minecraft.World/Blocks/PressurePlateTile.cpp @@ -1,191 +1,51 @@ #include "../Platform/stdafx.h" -#include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.level.h" -#include "../Headers/net.minecraft.world.level.tile.h" -#include "../Headers/net.minecraft.world.phys.h" -#include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "PressurePlateTile.h" -#include "../Util/SoundTypes.h" PressurePlateTile::PressurePlateTile(int id, const std::wstring& tex, Material* material, Sensitivity sensitivity) - : Tile(id, material, false) { + : BasePressurePlateTile(id, tex, material) { this->sensitivity = sensitivity; - this->setTicking(true); - this->texture = tex; - float o = 1 / 16.0f; - setShape(o, 0, o, 1 - o, 0.5f / 16.0f, 1 - o); + // 4J Stu - Move this from base class to use virtual function + updateShape(getDataForSignal(Redstone::SIGNAL_MAX)); } -int PressurePlateTile::getTickDelay() { return 20; } - -AABB* PressurePlateTile::getAABB(Level* level, int x, int y, int z) { - return NULL; +int PressurePlateTile::getDataForSignal(int signal) { + return signal > 0 ? 1 : 0; } -bool PressurePlateTile::isSolidRender(bool isServerLevel) { return false; } - -bool PressurePlateTile::blocksLight() { return false; } - -bool PressurePlateTile::isCubeShaped() { return false; } - -bool PressurePlateTile::isPathfindable(LevelSource* level, int x, int y, - int z) { - return true; +int PressurePlateTile::getSignalForData(int data) { + return data == 1 ? Redstone::SIGNAL_MAX : 0; } -bool PressurePlateTile::mayPlace(Level* level, int x, int y, int z) { - return level->isTopSolidBlocking(x, y - 1, z) || - FenceTile::isFence(level->getTile(x, y - 1, z)); -} - -void PressurePlateTile::neighborChanged(Level* level, int x, int y, int z, - int type) { - bool replace = false; - - if (!level->isTopSolidBlocking(x, y - 1, z) && - !FenceTile::isFence(level->getTile(x, y - 1, z))) - replace = true; - - if (replace) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); - } -} - -void PressurePlateTile::tick(Level* level, int x, int y, int z, - Random* random) { - if (level->isClientSide) return; - if (level->getData(x, y, z) == 0) { - return; - } - - checkPressed(level, x, y, z); -} - -void PressurePlateTile::entityInside(Level* level, int x, int y, int z, - std::shared_ptr entity) { - if (level->isClientSide) return; - - if (level->getData(x, y, z) == 1) { - return; - } - - checkPressed(level, x, y, z); -} - -void PressurePlateTile::checkPressed(Level* level, int x, int y, int z) { - bool wasPressed = level->getData(x, y, z) == 1; - bool shouldBePressed = false; - - float b = 2 / 16.0f; +int PressurePlateTile::getSignalStrength(Level* level, int x, int y, int z) { std::vector >* entities = NULL; - bool entitiesToBeFreed = false; - if (sensitivity == PressurePlateTile::everything) - entities = level->getEntities( - nullptr, - AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b)); + if (sensitivity == everything) + entities = level->getEntities(nullptr, getSensitiveAABB(x, y, z)); + else if (sensitivity == mobs) + entities = level->getEntitiesOfClass(typeid(LivingEntity), + getSensitiveAABB(x, y, z)); + else if (sensitivity == players) + entities = level->getEntitiesOfClass(typeid(Player), + getSensitiveAABB(x, y, z)); + else + __debugbreak(); // 4J-JEV: We're going to delete something at a random + // location. - if (sensitivity == PressurePlateTile::mobs) { - entities = level->getEntitiesOfClass( - typeid(Mob), - AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b)); - entitiesToBeFreed = true; - } - if (sensitivity == PressurePlateTile::players) { - entities = level->getEntitiesOfClass( - typeid(Player), - AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b)); - entitiesToBeFreed = true; + if (entities != NULL && !entities->empty()) { + for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { + std::shared_ptr e = *it; + if (!e->isIgnoringTileTriggers()) { + if (sensitivity != everything) delete entities; + return Redstone::SIGNAL_MAX; + } + } } - if (!entities->empty()) { - shouldBePressed = true; - } - - if (shouldBePressed && !wasPressed) { - level->setData(x, y, z, 1); - level->updateNeighborsAt(x, y, z, id); - level->updateNeighborsAt(x, y - 1, z, id); - level->setTilesDirty(x, y, z, x, y, z); - - level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, - 0.3f, 0.6f); - } - if (!shouldBePressed && wasPressed) { - level->setData(x, y, z, 0); - level->updateNeighborsAt(x, y, z, id); - level->updateNeighborsAt(x, y - 1, z, id); - level->setTilesDirty(x, y, z, x, y, z); - - level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, - 0.3f, 0.5f); - } - - if (shouldBePressed) { - level->addToTickNextTick(x, y, z, id, getTickDelay()); - } - - if (entitiesToBeFreed) { - delete entities; - } -} - -void PressurePlateTile::onRemove(Level* level, int x, int y, int z, int id, - int data) { - if (data > 0) { - level->updateNeighborsAt(x, y, z, this->id); - level->updateNeighborsAt(x, y - 1, z, this->id); - } - Tile::onRemove(level, x, y, z, id, data); -} - -void PressurePlateTile::updateShape( - LevelSource* level, int x, int y, int z, int forceData, - std::shared_ptr - forceEntity) // 4J added forceData, forceEntity param -{ - bool pressed = level->getData(x, y, z) == 1; - - float o = 1 / 16.0f; - if (pressed) { - this->setShape(o, 0, o, 1 - o, 0.5f / 16.0f, 1 - o); - } else { - setShape(o, 0, o, 1 - o, 1 / 16.0f, 1 - o); - } -} - -bool PressurePlateTile::getSignal(LevelSource* level, int x, int y, int z, - int dir) { - return (level->getData(x, y, z)) > 0; -} - -bool PressurePlateTile::getDirectSignal(Level* level, int x, int y, int z, - int dir) { - if (level->getData(x, y, z) == 0) return false; - return (dir == 1); -} - -bool PressurePlateTile::isSignalSource() { return true; } - -void PressurePlateTile::updateDefaultShape() { - float x = 8 / 16.0f; - float y = 2 / 16.0f; - float z = 8 / 16.0f; - setShape(0.5f - x, 0.5f - y, 0.5f - z, 0.5f + x, 0.5f + y, 0.5f + z); -} - -bool PressurePlateTile::shouldTileTick(Level* level, int x, int y, int z) { - return level->getData(x, y, z) != 0; -} - -int PressurePlateTile::getPistonPushReaction() { - return Material::PUSH_DESTROY; -} - -void PressurePlateTile::registerIcons(IconRegister* iconRegister) { - icon = iconRegister->registerIcon(texture); -} + if (sensitivity != everything) delete entities; + return Redstone::SIGNAL_NONE; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/PressurePlateTile.h b/Minecraft.World/Blocks/PressurePlateTile.h index c8ea4e293..796b62181 100644 --- a/Minecraft.World/Blocks/PressurePlateTile.h +++ b/Minecraft.World/Blocks/PressurePlateTile.h @@ -1,55 +1,19 @@ #pragma once -#include "Tile.h" -#include "../Util/Definitions.h" - -class Random; - -class PressurePlateTile : public Tile { - friend class Tile; - -private: - std::wstring texture; +#include "BasePressurePlateTile.h" +class PressurePlateTile : public BasePressurePlateTile { public: enum Sensitivity { everything, mobs, players }; private: Sensitivity sensitivity; -protected: +public: PressurePlateTile(int id, const std::wstring& tex, Material* material, Sensitivity sensitivity); -public: - virtual int getTickDelay(); - virtual AABB* getAABB(Level* level, int x, int y, int z); - virtual bool isSolidRender(bool isServerLevel = false); - virtual bool blocksLight(); - virtual bool isCubeShaped(); - virtual bool isPathfindable(LevelSource* level, int x, int y, int z); - virtual bool mayPlace(Level* level, int x, int y, int z); - virtual void neighborChanged(Level* level, int x, int y, int z, int type); - virtual void tick(Level* level, int x, int y, int z, Random* random); - virtual void entityInside(Level* level, int x, int y, int z, - std::shared_ptr entity); - -private: - virtual void checkPressed(Level* level, int x, int y, int z); - -public: - virtual void onRemove(Level* level, int x, int y, int z, int id, int data); - virtual void updateShape( - LevelSource* level, int x, int y, int z, int forceData = -1, - std::shared_ptr forceEntity = std::shared_ptr< - TileEntity>()); // 4J added forceData, forceEntity param - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); - virtual bool isSignalSource(); - virtual void updateDefaultShape(); - virtual int getPistonPushReaction(); - void registerIcons(IconRegister* iconRegister); - - // 4J Added so we can check before we try to add a tile to the tick list if - // it's actually going to do seomthing - virtual bool shouldTileTick(Level* level, int x, int y, int z); -}; +protected: + virtual int getDataForSignal(int signal); + virtual int getSignalForData(int data); + virtual int getSignalStrength(Level* level, int x, int y, int z); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/PumpkinTile.cpp b/Minecraft.World/Blocks/PumpkinTile.cpp index 97a44f725..3b8da7a74 100644 --- a/Minecraft.World/Blocks/PumpkinTile.cpp +++ b/Minecraft.World/Blocks/PumpkinTile.cpp @@ -12,7 +12,7 @@ const std::wstring PumpkinTile::TEXTURE_FACE = L"pumpkin_face"; const std::wstring PumpkinTile::TEXTURE_LANTERN = L"pumpkin_jack"; PumpkinTile::PumpkinTile(int id, bool lit) - : DirectionalTile(id, Material::vegetable) { + : DirectionalTile(id, Material::vegetable, false) { iconTop = NULL; iconFace = NULL; setTicking(true); @@ -40,9 +40,9 @@ void PumpkinTile::onPlace(Level* level, int x, int y, int z) { if (!level->isClientSide) { // 4J - added limit of number of snowmen that can be spawned if (level->canCreateMore(eTYPE_SNOWMAN, Level::eSpawnType_Egg)) { - level->setTileNoUpdate(x, y, z, 0); - level->setTileNoUpdate(x, y - 1, z, 0); - level->setTileNoUpdate(x, y - 2, z, 0); + level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 2, z, 0, 0, Tile::UPDATE_CLIENTS); std::shared_ptr snowMan = std::shared_ptr(new SnowMan(level)); snowMan->moveTo(x + 0.5, y - 1.95, z + 0.5, 0, 0); @@ -59,9 +59,9 @@ void PumpkinTile::onPlace(Level* level, int x, int y, int z) { level, x, y - 1, z, level->getData(x, y - 1, z), 0); Tile::tiles[Tile::snow_Id]->spawnResources( level, x, y - 2, z, level->getData(x, y - 2, z), 0); - level->setTile(x, y, z, 0); - level->setTile(x, y - 1, z, 0); - level->setTile(x, y - 2, z, 0); + level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 2, z, 0, 0, Tile::UPDATE_CLIENTS); } } for (int i = 0; i < 120; i++) { @@ -81,15 +81,21 @@ void PumpkinTile::onPlace(Level* level, int x, int y, int z) { // 4J - added limit of number of golems that can be spawned if (level->canCreateMore(eTYPE_VILLAGERGOLEM, Level::eSpawnType_Egg)) { - level->setTileNoUpdate(x, y, z, 0); - level->setTileNoUpdate(x, y - 1, z, 0); - level->setTileNoUpdate(x, y - 2, z, 0); + level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 2, z, 0, 0, + Tile::UPDATE_CLIENTS); if (xArms) { - level->setTileNoUpdate(x - 1, y - 1, z, 0); - level->setTileNoUpdate(x + 1, y - 1, z, 0); + level->setTileAndData(x - 1, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); } else { - level->setTileNoUpdate(x, y - 1, z - 1, 0); - level->setTileNoUpdate(x, y - 1, z + 1, 0); + level->setTileAndData(x, y - 1, z - 1, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z + 1, 0, 0, + Tile::UPDATE_CLIENTS); } std::shared_ptr villagerGolem = @@ -125,9 +131,11 @@ void PumpkinTile::onPlace(Level* level, int x, int y, int z) { level, x, y - 1, z, level->getData(x, y - 1, z), 0); Tile::tiles[Tile::ironBlock_Id]->spawnResources( level, x, y - 2, z, level->getData(x, y - 2, z), 0); - level->setTile(x, y, z, 0); - level->setTile(x, y - 1, z, 0); - level->setTile(x, y - 2, z, 0); + level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 2, z, 0, 0, + Tile::UPDATE_CLIENTS); if (xArms) { Tile::tiles[Tile::ironBlock_Id]->spawnResources( @@ -136,8 +144,10 @@ void PumpkinTile::onPlace(Level* level, int x, int y, int z) { Tile::tiles[Tile::ironBlock_Id]->spawnResources( level, x + 1, y - 1, z, level->getData(x + 1, y - 1, z), 0); - level->setTile(x - 1, y - 1, z, 0); - level->setTile(x + 1, y - 1, z, 0); + level->setTileAndData(x - 1, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); } else { Tile::tiles[Tile::ironBlock_Id]->spawnResources( level, x, y - 1, z - 1, @@ -145,8 +155,10 @@ void PumpkinTile::onPlace(Level* level, int x, int y, int z) { Tile::tiles[Tile::ironBlock_Id]->spawnResources( level, x, y - 1, z + 1, level->getData(x, y - 1, z + 1), 0); - level->setTile(x, y - 1, z - 1, 0); - level->setTile(x, y - 1, z + 1, 0); + level->setTileAndData(x, y - 1, z - 1, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z + 1, 0, 0, + Tile::UPDATE_CLIENTS); } } } @@ -161,13 +173,15 @@ bool PumpkinTile::mayPlace(Level* level, int x, int y, int z) { } void PumpkinTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = Mth::floor(by->yRot * 4 / (360) + 2.5) & 3; - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); } void PumpkinTile::registerIcons(IconRegister* iconRegister) { - iconFace = iconRegister->registerIcon(lit ? TEXTURE_LANTERN : TEXTURE_FACE); - iconTop = iconRegister->registerIcon(L"pumpkin_top"); - icon = iconRegister->registerIcon(L"pumpkin_side"); + iconFace = iconRegister->registerIcon(getIconName() + L"_face_" + + (lit ? L"on" : L"off")); + iconTop = iconRegister->registerIcon(getIconName() + L"_top"); + icon = iconRegister->registerIcon(getIconName() + L"_side"); } diff --git a/Minecraft.World/Blocks/PumpkinTile.h b/Minecraft.World/Blocks/PumpkinTile.h index 0f6bdae8b..40c484b21 100644 --- a/Minecraft.World/Blocks/PumpkinTile.h +++ b/Minecraft.World/Blocks/PumpkinTile.h @@ -29,6 +29,7 @@ public: virtual void onPlace(Level* level, int x, int y, int z); virtual bool mayPlace(Level* level, int x, int y, int z); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); void registerIcons(IconRegister* iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/QuartzBlockTile.cpp b/Minecraft.World/Blocks/QuartzBlockTile.cpp index b67ae34b4..c5d02b1eb 100644 --- a/Minecraft.World/Blocks/QuartzBlockTile.cpp +++ b/Minecraft.World/Blocks/QuartzBlockTile.cpp @@ -13,15 +13,12 @@ int QuartzBlockTile::BLOCK_NAMES[QUARTZ_BLOCK_NAMES] = { IDS_TILE_QUARTZ_BLOCK_LINES, IDS_TILE_QUARTZ_BLOCK_LINES, IDS_TILE_QUARTZ_BLOCK_LINES}; -const std::wstring QuartzBlockTile::TEXTURE_TOP = L"quartzblock_top"; -const std::wstring QuartzBlockTile::TEXTURE_CHISELED_TOP = - L"quartzblock_chiseled_top"; -const std::wstring QuartzBlockTile::TEXTURE_LINES_TOP = - L"quartzblock_lines_top"; -const std::wstring QuartzBlockTile::TEXTURE_BOTTOM = L"quartzblock_bottom"; +const std::wstring QuartzBlockTile::TEXTURE_TOP = L"top"; +const std::wstring QuartzBlockTile::TEXTURE_CHISELED_TOP = L"chiseled_top"; +const std::wstring QuartzBlockTile::TEXTURE_LINES_TOP = L"lines_top"; +const std::wstring QuartzBlockTile::TEXTURE_BOTTOM = L"bottom"; const std::wstring QuartzBlockTile::TEXTURE_NAMES[QUARTZ_BLOCK_TEXTURES] = { - L"quartzblock_side", L"quartzblock_chiseled", L"quartzblock_lines", L"", - L""}; + L"side", L"chiseled", L"lines", L"", L""}; QuartzBlockTile::QuartzBlockTile(int id) : Tile(id, Material::stone) {} @@ -99,12 +96,16 @@ void QuartzBlockTile::registerIcons(IconRegister* iconRegister) { if (TEXTURE_NAMES[i].empty()) { icons[i] = icons[i - 1]; } else { - icons[i] = iconRegister->registerIcon(TEXTURE_NAMES[i]); + icons[i] = iconRegister->registerIcon(getIconName() + L"_" + + TEXTURE_NAMES[i]); } } - iconTop = iconRegister->registerIcon(TEXTURE_TOP); - iconChiseledTop = iconRegister->registerIcon(TEXTURE_CHISELED_TOP); - iconLinesTop = iconRegister->registerIcon(TEXTURE_LINES_TOP); - iconBottom = iconRegister->registerIcon(TEXTURE_BOTTOM); + iconTop = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_TOP); + iconChiseledTop = + iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_CHISELED_TOP); + iconLinesTop = + iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_LINES_TOP); + iconBottom = + iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_BOTTOM); } \ No newline at end of file diff --git a/Minecraft.World/Blocks/RailTile.cpp b/Minecraft.World/Blocks/RailTile.cpp index 0352cfabe..5d72f9906 100644 --- a/Minecraft.World/Blocks/RailTile.cpp +++ b/Minecraft.World/Blocks/RailTile.cpp @@ -1,558 +1,27 @@ #include "../Platform/stdafx.h" -#include "../Headers/net.minecraft.world.phys.h" -#include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.h" #include "RailTile.h" -RailTile::Rail::Rail(Level* level, int x, int y, int z) { - this->level = level; - this->x = x; - this->y = y; - this->z = z; - - int id = level->getTile(x, y, z); - - // 4J Stu - We saw a random crash near the end of development on XboxOne - // orignal version where the id here isn't a tile any more Adding this check - // in to avoid that crash - m_bValidRail = isRail(id); - if (m_bValidRail) { - int direction = level->getData(x, y, z); - if (((RailTile*)Tile::tiles[id])->usesDataBit) { - usesDataBit = true; - direction = direction & ~RAIL_DATA_BIT; - } else { - usesDataBit = false; - } - updateConnections(direction); - } -} - -RailTile::Rail::~Rail() { - for (int i = 0; i < connections.size(); i++) { - delete connections[i]; - } -} - -void RailTile::Rail::updateConnections(int direction) { - if (m_bValidRail) { - for (int i = 0; i < connections.size(); i++) { - delete connections[i]; - } - connections.clear(); - MemSect(50); - if (direction == DIR_FLAT_Z) { - connections.push_back(new TilePos(x, y, z - 1)); - connections.push_back(new TilePos(x, y, z + 1)); - } else if (direction == DIR_FLAT_X) { - connections.push_back(new TilePos(x - 1, y, z)); - connections.push_back(new TilePos(x + 1, y, z)); - } else if (direction == 2) { - connections.push_back(new TilePos(x - 1, y, z)); - connections.push_back(new TilePos(x + 1, y + 1, z)); - } else if (direction == 3) { - connections.push_back(new TilePos(x - 1, y + 1, z)); - connections.push_back(new TilePos(x + 1, y, z)); - } else if (direction == 4) { - connections.push_back(new TilePos(x, y + 1, z - 1)); - connections.push_back(new TilePos(x, y, z + 1)); - } else if (direction == 5) { - connections.push_back(new TilePos(x, y, z - 1)); - connections.push_back(new TilePos(x, y + 1, z + 1)); - } else if (direction == 6) { - connections.push_back(new TilePos(x + 1, y, z)); - connections.push_back(new TilePos(x, y, z + 1)); - } else if (direction == 7) { - connections.push_back(new TilePos(x - 1, y, z)); - connections.push_back(new TilePos(x, y, z + 1)); - } else if (direction == 8) { - connections.push_back(new TilePos(x - 1, y, z)); - connections.push_back(new TilePos(x, y, z - 1)); - } else if (direction == 9) { - connections.push_back(new TilePos(x + 1, y, z)); - connections.push_back(new TilePos(x, y, z - 1)); - } - MemSect(0); - } -} - -void RailTile::Rail::removeSoftConnections() { - if (m_bValidRail) { - for (unsigned int i = 0; i < connections.size(); i++) { - Rail* rail = getRail(connections[i]); - if (rail == NULL || !rail->connectsTo(this)) { - delete connections[i]; - connections.erase(connections.begin() + i); - i--; - } else { - delete connections[i]; - MemSect(50); - connections[i] = new TilePos(rail->x, rail->y, rail->z); - MemSect(0); - } - delete rail; - } - } -} - -bool RailTile::Rail::hasRail(int x, int y, int z) { - if (!m_bValidRail) return false; - if (isRail(level, x, y, z)) return true; - if (isRail(level, x, y + 1, z)) return true; - if (isRail(level, x, y - 1, z)) return true; - return false; -} - -RailTile::Rail* RailTile::Rail::getRail(TilePos* p) { - if (!m_bValidRail) return NULL; - if (isRail(level, p->x, p->y, p->z)) - return new Rail(level, p->x, p->y, p->z); - if (isRail(level, p->x, p->y + 1, p->z)) - return new Rail(level, p->x, p->y + 1, p->z); - if (isRail(level, p->x, p->y - 1, p->z)) - return new Rail(level, p->x, p->y - 1, p->z); - return NULL; -} - -bool RailTile::Rail::connectsTo(Rail* rail) { - if (m_bValidRail) { - AUTO_VAR(itEnd, connections.end()); - for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) { - TilePos* p = *it; // connections[i]; - if (p->x == rail->x && p->z == rail->z) { - return true; - } - } - } - return false; -} - -bool RailTile::Rail::hasConnection(int x, int y, int z) { - if (m_bValidRail) { - AUTO_VAR(itEnd, connections.end()); - for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) { - TilePos* p = *it; // connections[i]; - if (p->x == x && p->z == z) { - return true; - } - } - } - return false; -} - -int RailTile::Rail::countPotentialConnections() { - int count = 0; - - if (m_bValidRail) { - if (hasRail(x, y, z - 1)) count++; - if (hasRail(x, y, z + 1)) count++; - if (hasRail(x - 1, y, z)) count++; - if (hasRail(x + 1, y, z)) count++; - } - - return count; -} - -bool RailTile::Rail::canConnectTo(Rail* rail) { - if (!m_bValidRail) return false; - if (connectsTo(rail)) return true; - if (connections.size() == 2) { - return false; - } - if (connections.empty()) { - return true; - } - - TilePos* c = connections[0]; - - return true; -} - -void RailTile::Rail::connectTo(Rail* rail) { - if (m_bValidRail) { - MemSect(50); - connections.push_back(new TilePos(rail->x, rail->y, rail->z)); - MemSect(0); - - bool n = hasConnection(x, y, z - 1); - bool s = hasConnection(x, y, z + 1); - bool w = hasConnection(x - 1, y, z); - bool e = hasConnection(x + 1, y, z); - - int dir = -1; - - if (n || s) dir = DIR_FLAT_Z; - if (w || e) dir = DIR_FLAT_X; - - if (!usesDataBit) { - if (s && e && !n && !w) dir = 6; - if (s && w && !n && !e) dir = 7; - if (n && w && !s && !e) dir = 8; - if (n && e && !s && !w) dir = 9; - } - if (dir == DIR_FLAT_Z) { - if (isRail(level, x, y + 1, z - 1)) dir = 4; - if (isRail(level, x, y + 1, z + 1)) dir = 5; - } - if (dir == DIR_FLAT_X) { - if (isRail(level, x + 1, y + 1, z)) dir = 2; - if (isRail(level, x - 1, y + 1, z)) dir = 3; - } - - if (dir < 0) dir = DIR_FLAT_Z; - - int data = dir; - if (usesDataBit) { - data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir; - } - - level->setData(x, y, z, data); - } -} - -bool RailTile::Rail::hasNeighborRail(int x, int y, int z) { - if (!m_bValidRail) return false; - TilePos tp(x, y, z); - Rail* neighbor = getRail(&tp); - if (neighbor == NULL) return false; - neighbor->removeSoftConnections(); - bool retval = neighbor->canConnectTo(this); - delete neighbor; - return retval; -} - -void RailTile::Rail::place(bool hasSignal, bool first) { - if (m_bValidRail) { - bool n = hasNeighborRail(x, y, z - 1); - bool s = hasNeighborRail(x, y, z + 1); - bool w = hasNeighborRail(x - 1, y, z); - bool e = hasNeighborRail(x + 1, y, z); - - int dir = -1; - - if ((n || s) && !w && !e) dir = DIR_FLAT_Z; - if ((w || e) && !n && !s) dir = DIR_FLAT_X; - - if (!usesDataBit) { - if (s && e && !n && !w) dir = 6; - if (s && w && !n && !e) dir = 7; - if (n && w && !s && !e) dir = 8; - if (n && e && !s && !w) dir = 9; - } - if (dir == -1) { - if (n || s) dir = DIR_FLAT_Z; - if (w || e) dir = DIR_FLAT_X; - - if (!usesDataBit) { - if (hasSignal) { - if (s && e) dir = 6; - if (w && s) dir = 7; - if (e && n) dir = 9; - if (n && w) dir = 8; - } else { - if (n && w) dir = 8; - if (e && n) dir = 9; - if (w && s) dir = 7; - if (s && e) dir = 6; - } - } - } - - if (dir == DIR_FLAT_Z) { - if (isRail(level, x, y + 1, z - 1)) dir = 4; - if (isRail(level, x, y + 1, z + 1)) dir = 5; - } - if (dir == DIR_FLAT_X) { - if (isRail(level, x + 1, y + 1, z)) dir = 2; - if (isRail(level, x - 1, y + 1, z)) dir = 3; - } - - if (dir < 0) dir = DIR_FLAT_Z; - - updateConnections(dir); - - int data = dir; - if (usesDataBit) { - data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir; - } - - if (first || level->getData(x, y, z) != data) { - level->setData(x, y, z, data); - - AUTO_VAR(itEnd, connections.end()); - for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) { - Rail* neighbor = getRail(*it); - if (neighbor == NULL) continue; - neighbor->removeSoftConnections(); - - if (neighbor->canConnectTo(this)) { - neighbor->connectTo(this); - } - delete neighbor; - } - } - } -} - -bool RailTile::isRail(Level* level, int x, int y, int z) { - int tile = level->getTile(x, y, z); - return tile == Tile::rail_Id || tile == Tile::goldenRail_Id || - tile == Tile::detectorRail_Id; -} - -bool RailTile::isRail(int id) { - return id == Tile::rail_Id || id == Tile::goldenRail_Id || - id == Tile::detectorRail_Id; -} - -// 4jcraft, changed from isSolidRender() to false, _init was changed by -// 4jstudios to take in a bool to avoid calling isSolidRender before the vptr is -// set, -RailTile::RailTile(int id, bool usesDataBit) - : Tile(id, Material::decoration, false) { - this->usesDataBit = usesDataBit; - this->setShape(0, 0, 0, 1, 2 / 16.0f, 1); - - iconTurn = NULL; -} - -bool RailTile::isUsesDataBit() { return usesDataBit; } - -AABB* RailTile::getAABB(Level* level, int x, int y, int z) { return NULL; } - -bool RailTile::blocksLight() { return false; } - -bool RailTile::isSolidRender(bool isServerLevel) { return false; } - -HitResult* RailTile::clip(Level* level, int xt, int yt, int zt, Vec3* a, - Vec3* b) { - updateShape(level, xt, yt, zt); - return Tile::clip(level, xt, yt, zt, a, b); -} - -void RailTile::updateShape( - LevelSource* level, int x, int y, int z, int forceData, - std::shared_ptr - forceEntity) // 4J added forceData, forceEntity param -{ - int data = level->getData(x, y, z); - if (data >= 2 && data <= 5) { - setShape(0, 0, 0, 1, 2 / 16.0f + 0.5f, 1); - } else { - setShape(0, 0, 0, 1, 2 / 16.0f, 1); - } -} +RailTile::RailTile(int id) : BaseRailTile(id, false) {} Icon* RailTile::getTexture(int face, int data) { - if (usesDataBit) { - if (id == Tile::goldenRail_Id) { - if ((data & RAIL_DATA_BIT) == 0) { - return icon; - } else { - return iconTurn; // Actually the powered rail on version - } - } - } else if (data >= 6) + if (data >= 6) { return iconTurn; - return icon; -} - -bool RailTile::isCubeShaped() { return false; } - -int RailTile::getRenderShape() { return Tile::SHAPE_RAIL; } - -int RailTile::getResourceCount(Random random) { return 1; } - -bool RailTile::mayPlace(Level* level, int x, int y, int z) { - if (level->isTopSolidBlocking(x, y - 1, z)) { - return true; - } - return false; -} - -void RailTile::onPlace(Level* level, int x, int y, int z) { - if (!level->isClientSide) { - updateDir(level, x, y, z, true); - - if (id == Tile::goldenRail_Id) { - neighborChanged(level, x, y, z, id); - } - } -} - -void RailTile::neighborChanged(Level* level, int x, int y, int z, int type) { - if (level->isClientSide) return; - - int data = level->getData(x, y, z); - int dir = data; - if (usesDataBit) { - dir = dir & RAIL_DIRECTION_MASK; - } - bool remove = false; - - if (!level->isTopSolidBlocking(x, y - 1, z)) remove = true; - if (dir == 2 && !level->isTopSolidBlocking(x + 1, y, z)) remove = true; - if (dir == 3 && !level->isTopSolidBlocking(x - 1, y, z)) remove = true; - if (dir == 4 && !level->isTopSolidBlocking(x, y, z - 1)) remove = true; - if (dir == 5 && !level->isTopSolidBlocking(x, y, z + 1)) remove = true; - - if (remove) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); } else { - if (id == Tile::goldenRail_Id) { - bool signal = level->hasNeighborSignal(x, y, z); - signal = signal || - findGoldenRailSignal(level, x, y, z, data, true, 0) || - findGoldenRailSignal(level, x, y, z, data, false, 0); - - bool changed = false; - if (signal && (data & RAIL_DATA_BIT) == 0) { - level->setData(x, y, z, dir | RAIL_DATA_BIT); - changed = true; - } else if (!signal && (data & RAIL_DATA_BIT) != 0) { - level->setData(x, y, z, dir); - changed = true; - } - - // usually the level only updates neighbors that are in the same - // y plane as the current tile, but sloped rails may need to - // update tiles above or below it as well - if (changed) { - level->updateNeighborsAt(x, y - 1, z, id); - if (dir == 2 || dir == 3 || dir == 4 || dir == 5) { - level->updateNeighborsAt(x, y + 1, z, id); - } - } - } else if (type > 0 && Tile::tiles[type]->isSignalSource() && - !usesDataBit) { - Rail* rail = new Rail(level, x, y, z); - if (rail->countPotentialConnections() == 3) { - updateDir(level, x, y, z, false); - } - delete rail; - } + return icon; } } -void RailTile::updateDir(Level* level, int x, int y, int z, bool first) { - if (level->isClientSide) return; - Rail* rail = new Rail(level, x, y, z); - rail->place(level->hasNeighborSignal(x, y, z), first); - delete rail; -} - -bool RailTile::findGoldenRailSignal(Level* level, int x, int y, int z, int data, - bool forward, int searchDepth) { - if (searchDepth >= 8) { - return false; - } - - int dir = data & RAIL_DIRECTION_MASK; - - bool checkBelow = true; - switch (dir) { - case DIR_FLAT_Z: - if (forward) { - z++; - } else { - z--; - } - break; - case DIR_FLAT_X: - if (forward) { - x--; - } else { - x++; - } - break; - case 2: - if (forward) { - x--; - } else { - x++; - y++; - checkBelow = false; - } - dir = DIR_FLAT_X; - break; - case 3: - if (forward) { - x--; - y++; - checkBelow = false; - } else { - x++; - } - dir = DIR_FLAT_X; - break; - case 4: - if (forward) { - z++; - } else { - z--; - y++; - checkBelow = false; - } - dir = DIR_FLAT_Z; - break; - case 5: - if (forward) { - z++; - y++; - checkBelow = false; - } else { - z--; - } - dir = DIR_FLAT_Z; - break; - } - - if (isGoldenRailWithPower(level, x, y, z, forward, searchDepth, dir)) { - return true; - } - if (checkBelow && - isGoldenRailWithPower(level, x, y - 1, z, forward, searchDepth, dir)) { - return true; - } - return false; -} - -bool RailTile::isGoldenRailWithPower(Level* level, int x, int y, int z, - bool forward, int searchDepth, int dir) { - int tile = level->getTile(x, y, z); - if (tile == Tile::goldenRail_Id) { - int tileData = level->getData(x, y, z); - int myDir = tileData & RAIL_DIRECTION_MASK; - - if (dir == DIR_FLAT_X && - (myDir == DIR_FLAT_Z || myDir == 4 || myDir == 5)) { - return false; - } - if (dir == DIR_FLAT_Z && - (myDir == DIR_FLAT_X || myDir == 2 || myDir == 3)) { - return false; - } - - if ((tileData & RAIL_DATA_BIT) != 0) { - if (level->hasNeighborSignal(x, y, z)) { - return true; - } else { - return findGoldenRailSignal(level, x, y, z, tileData, forward, - searchDepth + 1); - } - } - } - return false; -} - -int RailTile::getPistonPushReaction() { return Material::PUSH_NORMAL; } - void RailTile::registerIcons(IconRegister* iconRegister) { - Tile::registerIcons(iconRegister); - if (id == Tile::goldenRail_Id) { - iconTurn = iconRegister->registerIcon(L"goldenRail_powered"); - } else { - iconTurn = iconRegister->registerIcon(L"rail_turn"); - } + BaseRailTile::registerIcons(iconRegister); + iconTurn = iconRegister->registerIcon(getIconName() + L"_turned"); } + +void RailTile::updateState(Level* level, int x, int y, int z, int data, int dir, + int type) { + if (type > 0 && Tile::tiles[type]->isSignalSource()) { + if (Rail(level, x, y, z).countPotentialConnections() == 3) { + updateDir(level, x, y, z, false); + } + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/RailTile.h b/Minecraft.World/Blocks/RailTile.h index ada085fca..b4a06cce8 100644 --- a/Minecraft.World/Blocks/RailTile.h +++ b/Minecraft.World/Blocks/RailTile.h @@ -1,96 +1,20 @@ #pragma once -#include "Tile.h" -#include "../Level/TilePos.h" -#include "../Util/Definitions.h" -class Random; -class HitResult; -class ChunkRebuildData; +#include "BaseRailTile.h" -class RailTile : public Tile { - friend class Tile; +class RailTile : public BaseRailTile { friend class ChunkRebuildData; -public: - static const int DIR_FLAT_Z = 0; - static const int DIR_FLAT_X = 1; - // the data bit is used by boosters and detectors, so they can't turn - static const int RAIL_DATA_BIT = 8; - static const int RAIL_DIRECTION_MASK = 7; - private: Icon* iconTurn; - bool usesDataBit; - - class Rail { - friend class RailTile; - - private: - Level* level; - int x, y, z; - bool usesDataBit; - std::vector connections; - bool m_bValidRail; // 4J added - - public: - Rail(Level* level, int x, int y, int z); - ~Rail(); - - private: - void updateConnections(int direction); - void removeSoftConnections(); - bool hasRail(int x, int y, int z); - Rail* getRail(TilePos* p); - bool connectsTo(Rail* rail); - bool hasConnection(int x, int y, int z); - int countPotentialConnections(); - bool canConnectTo(Rail* rail); - - private: - void connectTo(Rail* rail); - bool hasNeighborRail(int x, int y, int z); - - public: - void place(bool hasSignal, bool first); - }; - public: - static bool isRail(Level* level, int x, int y, int z); - static bool isRail(int id); + RailTile(int id); + + Icon* getTexture(int face, int data); + void registerIcons(IconRegister* iconRegister); protected: - RailTile(int id, bool usesDataBit); - -public: - using Tile::getResourceCount; - - bool isUsesDataBit(); - virtual AABB* getAABB(Level* level, int x, int y, int z); - virtual bool blocksLight(); - virtual bool isSolidRender(bool isServerLevel = false); - virtual HitResult* clip(Level* level, int xt, int yt, int zt, Vec3* a, - Vec3* b); - virtual void updateShape( - LevelSource* level, int x, int y, int z, int forceData = -1, - std::shared_ptr forceEntity = std::shared_ptr< - TileEntity>()); // 4J added forceData, forceEntity param - virtual Icon* getTexture(int face, int data); - virtual bool isCubeShaped(); - virtual int getRenderShape(); - virtual int getResourceCount(Random random); - virtual bool mayPlace(Level* level, int x, int y, int z); - virtual void onPlace(Level* level, int x, int y, int z); - virtual void neighborChanged(Level* level, int x, int y, int z, int type); - -private: - void updateDir(Level* level, int x, int y, int z, bool first); - bool findGoldenRailSignal(Level* level, int x, int y, int z, int data, - bool forward, int searchDepth); - bool isGoldenRailWithPower(Level* level, int x, int y, int z, bool forward, - int searchDepth, int dir); - -public: - virtual int getPistonPushReaction(); - void registerIcons(IconRegister* iconRegister); -}; + void updateState(Level* level, int x, int y, int z, int data, int dir, + int type); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/RecordPlayerTile.cpp b/Minecraft.World/Blocks/RecordPlayerTile.cpp deleted file mode 100644 index 2c3708158..000000000 --- a/Minecraft.World/Blocks/RecordPlayerTile.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include "../Platform/stdafx.h" -#include "../Headers/net.minecraft.world.entity.item.h" -#include "../Headers/net.minecraft.world.item.h" -#include "../Headers/net.minecraft.world.level.h" -#include "../Headers/net.minecraft.h" -#include "../Headers/net.minecraft.world.h" -#include "RecordPlayerTile.h" -#include "../Level/Events/LevelEvent.h" - -RecordPlayerTile::RecordPlayerTile(int id) : EntityTile(id, Material::wood) { - iconTop = NULL; -} - -Icon* RecordPlayerTile::getTexture(int face, int data) { - if (face == Facing::UP) { - return iconTop; - } - return icon; -} - -// 4J-PB - Adding a TestUse for tooltip display -bool RecordPlayerTile::TestUse(Level* level, int x, int y, int z, - std::shared_ptr player) { - // if the jukebox is empty, return true - if (level->getData(x, y, z) == 0) return false; - return true; -} - -bool RecordPlayerTile::use( - Level* level, int x, int y, int z, std::shared_ptr player, - int clickedFace, float clickX, float clickY, float clickZ, - bool soundOnly /*=false*/) // 4J added soundOnly param -{ - if (soundOnly) return false; - if (level->getData(x, y, z) == 0) return false; - dropRecording(level, x, y, z); - return true; -} - -void RecordPlayerTile::setRecord(Level* level, int x, int y, int z, - int record) { - if (level->isClientSide) return; - - std::shared_ptr rte = - std::dynamic_pointer_cast( - level->getTileEntity(x, y, z)); - rte->record = record; - rte->setChanged(); - - level->setData(x, y, z, 1); -} - -void RecordPlayerTile::dropRecording(Level* level, int x, int y, int z) { - if (level->isClientSide) return; - - std::shared_ptr rte = - std::dynamic_pointer_cast( - level->getTileEntity(x, y, z)); - if (rte == NULL) return; - - int oldRecord = rte->record; - if (oldRecord == 0) return; - - level->levelEvent(LevelEvent::SOUND_PLAY_RECORDING, x, y, z, 0); - // 4J-PB- the level event will play the music - // level->playStreamingMusic(L"", x, y, z); - rte->record = 0; - rte->setChanged(); - level->setData(x, y, z, 0); - - float s = 0.7f; - double xo = level->random->nextFloat() * s + (1 - s) * 0.5; - double yo = level->random->nextFloat() * s + (1 - s) * 0.2 + 0.6; - double zo = level->random->nextFloat() * s + (1 - s) * 0.5; - std::shared_ptr item = - std::shared_ptr(new ItemEntity( - level, x + xo, y + yo, z + zo, - std::shared_ptr(new ItemInstance(oldRecord, 1, 0)))); - item->throwTime = 10; - level->addEntity(item); -} - -void RecordPlayerTile::onRemove(Level* level, int x, int y, int z, int id, - int data) { - dropRecording(level, x, y, z); - Tile::onRemove(level, x, y, z, id, data); -} - -void RecordPlayerTile::spawnResources(Level* level, int x, int y, int z, - int data, float odds, int playerBonus) { - if (level->isClientSide) return; - Tile::spawnResources(level, x, y, z, data, odds, 0); -} - -std::shared_ptr RecordPlayerTile::newTileEntity(Level* level) { - return std::shared_ptr( - new RecordPlayerTile::Entity()); -} - -void RecordPlayerTile::registerIcons(IconRegister* iconRegister) { - icon = iconRegister->registerIcon(L"musicBlock"); - iconTop = iconRegister->registerIcon(L"jukebox_top"); -} \ No newline at end of file diff --git a/Minecraft.World/Blocks/RecordPlayerTile.h b/Minecraft.World/Blocks/RecordPlayerTile.h deleted file mode 100644 index df49121a3..000000000 --- a/Minecraft.World/Blocks/RecordPlayerTile.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "TileEntities/EntityTile.h" -#include "../IO/NBT/CompoundTag.h" -#include "TileEntities/TileEntity.h" - -class CompoundTag; -class ChunkRebuildData; - -class RecordPlayerTile : public EntityTile { - friend class Tile; - friend class ChunkRebuildData; - -public: - class Entity : public TileEntity { - public: - eINSTANCEOF GetType() { return eTYPE_RECORDPLAYERTILE; } - static TileEntity* create() { return new RecordPlayerTile::Entity(); } - - public: - int record; - Entity() : TileEntity(), record(0) {} - - virtual void load(CompoundTag* tag) { - TileEntity::load(tag); - record = tag->getInt(L"Record"); - } - - virtual void save(CompoundTag* tag) { - TileEntity::save(tag); - if (record > 0) tag->putInt(L"Record", record); - // return true; // 4J - TODO, in java there is no return type - // here but we can't change our derived class member function to not - // have one - investigate 4J Jev, took out the return statement, - // TileEntity::save is now virtual. Think this fixes above. - } - - // 4J Added - std::shared_ptr clone() { - std::shared_ptr result = - std::shared_ptr( - new RecordPlayerTile::Entity()); - TileEntity::clone(result); - - result->record = record; - - return result; - } - }; - -private: - Icon* iconTop; - -protected: - RecordPlayerTile(int id); - -public: - virtual Icon* getTexture(int face, int data); - virtual bool TestUse(Level* level, int x, int y, int z, - std::shared_ptr player); - virtual bool use(Level* level, int x, int y, int z, - std::shared_ptr player, int clickedFace, - float clickX, float clickY, float clickZ, - bool soundOnly = false); // 4J added soundOnly param - void setRecord(Level* level, int x, int y, int z, int record); - void dropRecording(Level* level, int x, int y, int z); - virtual void onRemove(Level* level, int x, int y, int z, int id, int data); - virtual void spawnResources(Level* level, int x, int y, int z, int data, - float odds, int playerBonus); - - virtual std::shared_ptr newTileEntity(Level* level); - void registerIcons(IconRegister* iconRegister); -}; diff --git a/Minecraft.World/Blocks/RedLightTile.cpp b/Minecraft.World/Blocks/RedLightTile.cpp index 627f473dd..64322d8f5 100644 --- a/Minecraft.World/Blocks/RedLightTile.cpp +++ b/Minecraft.World/Blocks/RedLightTile.cpp @@ -26,7 +26,8 @@ void RedlightTile::onPlace(Level* level, int x, int y, int z) { if (isLit && !level->hasNeighborSignal(x, y, z)) { level->addToTickNextTick(x, y, z, id, 4); } else if (!isLit && level->hasNeighborSignal(x, y, z)) { - level->setTile(x, y, z, Tile::redstoneLight_lit_Id); + level->setTileAndData(x, y, z, Tile::redstoneLight_lit_Id, 0, + UPDATE_CLIENTS); } } } @@ -37,7 +38,8 @@ void RedlightTile::neighborChanged(Level* level, int x, int y, int z, if (isLit && !level->hasNeighborSignal(x, y, z)) { level->addToTickNextTick(x, y, z, id, 4); } else if (!isLit && level->hasNeighborSignal(x, y, z)) { - level->setTile(x, y, z, Tile::redstoneLight_lit_Id); + level->setTileAndData(x, y, z, Tile::redstoneLight_lit_Id, 0, + UPDATE_CLIENTS); } } } @@ -45,7 +47,8 @@ void RedlightTile::neighborChanged(Level* level, int x, int y, int z, void RedlightTile::tick(Level* level, int x, int y, int z, Random* random) { if (!level->isClientSide) { if (isLit && !level->hasNeighborSignal(x, y, z)) { - level->setTile(x, y, z, Tile::redstoneLight_Id); + level->setTileAndData(x, y, z, Tile::redstoneLight_Id, 0, + UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/Blocks/RedStoneDustTile.cpp b/Minecraft.World/Blocks/RedStoneDustTile.cpp index fa7c63757..f4e3ce074 100644 --- a/Minecraft.World/Blocks/RedStoneDustTile.cpp +++ b/Minecraft.World/Blocks/RedStoneDustTile.cpp @@ -3,7 +3,10 @@ #include "RedStoneDustTile.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.h" #include "../Util/Direction.h" #include "DiodeTile.h" @@ -11,12 +14,10 @@ #include "../IO/Streams/IntBuffer.h" #include "../../Minecraft.Client/Rendering/Tesselator.h" -const std::wstring RedStoneDustTile::TEXTURE_CROSS = L"redstoneDust_cross"; -const std::wstring RedStoneDustTile::TEXTURE_LINE = L"redstoneDust_line"; -const std::wstring RedStoneDustTile::TEXTURE_CROSS_OVERLAY = - L"redstoneDust_cross_overlay"; -const std::wstring RedStoneDustTile::TEXTURE_LINE_OVERLAY = - L"redstoneDust_line_overlay"; +const std::wstring RedStoneDustTile::TEXTURE_CROSS = L"_cross"; +const std::wstring RedStoneDustTile::TEXTURE_LINE = L"_line"; +const std::wstring RedStoneDustTile::TEXTURE_CROSS_OVERLAY = L"_cross_overlay"; +const std::wstring RedStoneDustTile::TEXTURE_LINE_OVERLAY = L"_line_overlay"; RedStoneDustTile::RedStoneDustTile(int id) : Tile(id, Material::decoration, false) { @@ -63,7 +64,7 @@ int RedStoneDustTile::getColor(LevelSource* level, int x, int y, int z, bool RedStoneDustTile::mayPlace(Level* level, int x, int y, int z) { return level->isTopSolidBlocking(x, y - 1, z) || - level->getTile(x, y - 1, z) == Tile::lightGem_Id; + level->getTile(x, y - 1, z) == Tile::glowstone_Id; } void RedStoneDustTile::updatePowerStrength(Level* level, int x, int y, int z) { @@ -85,13 +86,18 @@ void RedStoneDustTile::updatePowerStrength(Level* level, int x, int y, int z, int old = level->getData(x, y, z); int target = 0; - this->shouldSignal = false; - bool neighborSignal = level->hasNeighborSignal(x, y, z); - this->shouldSignal = true; + target = checkTarget(level, xFrom, yFrom, zFrom, target); - if (neighborSignal) { - target = 15; - } else { + shouldSignal = false; + int neighborSignal = level->getBestNeighborSignal(x, y, z); + shouldSignal = true; + + if (neighborSignal > Redstone::SIGNAL_NONE && neighborSignal > target - 1) { + target = neighborSignal; + } + + { + int newTarget = 0; for (int i = 0; i < 4; i++) { int xt = x; int zt = z; @@ -100,56 +106,33 @@ void RedStoneDustTile::updatePowerStrength(Level* level, int x, int y, int z, if (i == 2) zt--; if (i == 3) zt++; - if (xt != xFrom || y != yFrom || zt != zFrom) - target = checkTarget(level, xt, y, zt, target); + if (xt != xFrom || zt != zFrom) + newTarget = checkTarget(level, xt, y, zt, newTarget); if (level->isSolidBlockingTile(xt, y, zt) && !level->isSolidBlockingTile(x, y + 1, z)) { - if (xt != xFrom || y + 1 != yFrom || zt != zFrom) - target = checkTarget(level, xt, y + 1, zt, target); + if ((xt != xFrom || zt != zFrom) && y >= yFrom) + newTarget = checkTarget(level, xt, y + 1, zt, newTarget); } else if (!level->isSolidBlockingTile(xt, y, zt)) { - if (xt != xFrom || y - 1 != yFrom || zt != zFrom) - target = checkTarget(level, xt, y - 1, zt, target); + if ((xt != xFrom || zt != zFrom) && y <= yFrom) + newTarget = checkTarget(level, xt, y - 1, zt, newTarget); } } - if (target > 0) + if (newTarget > target) + target = newTarget - 1; + else if (target > 0) target--; else target = 0; + + if (neighborSignal > target - 1) { + target = neighborSignal; + } } if (old != target) { - level->noNeighborUpdate = true; - level->setData(x, y, z, target); - level->setTilesDirty(x, y, z, x, y, z); - level->noNeighborUpdate = false; + level->setData(x, y, z, target, Tile::UPDATE_CLIENTS); - for (int i = 0; i < 4; i++) { - int xt = x; - int zt = z; - int yt = y - 1; - if (i == 0) xt--; - if (i == 1) xt++; - if (i == 2) zt--; - if (i == 3) zt++; - - if (level->isSolidBlockingTile(xt, y, zt)) yt += 2; - - int current = 0; - current = checkTarget(level, xt, y, zt, -1); - target = level->getData(x, y, z); - if (target > 0) target--; - if (current >= 0 && current != target) { - updatePowerStrength(level, xt, y, zt, x, y, z); - } - current = checkTarget(level, xt, yt, zt, -1); - target = level->getData(x, y, z); - if (target > 0) target--; - if (current >= 0 && current != target) { - updatePowerStrength(level, xt, yt, zt, x, y, z); - } - } - - if (old < target || target == 0) { + { toUpdate.insert(TilePos(x, y, z)); toUpdate.insert(TilePos(x - 1, y, z)); toUpdate.insert(TilePos(x + 1, y, z)); @@ -252,15 +235,14 @@ int RedStoneDustTile::checkTarget(Level* level, int x, int y, int z, void RedStoneDustTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (level->isClientSide) return; - int face = level->getData(x, y, z); bool ok = mayPlace(level, x, y, z); if (ok) { updatePowerStrength(level, x, y, z); } else { - spawnResources(level, x, y, z, face, 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, 0, 0); + level->removeTile(x, y, z); } Tile::neighborChanged(level, x, y, z, type); @@ -271,67 +253,66 @@ int RedStoneDustTile::getResource(int data, Random* random, return Item::redStone->id; } -bool RedStoneDustTile::getDirectSignal(Level* level, int x, int y, int z, - int dir) { - if (!shouldSignal) return false; +int RedStoneDustTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int dir) { + if (!shouldSignal) return Redstone::SIGNAL_NONE; return getSignal(level, x, y, z, dir); } -bool RedStoneDustTile::getSignal(LevelSource* level, int x, int y, int z, - int dir) { - if (!shouldSignal) return false; - if (level->getData(x, y, z) == 0) return false; +int RedStoneDustTile::getSignal(LevelSource* level, int x, int y, int z, + int dir) { + if (!shouldSignal) return Redstone::SIGNAL_NONE; + int data = level->getData(x, y, z); + if (data == Facing::DOWN) { + return Redstone::SIGNAL_NONE; + } - if (dir == 1) return true; + if (dir == Facing::UP) return data; - bool w = RedStoneDustTile::shouldReceivePowerFrom(level, x - 1, y, z, - Direction::WEST) || - (!level->isSolidBlockingTile(x - 1, y, z) && - RedStoneDustTile::shouldReceivePowerFrom(level, x - 1, y - 1, z, - Direction::UNDEFINED)); - bool e = RedStoneDustTile::shouldReceivePowerFrom(level, x + 1, y, z, - Direction::EAST) || - (!level->isSolidBlockingTile(x + 1, y, z) && - RedStoneDustTile::shouldReceivePowerFrom(level, x + 1, y - 1, z, - Direction::UNDEFINED)); - bool n = RedStoneDustTile::shouldReceivePowerFrom(level, x, y, z - 1, - Direction::NORTH) || - (!level->isSolidBlockingTile(x, y, z - 1) && - RedStoneDustTile::shouldReceivePowerFrom(level, x, y - 1, z - 1, - Direction::UNDEFINED)); - bool s = RedStoneDustTile::shouldReceivePowerFrom(level, x, y, z + 1, - Direction::SOUTH) || - (!level->isSolidBlockingTile(x, y, z + 1) && - RedStoneDustTile::shouldReceivePowerFrom(level, x, y - 1, z + 1, - Direction::UNDEFINED)); + bool w = + shouldReceivePowerFrom(level, x - 1, y, z, Direction::WEST) || + (!level->isSolidBlockingTile(x - 1, y, z) && + shouldReceivePowerFrom(level, x - 1, y - 1, z, Direction::UNDEFINED)); + bool e = + shouldReceivePowerFrom(level, x + 1, y, z, Direction::EAST) || + (!level->isSolidBlockingTile(x + 1, y, z) && + shouldReceivePowerFrom(level, x + 1, y - 1, z, Direction::UNDEFINED)); + bool n = + shouldReceivePowerFrom(level, x, y, z - 1, Direction::NORTH) || + (!level->isSolidBlockingTile(x, y, z - 1) && + shouldReceivePowerFrom(level, x, y - 1, z - 1, Direction::UNDEFINED)); + bool s = + shouldReceivePowerFrom(level, x, y, z + 1, Direction::SOUTH) || + (!level->isSolidBlockingTile(x, y, z + 1) && + shouldReceivePowerFrom(level, x, y - 1, z + 1, Direction::UNDEFINED)); if (!level->isSolidBlockingTile(x, y + 1, z)) { if (level->isSolidBlockingTile(x - 1, y, z) && - RedStoneDustTile::shouldReceivePowerFrom(level, x - 1, y + 1, z, - Direction::UNDEFINED)) + shouldReceivePowerFrom(level, x - 1, y + 1, z, + Direction::UNDEFINED)) w = true; if (level->isSolidBlockingTile(x + 1, y, z) && - RedStoneDustTile::shouldReceivePowerFrom(level, x + 1, y + 1, z, - Direction::UNDEFINED)) + shouldReceivePowerFrom(level, x + 1, y + 1, z, + Direction::UNDEFINED)) e = true; if (level->isSolidBlockingTile(x, y, z - 1) && - RedStoneDustTile::shouldReceivePowerFrom(level, x, y + 1, z - 1, - Direction::UNDEFINED)) + shouldReceivePowerFrom(level, x, y + 1, z - 1, + Direction::UNDEFINED)) n = true; if (level->isSolidBlockingTile(x, y, z + 1) && - RedStoneDustTile::shouldReceivePowerFrom(level, x, y + 1, z + 1, - Direction::UNDEFINED)) + shouldReceivePowerFrom(level, x, y + 1, z + 1, + Direction::UNDEFINED)) s = true; } - if (!n && !e && !w && !s && (dir >= 2 && dir <= 5)) return true; + if (!n && !e && !w && !s && (dir >= 2 && dir <= 5)) return data; - if (dir == 2 && n && (!w && !e)) return true; - if (dir == 3 && s && (!w && !e)) return true; - if (dir == 4 && w && (!n && !s)) return true; - if (dir == 5 && e && (!n && !s)) return true; + if (dir == 2 && n && (!w && !e)) return data; + if (dir == 3 && s && (!w && !e)) return data; + if (dir == 4 && w && (!n && !s)) return data; + if (dir == 5 && e && (!n && !s)) return data; - return false; + return Redstone::SIGNAL_NONE; } bool RedStoneDustTile::isSignalSource() { return shouldSignal; } @@ -395,7 +376,7 @@ bool RedStoneDustTile::shouldConnectTo(LevelSource* level, int x, int y, int z, int t = level->getTile(x, y, z); if (t == Tile::redStoneDust_Id) return true; if (t == 0) return false; - if (t == Tile::diode_off_Id || t == Tile::diode_on_Id) { + if (Tile::diode_off->isSameDiode(t)) { int data = level->getData(x, y, z); return direction == (data & DiodeTile::DIRECTION_MASK) || direction == @@ -427,10 +408,12 @@ int RedStoneDustTile::cloneTileId(Level* level, int x, int y, int z) { } void RedStoneDustTile::registerIcons(IconRegister* iconRegister) { - iconCross = iconRegister->registerIcon(TEXTURE_CROSS); - iconLine = iconRegister->registerIcon(TEXTURE_LINE); - iconCrossOver = iconRegister->registerIcon(TEXTURE_CROSS_OVERLAY); - iconLineOver = iconRegister->registerIcon(TEXTURE_LINE_OVERLAY); + iconCross = iconRegister->registerIcon(getIconName() + TEXTURE_CROSS); + iconLine = iconRegister->registerIcon(getIconName() + TEXTURE_LINE); + iconCrossOver = + iconRegister->registerIcon(getIconName() + TEXTURE_CROSS_OVERLAY); + iconLineOver = + iconRegister->registerIcon(getIconName() + TEXTURE_LINE_OVERLAY); icon = iconCross; } diff --git a/Minecraft.World/Blocks/RedStoneDustTile.h b/Minecraft.World/Blocks/RedStoneDustTile.h index 2367a9eb3..872f9ea58 100644 --- a/Minecraft.World/Blocks/RedStoneDustTile.h +++ b/Minecraft.World/Blocks/RedStoneDustTile.h @@ -52,8 +52,9 @@ private: public: virtual void neighborChanged(Level* level, int x, int y, int z, int type); virtual int getResource(int data, Random* random, int playerBonusLevel); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); virtual bool isSignalSource(); virtual void animateTick(Level* level, int x, int y, int z, Random* random); diff --git a/Minecraft.World/Blocks/RedStoneOreTile.cpp b/Minecraft.World/Blocks/RedStoneOreTile.cpp index 753543e7e..8e563d117 100644 --- a/Minecraft.World/Blocks/RedStoneOreTile.cpp +++ b/Minecraft.World/Blocks/RedStoneOreTile.cpp @@ -10,7 +10,7 @@ RedStoneOreTile::RedStoneOreTile(int id, bool lit) : Tile(id, Material::stone) { this->lit = lit; } -int RedStoneOreTile::getTickDelay() { return 30; } +int RedStoneOreTile::getTickDelay(Level* level) { return 30; } void RedStoneOreTile::attack(Level* level, int x, int y, int z, std::shared_ptr player) { @@ -25,7 +25,7 @@ void RedStoneOreTile::stepOn(Level* level, int x, int y, int z, } // 4J-PB - Adding a TestUse for tooltip display -bool RedStoneOreTile::TestUse() { return true; } +bool RedStoneOreTile::TestUse() { return id == Tile::redStoneOre_Id; } bool RedStoneOreTile::use( Level* level, int x, int y, int z, std::shared_ptr player, @@ -42,13 +42,13 @@ void RedStoneOreTile::interact(Level* level, int x, int y, int z) { poofParticles(level, x, y, z); if (level->isClientSide) return; // 4J added if (id == Tile::redStoneOre_Id) { - level->setTile(x, y, z, Tile::redStoneOre_lit_Id); + level->setTileAndUpdate(x, y, z, Tile::redStoneOre_lit_Id); } } void RedStoneOreTile::tick(Level* level, int x, int y, int z, Random* random) { if (id == Tile::redStoneOre_lit_Id) { - level->setTile(x, y, z, Tile::redStoneOre_Id); + level->setTileAndUpdate(x, y, z, Tile::redStoneOre_Id); } } diff --git a/Minecraft.World/Blocks/RedStoneOreTile.h b/Minecraft.World/Blocks/RedStoneOreTile.h index 53107f120..f6d578c72 100644 --- a/Minecraft.World/Blocks/RedStoneOreTile.h +++ b/Minecraft.World/Blocks/RedStoneOreTile.h @@ -10,7 +10,7 @@ private: public: RedStoneOreTile(int id, bool lit); - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual void attack(Level* level, int x, int y, int z, std::shared_ptr player); virtual void stepOn(Level* level, int x, int y, int z, diff --git a/Minecraft.World/Blocks/ReedTile.cpp b/Minecraft.World/Blocks/ReedTile.cpp index a2ff4b4fd..c9297caf4 100644 --- a/Minecraft.World/Blocks/ReedTile.cpp +++ b/Minecraft.World/Blocks/ReedTile.cpp @@ -26,10 +26,10 @@ void ReedTile::tick(Level* level, int x, int y, int z, Random* random) { if (height < 3) { int age = level->getData(x, y, z); if (age == 15) { - level->setTile(x, y + 1, z, id); - level->setData(x, y, z, 0); + level->setTileAndUpdate(x, y + 1, z, id); + level->setData(x, y, z, 0, Tile::UPDATE_NONE); } else { - level->setData(x, y, z, age + 1); + level->setData(x, y, z, age + 1, Tile::UPDATE_NONE); } } } @@ -55,8 +55,8 @@ void ReedTile::neighborChanged(Level* level, int x, int y, int z, int type) { const void ReedTile::checkAlive(Level* level, int x, int y, int z) { if (!canSurvive(level, x, y, z)) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); } } diff --git a/Minecraft.World/Blocks/RepeaterTile.cpp b/Minecraft.World/Blocks/RepeaterTile.cpp new file mode 100644 index 000000000..5afae29a9 --- /dev/null +++ b/Minecraft.World/Blocks/RepeaterTile.cpp @@ -0,0 +1,109 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "RepeaterTile.h" + +const double RepeaterTile::DELAY_RENDER_OFFSETS[4] = { + -1.0f / 16.0f, 1.0f / 16.0f, 3.0f / 16.0f, 5.0f / 16.0f}; +const int RepeaterTile::DELAYS[4] = {1, 2, 3, 4}; + +RepeaterTile::RepeaterTile(int id, bool on) : DiodeTile(id, on) {} + +bool RepeaterTile::use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly) { + if (soundOnly) return false; + + int data = level->getData(x, y, z); + int delay = (data & DELAY_MASK) >> DELAY_SHIFT; + delay = ((delay + 1) << DELAY_SHIFT) & DELAY_MASK; + + level->setData(x, y, z, delay | (data & DIRECTION_MASK), Tile::UPDATE_ALL); + return true; +} + +int RepeaterTile::getTurnOnDelay(int data) { + return DELAYS[(data & DELAY_MASK) >> DELAY_SHIFT] * 2; +} + +DiodeTile* RepeaterTile::getOnTile() { return Tile::diode_on; } + +DiodeTile* RepeaterTile::getOffTile() { return Tile::diode_off; } + +int RepeaterTile::getResource(int data, Random* random, int playerBonusLevel) { + return Item::repeater_Id; +} + +int RepeaterTile::cloneTileId(Level* level, int x, int y, int z) { + return Item::repeater_Id; +} + +int RepeaterTile::getRenderShape() { return SHAPE_REPEATER; } + +bool RepeaterTile::isLocked(LevelSource* level, int x, int y, int z, int data) { + return getAlternateSignal(level, x, y, z, data) > Redstone::SIGNAL_NONE; +} + +bool RepeaterTile::isAlternateInput(int tile) { return isDiode(tile); } + +void RepeaterTile::animateTick(Level* level, int xt, int yt, int zt, + Random* random) { + if (!on) return; + int data = level->getData(xt, yt, zt); + int dir = getDirection(data); + + double x = xt + 0.5f + (random->nextFloat() - 0.5f) * 0.2; + double y = yt + 0.4f + (random->nextFloat() - 0.5f) * 0.2; + double z = zt + 0.5f + (random->nextFloat() - 0.5f) * 0.2; + + double xo = 0; + double zo = 0; + + if (random->nextInt(2) == 0) { + // spawn on receiver + switch (dir) { + case Direction::SOUTH: + zo = -5.0f / 16.0f; + break; + case Direction::NORTH: + zo = 5.0f / 16.0f; + break; + case Direction::EAST: + xo = -5.0f / 16.0f; + break; + case Direction::WEST: + xo = 5.0f / 16.0f; + break; + } + } else { + // spawn on transmitter + int delay = (data & DELAY_MASK) >> DELAY_SHIFT; + switch (dir) { + case Direction::SOUTH: + zo = DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::NORTH: + zo = -DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::EAST: + xo = DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::WEST: + xo = -DELAY_RENDER_OFFSETS[delay]; + break; + } + } + + level->addParticle(eParticleType_reddust, x + xo, y, z + zo, 0, 0, 0); +} + +void RepeaterTile::onRemove(Level* level, int x, int y, int z, int id, + int data) { + DiodeTile::onRemove(level, x, y, z, id, data); + updateNeighborsInFront(level, x, y, z); +} + +bool RepeaterTile::TestUse() { return true; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/RepeaterTile.h b/Minecraft.World/Blocks/RepeaterTile.h new file mode 100644 index 000000000..b84d10d94 --- /dev/null +++ b/Minecraft.World/Blocks/RepeaterTile.h @@ -0,0 +1,42 @@ +#pragma once + +#include "DiodeTile.h" + +class RepeaterTile : public DiodeTile { +public: + static const int DELAY_MASK = DIRECTION_INV_MASK; + static const int DELAY_SHIFT = 2; + + static const double DELAY_RENDER_OFFSETS[4]; + +private: + static const int DELAYS[4]; + +public: + RepeaterTile(int id, bool on); + + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); + +protected: + virtual int getTurnOnDelay(int data); + virtual DiodeTile* getOnTile(); + virtual DiodeTile* getOffTile(); + +public: + virtual int getResource(int data, Random* random, int playerBonusLevel); + virtual int cloneTileId(Level* level, int x, int y, int z); + virtual int getRenderShape(); + virtual bool isLocked(LevelSource* level, int x, int y, int z, int data); + +protected: + virtual bool isAlternateInput(int tile); + +public: + void animateTick(Level* level, int xt, int yt, int zt, Random* random); + void onRemove(Level* level, int x, int y, int z, int id, int data); + + virtual bool TestUse(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/RotatedPillarTile.cpp b/Minecraft.World/Blocks/RotatedPillarTile.cpp new file mode 100644 index 000000000..4d4b47e54 --- /dev/null +++ b/Minecraft.World/Blocks/RotatedPillarTile.cpp @@ -0,0 +1,64 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.h" +#include "RotatedPillarTile.h" + +RotatedPillarTile::RotatedPillarTile(int id, Material* material) + : Tile(id, material) {} + +int RotatedPillarTile::getRenderShape() { return Tile::SHAPE_TREE; } + +int RotatedPillarTile::getPlacedOnFaceDataValue(Level* level, int x, int y, + int z, int face, float clickX, + float clickY, float clickZ, + int itemValue) { + int type = itemValue & MASK_TYPE; + int facing = 0; + + switch (face) { + case Facing::NORTH: + case Facing::SOUTH: + facing = FACING_Z; + break; + case Facing::EAST: + case Facing::WEST: + facing = FACING_X; + break; + case Facing::UP: + case Facing::DOWN: + facing = FACING_Y; + break; + } + + return type | facing; +} + +Icon* RotatedPillarTile::getTexture(int face, int data) { + int dir = data & MASK_FACING; + int type = data & MASK_TYPE; + + if (dir == FACING_Y && (face == Facing::UP || face == Facing::DOWN)) { + return getTopTexture(type); + } else if (dir == FACING_X && + (face == Facing::EAST || face == Facing::WEST)) { + return getTopTexture(type); + } else if (dir == FACING_Z && + (face == Facing::NORTH || face == Facing::SOUTH)) { + return getTopTexture(type); + } + + return getTypeTexture(type); +} + +Icon* RotatedPillarTile::getTopTexture(int type) { return iconTop; } + +int RotatedPillarTile::getSpawnResourcesAuxValue(int data) { + return data & MASK_TYPE; +} + +int RotatedPillarTile::getType(int data) { return data & MASK_TYPE; } + +std::shared_ptr RotatedPillarTile::getSilkTouchItemInstance( + int data) { + return std::shared_ptr( + new ItemInstance(id, 1, getType(data))); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/RotatedPillarTile.h b/Minecraft.World/Blocks/RotatedPillarTile.h new file mode 100644 index 000000000..75207acbf --- /dev/null +++ b/Minecraft.World/Blocks/RotatedPillarTile.h @@ -0,0 +1,36 @@ +#pragma once + +#include "Tile.h" + +class RotatedPillarTile : public Tile { +public: + static const int MASK_TYPE = 0x3; + static const int MASK_FACING = 0xC; + static const int FACING_Y = 0 << 2; + static const int FACING_X = 1 << 2; + static const int FACING_Z = 2 << 2; + +protected: + Icon* iconTop; + + RotatedPillarTile(int id, Material* material); + +public: + virtual int getRenderShape(); + virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, + int face, float clickX, float clickY, + float clickZ, int itemValue); + virtual Icon* getTexture(int face, int data); + +protected: + virtual Icon* getTypeTexture(int type) = 0; + + virtual Icon* getTopTexture(int type); + +public: + virtual int getSpawnResourcesAuxValue(int data); + virtual int getType(int data); + +protected: + virtual std::shared_ptr getSilkTouchItemInstance(int data); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/SaplingPlantTile.cpp b/Minecraft.World/Blocks/SaplingPlantTile.cpp index c2552b95d..951107a3c 100644 --- a/Minecraft.World/Blocks/SaplingPlantTile.cpp +++ b/Minecraft.World/Blocks/SaplingPlantTile.cpp @@ -6,7 +6,7 @@ #include "SaplingPlantTile.h" -const unsigned int Sapling::SAPLING_NAMES[SAPLING_NAMES_SIZE] = { +int Sapling::SAPLING_NAMES[SAPLING_NAMES_SIZE] = { IDS_TILE_SAPLING_OAK, IDS_TILE_SAPLING_SPRUCE, IDS_TILE_SAPLING_BIRCH, IDS_TILE_SAPLING_JUNGLE}; @@ -31,12 +31,7 @@ void Sapling::tick(Level* level, int x, int y, int z, Random* random) { if (level->getRawBrightness(x, y + 1, z) >= Level::MAX_BRIGHTNESS - 6) { if (random->nextInt(7) == 0) { - int data = level->getData(x, y, z); - if ((data & AGE_BIT) == 0) { - level->setData(x, y, z, data | AGE_BIT); - } else { - growTree(level, x, y, z, random); - } + advanceTree(level, x, y, z, random); } } } @@ -46,6 +41,15 @@ Icon* Sapling::getTexture(int face, int data) { return icons[data]; } +void Sapling::advanceTree(Level* level, int x, int y, int z, Random* random) { + int data = level->getData(x, y, z); + if ((data & AGE_BIT) == 0) { + level->setData(x, y, z, data | AGE_BIT, Tile::UPDATE_NONE); + } else { + growTree(level, x, y, z, random); + } +} + void Sapling::growTree(Level* level, int x, int y, int z, Random* random) { int data = level->getData(x, y, z) & TYPE_MASK; @@ -91,24 +95,26 @@ void Sapling::growTree(Level* level, int x, int y, int z, Random* random) { } } if (multiblock) { - level->setTileNoUpdate(x + ox, y, z + oz, 0); - level->setTileNoUpdate(x + ox + 1, y, z + oz, 0); - level->setTileNoUpdate(x + ox, y, z + oz + 1, 0); - level->setTileNoUpdate(x + ox + 1, y, z + oz + 1, 0); + level->setTileAndData(x + ox, y, z + oz, 0, 0, Tile::UPDATE_NONE); + level->setTileAndData(x + ox + 1, y, z + oz, 0, 0, Tile::UPDATE_NONE); + level->setTileAndData(x + ox, y, z + oz + 1, 0, 0, Tile::UPDATE_NONE); + level->setTileAndData(x + ox + 1, y, z + oz + 1, 0, 0, + Tile::UPDATE_NONE); } else { - level->setTileNoUpdate(x, y, z, 0); + level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_NONE); } if (!f->place(level, random, x + ox, y, z + oz)) { if (multiblock) { - level->setTileAndDataNoUpdate(x + ox, y, z + oz, this->id, data); - level->setTileAndDataNoUpdate(x + ox + 1, y, z + oz, this->id, - data); - level->setTileAndDataNoUpdate(x + ox, y, z + oz + 1, this->id, - data); - level->setTileAndDataNoUpdate(x + ox + 1, y, z + oz + 1, this->id, - data); + level->setTileAndData(x + ox, y, z + oz, id, data, + Tile::UPDATE_NONE); + level->setTileAndData(x + ox + 1, y, z + oz, id, data, + Tile::UPDATE_NONE); + level->setTileAndData(x + ox, y, z + oz + 1, id, data, + Tile::UPDATE_NONE); + level->setTileAndData(x + ox + 1, y, z + oz + 1, id, data, + Tile::UPDATE_NONE); } else { - level->setTileAndDataNoUpdate(x, y, z, this->id, data); + level->setTileAndData(x, y, z, id, data, Tile::UPDATE_NONE); } } if (f != NULL) delete f; diff --git a/Minecraft.World/Blocks/SaplingPlantTile.h b/Minecraft.World/Blocks/SaplingPlantTile.h index 92421a012..d71ec0d99 100644 --- a/Minecraft.World/Blocks/SaplingPlantTile.h +++ b/Minecraft.World/Blocks/SaplingPlantTile.h @@ -18,7 +18,7 @@ public: static const int SAPLING_NAMES_SIZE = 4; - static const unsigned int SAPLING_NAMES[SAPLING_NAMES_SIZE]; + static int SAPLING_NAMES[SAPLING_NAMES_SIZE]; private: static const std::wstring TEXTURE_NAMES[]; @@ -33,10 +33,10 @@ protected: public: virtual void updateDefaultShape(); // 4J Added override - void tick(Level* level, int x, int y, int z, Random* random); - - Icon* getTexture(int face, int data); + virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual Icon* getTexture(int face, int data); + virtual void advanceTree(Level* level, int x, int y, int z, Random* random); void growTree(Level* level, int x, int y, int z, Random* random); virtual unsigned int getDescriptionId(int iData = -1); diff --git a/Minecraft.World/Blocks/SignTile.cpp b/Minecraft.World/Blocks/SignTile.cpp index 914edd313..0ffd3e7b9 100644 --- a/Minecraft.World/Blocks/SignTile.cpp +++ b/Minecraft.World/Blocks/SignTile.cpp @@ -6,7 +6,7 @@ #include "SignTile.h" SignTile::SignTile(int id, eINSTANCEOF clas, bool onGround) - : EntityTile(id, Material::wood, false) { + : BaseEntityTile(id, Material::wood, false) { this->onGround = onGround; this->clas = clas; updateDefaultShape(); @@ -26,7 +26,7 @@ AABB* SignTile::getAABB(Level* level, int x, int y, int z) { return NULL; } AABB* SignTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); - return EntityTile::getTileAABB(level, x, y, z); + return BaseEntityTile::getTileAABB(level, x, y, z); } void SignTile::updateShape( @@ -97,10 +97,10 @@ void SignTile::neighborChanged(Level* level, int x, int y, int z, int type) { } if (remove) { spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } - EntityTile::neighborChanged(level, x, y, z, type); + BaseEntityTile::neighborChanged(level, x, y, z, type); } int SignTile::cloneTileId(Level* level, int x, int y, int z) { @@ -109,4 +109,4 @@ int SignTile::cloneTileId(Level* level, int x, int y, int z) { void SignTile::registerIcons(IconRegister* iconRegister) { // None -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/SignTile.h b/Minecraft.World/Blocks/SignTile.h index 162a7317b..b3e5ec372 100644 --- a/Minecraft.World/Blocks/SignTile.h +++ b/Minecraft.World/Blocks/SignTile.h @@ -1,12 +1,12 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" #include "TileEntities/TileEntity.h" #include "../Platform/stdafx.h" #include "Material.h" -class SignTile : public EntityTile { +class SignTile : public BaseEntityTile { friend class Tile; private: diff --git a/Minecraft.World/Blocks/SkullTile.cpp b/Minecraft.World/Blocks/SkullTile.cpp index d8ad46c56..251cb7833 100644 --- a/Minecraft.World/Blocks/SkullTile.cpp +++ b/Minecraft.World/Blocks/SkullTile.cpp @@ -1,11 +1,15 @@ #include "../Platform/stdafx.h" -#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.entity.h" +#include "../Entities/Mobs/WitherBoss.h" #include "../Headers/net.minecraft.h" #include "SkullTile.h" -SkullTile::SkullTile(int id) : EntityTile(id, Material::decoration, false) { +SkullTile::SkullTile(int id) + : BaseEntityTile(id, Material::decoration, false) { setShape(4.0f / 16.0f, 0, 4.0f / 16.0f, 12.0f / 16.0f, .5f, 12.0f / 16.0f); } @@ -47,13 +51,13 @@ void SkullTile::updateShape(LevelSource* level, int x, int y, int z, AABB* SkullTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); - return EntityTile::getAABB(level, x, y, z); + return BaseEntityTile::getAABB(level, x, y, z); } void SkullTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by) { int dir = Mth::floor(by->yRot * 4 / (360) + 2.5) & 3; - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); } std::shared_ptr SkullTile::newTileEntity(Level* level) { @@ -71,9 +75,7 @@ int SkullTile::cloneTileData(Level* level, int x, int y, int z) { if (skull != NULL) { return skull->getSkullType(); } - return 0; - // 4J Stu - Not added yet - // return EntityTile::cloneTileData(level, x, y, z); + return BaseEntityTile::cloneTileData(level, x, y, z); } int SkullTile::getSpawnResourcesAuxValue(int data) { return data; } @@ -86,23 +88,16 @@ void SkullTile::spawnResources(Level* level, int x, int y, int z, int data, void SkullTile::playerWillDestroy(Level* level, int x, int y, int z, int data, std::shared_ptr player) { - // 4J Stu - Not implemented -#if 0 - if (player->abilities.instabuild) - { - // prevent resource drop - data |= NO_DROP_BIT; - level.setData(x, y, z, data); - } - EntityTile::playerWillDestroy(level, x, y, z, data, player); -#endif + if (player->abilities.instabuild) { + // prevent resource drop + data |= NO_DROP_BIT; + level->setData(x, y, z, data, Tile::UPDATE_NONE); + } + BaseEntityTile::playerWillDestroy(level, x, y, z, data, player); } -void SkullTile::onRemove(Level* level, int x, int y, - int z) //, int id, int data) -{ +void SkullTile::onRemove(Level* level, int x, int y, int z, int id, int data) { if (level->isClientSide) return; - int data = level->getData(x, y, z); if ((data & NO_DROP_BIT) == 0) { std::shared_ptr item = std::shared_ptr( new ItemInstance(Item::skull_Id, 1, cloneTileData(level, x, y, z))); @@ -118,7 +113,7 @@ void SkullTile::onRemove(Level* level, int x, int y, popResource(level, x, y, z, item); } - EntityTile::onRemove(level, x, y, z, id, data); + BaseEntityTile::onRemove(level, x, y, z, id, data); } int SkullTile::getResource(int data, Random* random, int playerBonusLevel) { @@ -127,105 +122,175 @@ int SkullTile::getResource(int data, Random* random, int playerBonusLevel) { void SkullTile::checkMobSpawn(Level* level, int x, int y, int z, std::shared_ptr placedSkull) { - // 4J Stu - Don't have Withers yet, so don't need this -#if 0 - if (placedSkull.getSkullType() == SkullTileEntity.TYPE_WITHER && y >= 2 && level.difficulty > Difficulty.PEACEFUL) { + if (placedSkull->getSkullType() == SkullTileEntity::TYPE_WITHER && y >= 2 && + level->difficulty > Difficulty::PEACEFUL && !level->isClientSide) { + // Check wither boss spawn + int ss = Tile::soulsand_Id; - // check wither boss spawn + // North-south alignment + for (int zo = -2; zo <= 0; zo++) { + if ( // + level->getTile(x, y - 1, z + zo) == ss && // + level->getTile(x, y - 1, z + zo + 1) == ss && // + level->getTile(x, y - 2, z + zo + 1) == ss && // + level->getTile(x, y - 1, z + zo + 2) == ss && // + isSkullAt(level, x, y, z + zo, + SkullTileEntity::TYPE_WITHER) && // + isSkullAt(level, x, y, z + zo + 1, + SkullTileEntity::TYPE_WITHER) && // + isSkullAt(level, x, y, z + zo + 2, + SkullTileEntity::TYPE_WITHER)) { + level->setData(x, y, z + zo, NO_DROP_BIT, Tile::UPDATE_CLIENTS); + level->setData(x, y, z + zo + 1, NO_DROP_BIT, + Tile::UPDATE_CLIENTS); + level->setData(x, y, z + zo + 2, NO_DROP_BIT, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z + zo, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z + zo + 1, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z + zo + 2, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z + zo, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z + zo + 1, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 1, z + zo + 2, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y - 2, z + zo + 1, 0, 0, + Tile::UPDATE_CLIENTS); - final int ss = Tile.hellSand.id; + // 4J: Check that we can spawn a Wither + if (level->canCreateMore(eTYPE_WITHERBOSS, + Level::eSpawnType_Egg)) { + // 4J: Removed !isClientSide check because there's one + // earlier on + std::shared_ptr witherBoss = + std::shared_ptr(new WitherBoss(level)); + witherBoss->moveTo(x + 0.5, y - 1.45, z + zo + 1.5, 90, 0); + witherBoss->yBodyRot = 90; + witherBoss->makeInvulnerable(); + level->addEntity(witherBoss); + } else { + // 4J: Can't spawn, drop resource instead + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x, y - 1, z + zo, 0, 0); + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x, y - 1, z + zo + 1, 0, 0); + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x, y - 2, z + zo + 1, 0, 0); + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x, y - 1, z + zo + 2, 0, 0); - // north-south alignment - for (int zo = -2; zo <= 0; zo++) { - if ( // - level.getTile(x, y - 1, z + zo) == ss && // - level.getTile(x, y - 1, z + zo + 1) == ss && // - level.getTile(x, y - 2, z + zo + 1) == ss && // - level.getTile(x, y - 1, z + zo + 2) == ss && // - isSkullAt(level, x, y, z + zo, SkullTileEntity.TYPE_WITHER) && // - isSkullAt(level, x, y, z + zo + 1, SkullTileEntity.TYPE_WITHER) && // - isSkullAt(level, x, y, z + zo + 2, SkullTileEntity.TYPE_WITHER)) { + std::shared_ptr itemInstance = + std::shared_ptr(new ItemInstance( + Item::skull_Id, 3, SkullTileEntity::TYPE_WITHER)); + std::shared_ptr itemEntity = + std::shared_ptr(new ItemEntity( + level, x, y, z + zo + 1, itemInstance)); + level->addEntity(itemEntity); + } - level.setDataNoUpdate(x, y, z + zo, NO_DROP_BIT); - level.setDataNoUpdate(x, y, z + zo + 1, NO_DROP_BIT); - level.setDataNoUpdate(x, y, z + zo + 2, NO_DROP_BIT); - level.setTileNoUpdate(x, y, z + zo, 0); - level.setTileNoUpdate(x, y, z + zo + 1, 0); - level.setTileNoUpdate(x, y, z + zo + 2, 0); - level.setTileNoUpdate(x, y - 1, z + zo, 0); - level.setTileNoUpdate(x, y - 1, z + zo + 1, 0); - level.setTileNoUpdate(x, y - 1, z + zo + 2, 0); - level.setTileNoUpdate(x, y - 2, z + zo + 1, 0); + for (int i = 0; i < 120; i++) { + level->addParticle( + eParticleType_snowballpoof, + x + level->random->nextDouble(), + y - 2 + level->random->nextDouble() * 3.9, + z + zo + 1 + level->random->nextDouble(), 0, 0, 0); + } - if (!level.isClientSide) { - WitherBoss witherBoss = new WitherBoss(level); - witherBoss.moveTo(x + 0.5, y - 1.45, z + zo + 1.5, 90, 0); - witherBoss.yBodyRot = 90; - witherBoss.makeInvulnerable(); - level.addEntity(witherBoss); - } + level->tileUpdated(x, y, z + zo, 0); + level->tileUpdated(x, y, z + zo + 1, 0); + level->tileUpdated(x, y, z + zo + 2, 0); + level->tileUpdated(x, y - 1, z + zo, 0); + level->tileUpdated(x, y - 1, z + zo + 1, 0); + level->tileUpdated(x, y - 1, z + zo + 2, 0); + level->tileUpdated(x, y - 2, z + zo + 1, 0); - for (int i = 0; i < 120; i++) { - level.addParticle("snowballpoof", x + level.random.nextDouble(), y - 2 + level.random.nextDouble() * 3.9, z + zo + 1 + level.random.nextDouble(), 0, 0, 0); - } + return; + } + } + // West-east alignment + for (int xo = -2; xo <= 0; xo++) { + if ( // + level->getTile(x + xo, y - 1, z) == ss && // + level->getTile(x + xo + 1, y - 1, z) == ss && // + level->getTile(x + xo + 1, y - 2, z) == ss && // + level->getTile(x + xo + 2, y - 1, z) == ss && // + isSkullAt(level, x + xo, y, z, + SkullTileEntity::TYPE_WITHER) && // + isSkullAt(level, x + xo + 1, y, z, + SkullTileEntity::TYPE_WITHER) && // + isSkullAt(level, x + xo + 2, y, z, + SkullTileEntity::TYPE_WITHER)) { + level->setData(x + xo, y, z, NO_DROP_BIT, Tile::UPDATE_CLIENTS); + level->setData(x + xo + 1, y, z, NO_DROP_BIT, + Tile::UPDATE_CLIENTS); + level->setData(x + xo + 2, y, z, NO_DROP_BIT, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo, y, z, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo + 1, y, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo + 2, y, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo + 1, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo + 2, y - 1, z, 0, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(x + xo + 1, y - 2, z, 0, 0, + Tile::UPDATE_CLIENTS); - level.tileUpdated(x, y, z + zo, 0); - level.tileUpdated(x, y, z + zo + 1, 0); - level.tileUpdated(x, y, z + zo + 2, 0); - level.tileUpdated(x, y - 1, z + zo, 0); - level.tileUpdated(x, y - 1, z + zo + 1, 0); - level.tileUpdated(x, y - 1, z + zo + 2, 0); - level.tileUpdated(x, y - 2, z + zo + 1, 0); + // 4J: Check that we can spawn a Wither + if (level->canCreateMore(eTYPE_WITHERBOSS, + Level::eSpawnType_Egg)) { + // 4J: Removed !isClientSide check because there's one + // earlier on + std::shared_ptr witherBoss = + std::shared_ptr(new WitherBoss(level)); + witherBoss->moveTo(x + xo + 1.5, y - 1.45, z + .5, 0, 0); + witherBoss->makeInvulnerable(); + level->addEntity(witherBoss); + } else { + // 4J: Can't spawn, drop resource instead + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x + xo, y - 1, z, 0, 0); + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x + xo + 1, y - 1, z, 0, 0); + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x + xo + 1, y - 2, z, 0, 0); + Tile::tiles[Tile::soulsand_Id]->spawnResources( + level, x + xo + 2, y - 1, z, 0, 0); - return; - } - } - // west-east alignment - for (int xo = -2; xo <= 0; xo++) { - if ( // - level.getTile(x + xo, y - 1, z) == ss && // - level.getTile(x + xo + 1, y - 1, z) == ss && // - level.getTile(x + xo + 1, y - 2, z) == ss && // - level.getTile(x + xo + 2, y - 1, z) == ss && // - isSkullAt(level, x + xo, y, z, SkullTileEntity.TYPE_WITHER) && // - isSkullAt(level, x + xo + 1, y, z, SkullTileEntity.TYPE_WITHER) && // - isSkullAt(level, x + xo + 2, y, z, SkullTileEntity.TYPE_WITHER)) { + std::shared_ptr itemInstance = + std::shared_ptr(new ItemInstance( + Item::skull_Id, 3, SkullTileEntity::TYPE_WITHER)); + std::shared_ptr itemEntity = + std::shared_ptr(new ItemEntity( + level, x + xo + 1, y, z, itemInstance)); + level->addEntity(itemEntity); + } - level.setDataNoUpdate(x + xo, y, z, NO_DROP_BIT); - level.setDataNoUpdate(x + xo + 1, y, z, NO_DROP_BIT); - level.setDataNoUpdate(x + xo + 2, y, z, NO_DROP_BIT); - level.setTileNoUpdate(x + xo, y, z, 0); - level.setTileNoUpdate(x + xo + 1, y, z, 0); - level.setTileNoUpdate(x + xo + 2, y, z, 0); - level.setTileNoUpdate(x + xo, y - 1, z, 0); - level.setTileNoUpdate(x + xo + 1, y - 1, z, 0); - level.setTileNoUpdate(x + xo + 2, y - 1, z, 0); - level.setTileNoUpdate(x + xo + 1, y - 2, z, 0); + for (int i = 0; i < 120; i++) { + level->addParticle( + eParticleType_snowballpoof, + x + xo + 1 + level->random->nextDouble(), + y - 2 + level->random->nextDouble() * 3.9, + z + level->random->nextDouble(), 0, 0, 0); + } - if (!level.isClientSide) { - WitherBoss witherBoss = new WitherBoss(level); - witherBoss.moveTo(x + xo + 1.5, y - 1.45, z + .5, 0, 0); - witherBoss.makeInvulnerable(); - level.addEntity(witherBoss); - } + level->tileUpdated(x + xo, y, z, 0); + level->tileUpdated(x + xo + 1, y, z, 0); + level->tileUpdated(x + xo + 2, y, z, 0); + level->tileUpdated(x + xo, y - 1, z, 0); + level->tileUpdated(x + xo + 1, y - 1, z, 0); + level->tileUpdated(x + xo + 2, y - 1, z, 0); + level->tileUpdated(x + xo + 1, y - 2, z, 0); - for (int i = 0; i < 120; i++) { - level.addParticle("snowballpoof", x + xo + 1 + level.random.nextDouble(), y - 2 + level.random.nextDouble() * 3.9, z + level.random.nextDouble(), 0, 0, 0); - } - - level.tileUpdated(x + xo, y, z, 0); - level.tileUpdated(x + xo + 1, y, z, 0); - level.tileUpdated(x + xo + 2, y, z, 0); - level.tileUpdated(x + xo, y - 1, z, 0); - level.tileUpdated(x + xo + 1, y - 1, z, 0); - level.tileUpdated(x + xo + 2, y - 1, z, 0); - level.tileUpdated(x + xo + 1, y - 2, z, 0); - - return; - } - } - } -#endif + return; + } + } + } } bool SkullTile::isSkullAt(Level* level, int x, int y, int z, int skullType) { @@ -246,10 +311,9 @@ void SkullTile::registerIcons(IconRegister* iconRegister) { } Icon* SkullTile::getTexture(int face, int data) { - return Tile::hellSand->getTexture(face); + return Tile::soulsand->getTexture(face); } std::wstring SkullTile::getTileItemIconName() { - return L""; - // return SkullItem::ICON_NAMES[0]; -} + return getIconName() + L"_" + SkullItem::ICON_NAMES[0]; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/SkullTile.h b/Minecraft.World/Blocks/SkullTile.h index 0661af011..5c2642b01 100644 --- a/Minecraft.World/Blocks/SkullTile.h +++ b/Minecraft.World/Blocks/SkullTile.h @@ -1,10 +1,10 @@ #pragma once -#include "TileEntities/EntityTile.h" +#include "BaseEntityTile.h" class SkullTileEntity; -class SkullTile : public EntityTile { +class SkullTile : public BaseEntityTile { friend class Tile; public: @@ -17,7 +17,7 @@ public: SkullTile(int id); public: - using EntityTile::onRemove; + using BaseEntityTile::onRemove; int getRenderShape(); bool isSolidRender(bool isServerLevel = false); @@ -28,7 +28,7 @@ public: std::shared_ptr()); AABB* getAABB(Level* level, int x, int y, int z); void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by); std::shared_ptr newTileEntity(Level* level); int cloneTileId(Level* level, int x, int y, int z); int cloneTileData(Level* level, int x, int y, int z); @@ -37,7 +37,7 @@ public: int playerBonusLevel); void playerWillDestroy(Level* level, int x, int y, int z, int data, std::shared_ptr player); - void onRemove(Level* level, int x, int y, int z); //, int id, int data); + void onRemove(Level* level, int x, int y, int z, int id, int data); int getResource(int data, Random* random, int playerBonusLevel); void checkMobSpawn(Level* level, int x, int y, int z, std::shared_ptr placedSkull); diff --git a/Minecraft.World/Blocks/SmoothStoneBrickTile.cpp b/Minecraft.World/Blocks/SmoothStoneBrickTile.cpp index cdd33cd6c..154dbc550 100644 --- a/Minecraft.World/Blocks/SmoothStoneBrickTile.cpp +++ b/Minecraft.World/Blocks/SmoothStoneBrickTile.cpp @@ -3,8 +3,7 @@ #include "../Headers/net.minecraft.world.h" const std::wstring SmoothStoneBrickTile::TEXTURE_NAMES[] = { - L"stonebricksmooth", L"stonebricksmooth_mossy", L"stonebricksmooth_cracked", - L"stonebricksmooth_carved"}; + L"", L"mossy", L"cracked", L"carved"}; const unsigned int SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES [SMOOTH_STONE_BRICK_NAMES_LENGTH] = {IDS_TILE_STONE_BRICK_SMOOTH, @@ -32,6 +31,8 @@ void SmoothStoneBrickTile::registerIcons(IconRegister* iconRegister) { icons = new Icon*[SMOOTH_STONE_BRICK_NAMES_LENGTH]; for (int i = 0; i < SMOOTH_STONE_BRICK_NAMES_LENGTH; i++) { - icons[i] = iconRegister->registerIcon(TEXTURE_NAMES[i]); + std::wstring name = getIconName(); + if (!TEXTURE_NAMES[i].empty()) name += L"_" + TEXTURE_NAMES[i]; + icons[i] = iconRegister->registerIcon(name); } } \ No newline at end of file diff --git a/Minecraft.World/Blocks/SnowTile.cpp b/Minecraft.World/Blocks/SnowTile.cpp index 56dec83c2..801714d8b 100644 --- a/Minecraft.World/Blocks/SnowTile.cpp +++ b/Minecraft.World/Blocks/SnowTile.cpp @@ -15,7 +15,7 @@ int SnowTile::getResourceCount(Random* random) { return 4; } void SnowTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getBrightness(LightLayer::Block, x, y, z) > 11) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } diff --git a/Minecraft.World/Blocks/HellSandTile.cpp b/Minecraft.World/Blocks/SoulSandTile.cpp similarity index 60% rename from Minecraft.World/Blocks/HellSandTile.cpp rename to Minecraft.World/Blocks/SoulSandTile.cpp index 87ee3e113..fe240022f 100644 --- a/Minecraft.World/Blocks/HellSandTile.cpp +++ b/Minecraft.World/Blocks/SoulSandTile.cpp @@ -1,16 +1,16 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.phys.h" -#include "HellSandTile.h" +#include "SoulSandTile.h" -HellSandTile::HellSandTile(int id) : Tile(id, Material::sand) {} +SoulSandTile::SoulSandTile(int id) : Tile(id, Material::sand) {} -AABB* HellSandTile::getAABB(Level* level, int x, int y, int z) { +AABB* SoulSandTile::getAABB(Level* level, int x, int y, int z) { float r = 2 / 16.0f; return AABB::newTemp(x, y, z, x + 1, y + 1 - r, z + 1); } -void HellSandTile::entityInside(Level* level, int x, int y, int z, +void SoulSandTile::entityInside(Level* level, int x, int y, int z, std::shared_ptr entity) { entity->xd *= 0.4; entity->zd *= 0.4; diff --git a/Minecraft.World/Blocks/HellSandTile.h b/Minecraft.World/Blocks/SoulSandTile.h similarity index 81% rename from Minecraft.World/Blocks/HellSandTile.h rename to Minecraft.World/Blocks/SoulSandTile.h index c65c7b2e7..62d6b1e45 100644 --- a/Minecraft.World/Blocks/HellSandTile.h +++ b/Minecraft.World/Blocks/SoulSandTile.h @@ -2,9 +2,9 @@ #include "Tile.h" #include "../Util/Definitions.h" -class HellSandTile : public Tile { +class SoulSandTile : public Tile { public: - HellSandTile(int id); + SoulSandTile(int id); virtual AABB* getAABB(Level* level, int x, int y, int z); virtual void entityInside(Level* level, int x, int y, int z, std::shared_ptr entity); diff --git a/Minecraft.World/Blocks/SpringTile.cpp b/Minecraft.World/Blocks/SpringTile.cpp deleted file mode 100644 index 33e17cd8e..000000000 --- a/Minecraft.World/Blocks/SpringTile.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "../Platform/stdafx.h" -#include "../Headers/net.minecraft.world.level.h" - -#include "SpringTile.h" - -SpringTile::SpringTile(int id, int liquidTileId) : Tile(id, Material::water) { - this->liquidTileId = liquidTileId; - this->setTicking(true); -} - -void SpringTile::onPlace(Level* level, int x, int y, int z) { - Tile::onPlace(level, x, y, z); - if (level->isEmptyTile(x - 1, y, z)) - level->setTile(x - 1, y, z, liquidTileId); - if (level->isEmptyTile(x + 1, y, z)) - level->setTile(x + 1, y, z, liquidTileId); - if (level->isEmptyTile(x, y, z - 1)) - level->setTile(x, y, z - 1, liquidTileId); - if (level->isEmptyTile(x, y, z + 1)) - level->setTile(x, y, z + 1, liquidTileId); -} - -void SpringTile::tick(Level* level, int x, int y, int z, Random* random) { - Tile::tick(level, x, y, z, random); - if (level->isEmptyTile(x - 1, y, z)) - level->setTile(x - 1, y, z, liquidTileId); - if (level->isEmptyTile(x + 1, y, z)) - level->setTile(x + 1, y, z, liquidTileId); - if (level->isEmptyTile(x, y, z - 1)) - level->setTile(x, y, z - 1, liquidTileId); - if (level->isEmptyTile(x, y, z + 1)) - level->setTile(x, y, z + 1, liquidTileId); -} \ No newline at end of file diff --git a/Minecraft.World/Blocks/SpringTile.h b/Minecraft.World/Blocks/SpringTile.h deleted file mode 100644 index b4f78c158..000000000 --- a/Minecraft.World/Blocks/SpringTile.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "Tile.h" - -class SpringTile : public Tile { -private: - int liquidTileId; - -protected: - SpringTile(int id, int liquidTileId); - -public: - void onPlace(Level* level, int x, int y, int z); - - void tick(Level* level, int x, int y, int z, Random* random); -}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/StainedGlassBlock.cpp b/Minecraft.World/Blocks/StainedGlassBlock.cpp new file mode 100644 index 000000000..59f15729b --- /dev/null +++ b/Minecraft.World/Blocks/StainedGlassBlock.cpp @@ -0,0 +1,35 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.h" +#include "StainedGlassBlock.h" + +Icon* StainedGlassBlock::ICONS[StainedGlassBlock::ICONS_LENGTH]; + +StainedGlassBlock::StainedGlassBlock(int id, Material* material) + : HalfTransparentTile(id, L"glass", material, false) {} + +Icon* StainedGlassBlock::getTexture(int face, int data) { + return ICONS[data % ICONS_LENGTH]; +} + +int StainedGlassBlock::getSpawnResourcesAuxValue(int data) { return data; } + +int StainedGlassBlock::getItemAuxValueForBlockData(int data) { + return (~data & 0xf); +} + +int StainedGlassBlock::getRenderLayer() { return 1; } + +void StainedGlassBlock::registerIcons(IconRegister* iconRegister) { + for (int i = 0; i < ICONS_LENGTH; i++) { + ICONS[i] = iconRegister->registerIcon( + getIconName() + L"_" + + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForBlockData(i)]); + } +} + +int StainedGlassBlock::getResourceCount(Random* random) { return 0; } + +bool StainedGlassBlock::isSilkTouchable() { return true; } + +bool StainedGlassBlock::isCubeShaped() { return false; } diff --git a/Minecraft.World/Blocks/StainedGlassBlock.h b/Minecraft.World/Blocks/StainedGlassBlock.h new file mode 100644 index 000000000..d12f240cf --- /dev/null +++ b/Minecraft.World/Blocks/StainedGlassBlock.h @@ -0,0 +1,27 @@ +#pragma once + +#include "HalfTransparentTile.h" + +class StainedGlassBlock : public HalfTransparentTile { + friend class ChunkRebuildData; + +private: + static const int ICONS_LENGTH = 16; + static Icon* ICONS[ICONS_LENGTH]; + +public: + StainedGlassBlock(int id, Material* material); + + Icon* getTexture(int face, int data); + int getSpawnResourcesAuxValue(int data); + static int getItemAuxValueForBlockData(int data); + int getRenderLayer(); + void registerIcons(IconRegister* iconRegister); + int getResourceCount(Random* random); + +protected: + bool isSilkTouchable(); + +public: + bool isCubeShaped(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/StainedGlassPaneBlock.cpp b/Minecraft.World/Blocks/StainedGlassPaneBlock.cpp new file mode 100644 index 000000000..b1484a92d --- /dev/null +++ b/Minecraft.World/Blocks/StainedGlassPaneBlock.cpp @@ -0,0 +1,42 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.world.item.h" +#include "StainedGlassPaneBlock.h" + +Icon* StainedGlassPaneBlock::ICONS[StainedGlassPaneBlock::ICONS_COUNT]; +Icon* StainedGlassPaneBlock::EDGE_ICONS[StainedGlassPaneBlock::ICONS_COUNT]; + +StainedGlassPaneBlock::StainedGlassPaneBlock(int id) + : ThinFenceTile(id, L"glass", L"glass_pane_top", Material::glass, false) {} + +Icon* StainedGlassPaneBlock::getIconTexture(int face, int data) { + return ICONS[data % ICONS_COUNT]; +} + +Icon* StainedGlassPaneBlock::getEdgeTexture(int data) { + return EDGE_ICONS[~data & 0xF]; +} + +Icon* StainedGlassPaneBlock::getTexture(int face, int data) { + return getIconTexture(face, ~data & 0xf); +} + +int StainedGlassPaneBlock::getSpawnResourcesAuxValue(int data) { return data; } + +int StainedGlassPaneBlock::getItemAuxValueForBlockData(int data) { + return (data & 0xf); +} + +int StainedGlassPaneBlock::getRenderLayer() { return 1; } + +void StainedGlassPaneBlock::registerIcons(IconRegister* iconRegister) { + ThinFenceTile::registerIcons(iconRegister); + for (int i = 0; i < ICONS_COUNT; i++) { + ICONS[i] = iconRegister->registerIcon( + getIconName() + L"_" + + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForBlockData(i)]); + EDGE_ICONS[i] = iconRegister->registerIcon( + getIconName() + L"_pane_top_" + + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForBlockData(i)]); + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/StainedGlassPaneBlock.h b/Minecraft.World/Blocks/StainedGlassPaneBlock.h new file mode 100644 index 000000000..a5902cfab --- /dev/null +++ b/Minecraft.World/Blocks/StainedGlassPaneBlock.h @@ -0,0 +1,23 @@ +#pragma once + +#include "ThinFenceTile.h" + +class StainedGlassPaneBlock : public ThinFenceTile { + friend class ChunkRebuildData; + +private: + static const int ICONS_COUNT = 16; + static Icon* ICONS[ICONS_COUNT]; + static Icon* EDGE_ICONS[ICONS_COUNT]; + +public: + StainedGlassPaneBlock(int id); + + Icon* getIconTexture(int face, int data); + Icon* getEdgeTexture(int data); + Icon* getTexture(int face, int data); + int getSpawnResourcesAuxValue(int data); + static int getItemAuxValueForBlockData(int data); + int getRenderLayer(); + void registerIcons(IconRegister* iconRegister); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/StairTile.cpp b/Minecraft.World/Blocks/StairTile.cpp index db068ae80..f03aa9a08 100644 --- a/Minecraft.World/Blocks/StairTile.cpp +++ b/Minecraft.World/Blocks/StairTile.cpp @@ -282,45 +282,6 @@ void StairTile::addAABBs(Level* level, int x, int y, int z, AABB* box, } } - // int data = level->getData(x, y, z); - // int dir = data & 0x3; - // float lowerPieceY0 = 0; - // float lowerPieceY1 = 0.5f; - // float upperPieceY0 = 0.5f; - // float upperPieceY1 = 1; - - // if ((data & UPSIDEDOWN_BIT) != 0) - //{ - // lowerPieceY0 = .5f; - // lowerPieceY1 = 1; - // upperPieceY0 = 0; - // upperPieceY1 = .5f; - // } - - // setShape(0, lowerPieceY0, 0, 1, lowerPieceY1, 1); - // Tile::addAABBs(level, x, y, z, box, boxes); - - // if (dir == 0) - //{ - // setShape(0.5f, upperPieceY0, 0, 1, upperPieceY1, 1); - // Tile::addAABBs(level, x, y, z, box, boxes); - // } - // else if (dir == 1) - //{ - // setShape(0, upperPieceY0, 0, .5f, upperPieceY1, 1); - // Tile::addAABBs(level, x, y, z, box, boxes); - // } - // else if (dir == 2) - //{ - // setShape(0, upperPieceY0, 0.5f, 1, upperPieceY1, 1); - // Tile::addAABBs(level, x, y, z, box, boxes); - // } - // else if (dir == 3) - //{ - // setShape(0, upperPieceY0, 0, 1, upperPieceY1, .5f); - // Tile::addAABBs(level, x, y, z, box, boxes); - // } - setShape(0, 0, 0, 1, 1, 1); } @@ -363,7 +324,7 @@ Icon* StairTile::getTexture(int face, int data) { return base->getTexture(face, basedata); } -int StairTile::getTickDelay() { return base->getTickDelay(); } +int StairTile::getTickDelay(Level* level) { return base->getTickDelay(level); } AABB* StairTile::getTileAABB(Level* level, int x, int y, int z) { return base->getTileAABB(level, x, y, z); @@ -422,19 +383,23 @@ bool StairTile::use(Level* level, int x, int y, int z, return base->use(level, x, y, z, player, 0, 0, 0, 0); } -void StairTile::wasExploded(Level* level, int x, int y, int z) { - base->wasExploded(level, x, y, z); +void StairTile::wasExploded(Level* level, int x, int y, int z, + Explosion* explosion) { + base->wasExploded(level, x, y, z, explosion); } void StairTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { + std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3; int usd = level->getData(x, y, z) & UPSIDEDOWN_BIT; - if (dir == 0) level->setData(x, y, z, DIR_SOUTH | usd); - if (dir == 1) level->setData(x, y, z, DIR_WEST | usd); - if (dir == 2) level->setData(x, y, z, DIR_NORTH | usd); - if (dir == 3) level->setData(x, y, z, DIR_EAST | usd); + if (dir == 0) + level->setData(x, y, z, DIR_SOUTH | usd, Tile::UPDATE_CLIENTS); + if (dir == 1) level->setData(x, y, z, DIR_WEST | usd, Tile::UPDATE_CLIENTS); + if (dir == 2) + level->setData(x, y, z, DIR_NORTH | usd, Tile::UPDATE_CLIENTS); + if (dir == 3) level->setData(x, y, z, DIR_EAST | usd, Tile::UPDATE_CLIENTS); } int StairTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, diff --git a/Minecraft.World/Blocks/StairTile.h b/Minecraft.World/Blocks/StairTile.h index 2244d19f9..23d906835 100644 --- a/Minecraft.World/Blocks/StairTile.h +++ b/Minecraft.World/Blocks/StairTile.h @@ -37,11 +37,8 @@ public: std::shared_ptr()); // 4J added forceData, // forceEntity param bool isSolidRender(bool isServerLevel = false); - bool isCubeShaped(); - int getRenderShape(); - void setBaseShape(LevelSource* level, int x, int y, int z); static bool isStairs(int id); @@ -51,67 +48,48 @@ private: public: bool setStepShape(LevelSource* level, int x, int y, int z); bool setInnerPieceShape(LevelSource* level, int x, int y, int z); - void addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source); /** DELEGATES: **/ public: - void addLights(Level* level, int x, int y, int z); - - void animateTick(Level* level, int x, int y, int z, Random* random); - - void attack(Level* level, int x, int y, int z, - std::shared_ptr player); - - void destroy(Level* level, int x, int y, int z, int data); - - int getLightColor(LevelSource* level, int x, int y, int z, int tileId = -1); - float getBrightness(LevelSource* level, int x, int y, int z); - - float getExplosionResistance(std::shared_ptr source); - - int getRenderLayer(); - - Icon* getTexture(int face, int data); - - int getTickDelay(); - - AABB* getTileAABB(Level* level, int x, int y, int z); - - void handleEntityInside(Level* level, int x, int y, int z, - std::shared_ptr e, Vec3* current); - - bool mayPick(); - - bool mayPick(int data, bool liquid); - - bool mayPlace(Level* level, int x, int y, int z); - - void onPlace(Level* level, int x, int y, int z); - - void onRemove(Level* level, int x, int y, int z, int id, int data); - - void prepareRender(Level* level, int x, int y, int z); - - void stepOn(Level* level, int x, int y, int z, - std::shared_ptr entity); - - void tick(Level* level, int x, int y, int z, Random* random); - - bool use(Level* level, int x, int y, int z, std::shared_ptr player, - int clickedFace, float clickX, float clickY, float clickZ, - bool soundOnly = false); // 4J added soundOnly param - - void wasExploded(Level* level, int x, int y, int z); - - void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); - int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, - float clickX, float clickY, float clickZ, - int itemValue); - - HitResult* clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b); - + virtual void addLights(Level* level, int x, int y, int z); + virtual void animateTick(Level* level, int x, int y, int z, Random* random); + virtual void attack(Level* level, int x, int y, int z, + std::shared_ptr player); + virtual void destroy(Level* level, int x, int y, int z, int data); + virtual int getLightColor(LevelSource* level, int x, int y, int z, + int tileId = -1); + virtual float getBrightness(LevelSource* level, int x, int y, int z); + virtual float getExplosionResistance(std::shared_ptr source); + virtual int getRenderLayer(); + virtual Icon* getTexture(int face, int data); + virtual int getTickDelay(Level* level); + virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual void handleEntityInside(Level* level, int x, int y, int z, + std::shared_ptr e, Vec3* current); + virtual bool mayPick(); + virtual bool mayPick(int data, bool liquid); + virtual bool mayPlace(Level* level, int x, int y, int z); + virtual void onPlace(Level* level, int x, int y, int z); + virtual void onRemove(Level* level, int x, int y, int z, int id, int data); + virtual void prepareRender(Level* level, int x, int y, int z); + virtual void stepOn(Level* level, int x, int y, int z, + std::shared_ptr entity); + virtual void tick(Level* level, int x, int y, int z, Random* random); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); // 4J added soundOnly param + virtual void wasExploded(Level* level, int x, int y, int z, + Explosion* explosion); + virtual void setPlacedBy(Level* level, int x, int y, int z, + std::shared_ptr by, + std::shared_ptr itemInstance); + virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, + int face, float clickX, float clickY, + float clickZ, int itemValue); + virtual HitResult* clip(Level* level, int xt, int yt, int zt, Vec3* a, + Vec3* b); virtual void registerIcons(IconRegister* iconRegister); }; diff --git a/Minecraft.World/Blocks/StemTile.cpp b/Minecraft.World/Blocks/StemTile.cpp index 06e28b8a2..63321e872 100644 --- a/Minecraft.World/Blocks/StemTile.cpp +++ b/Minecraft.World/Blocks/StemTile.cpp @@ -32,7 +32,7 @@ void StemTile::tick(Level* level, int x, int y, int z, Random* random) { int age = level->getData(x, y, z); if (age < 7) { age++; - level->setData(x, y, z, age); + level->setData(x, y, z, age, Tile::UPDATE_CLIENTS); } else { if (level->getTile(x - 1, y, z) == fruit->id) return; if (level->getTile(x + 1, y, z) == fruit->id) return; @@ -52,15 +52,17 @@ void StemTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getTile(xx, y, zz) == 0 && (below == Tile::farmland_Id || below == Tile::dirt_Id || below == Tile::grass_Id)) { - level->setTile(xx, y, zz, fruit->id); + level->setTileAndUpdate(xx, y, zz, fruit->id); } } } } } -void StemTile::growCropsToMax(Level* level, int x, int y, int z) { - level->setData(x, y, z, 7); +void StemTile::growCrops(Level* level, int x, int y, int z) { + int stage = level->getData(x, y, z) + Mth::nextInt(level->random, 2, 5); + if (stage > 7) stage = 7; + level->setData(x, y, z, stage, Tile::UPDATE_CLIENTS); } float StemTile::getGrowthSpeed(Level* level, int x, int y, int z) { @@ -76,10 +78,9 @@ float StemTile::getGrowthSpeed(Level* level, int x, int y, int z) { int d2 = level->getTile(x + 1, y, z + 1); int d3 = level->getTile(x - 1, y, z + 1); - bool horizontal = w == this->id || e == this->id; - bool vertical = n == this->id || s == this->id; - bool diagonal = - d0 == this->id || d1 == this->id || d2 == this->id || d3 == this->id; + bool horizontal = w == id || e == id; + bool vertical = n == id || s == id; + bool diagonal = d0 == id || d1 == id || d2 == id || d3 == id; for (int xx = x - 1; xx <= x + 1; xx++) for (int zz = z - 1; zz <= z + 1; zz++) { @@ -136,7 +137,7 @@ int StemTile::getColor(LevelSource* level, int x, int y, int z) { void StemTile::updateDefaultShape() { float ss = 0.125f; - this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss); + setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss); } void StemTile::updateShape( @@ -147,8 +148,7 @@ void StemTile::updateShape( ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); tls->yy1 = (level->getData(x, y, z) * 2 + 2) / 16.0f; float ss = 0.125f; - this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, (float)tls->yy1, - 0.5f + ss); + setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, (float)tls->yy1, 0.5f + ss); } int StemTile::getRenderShape() { return Tile::SHAPE_STEM; } @@ -179,17 +179,8 @@ void StemTile::spawnResources(Level* level, int x, int y, int z, int data, if (fruit == Tile::pumpkin) seed = Item::seeds_pumpkin; if (fruit == Tile::melon) seed = Item::seeds_melon; for (int i = 0; i < 3; i++) { - if (level->random->nextInt(5 * 3) > data) continue; - float s = 0.7f; - float xo = level->random->nextFloat() * s + (1 - s) * 0.5f; - float yo = level->random->nextFloat() * s + (1 - s) * 0.5f; - float zo = level->random->nextFloat() * s + (1 - s) * 0.5f; - std::shared_ptr item = - std::shared_ptr(new ItemEntity( - level, x + xo, y + yo, z + zo, - std::shared_ptr(new ItemInstance(seed)))); - item->throwTime = 10; - level->addEntity(item); + popResource(level, x, y, z, + std::shared_ptr(new ItemInstance(seed))); } } diff --git a/Minecraft.World/Blocks/StemTile.h b/Minecraft.World/Blocks/StemTile.h index c29edd640..c5ec05b07 100644 --- a/Minecraft.World/Blocks/StemTile.h +++ b/Minecraft.World/Blocks/StemTile.h @@ -20,7 +20,7 @@ public: public: virtual void tick(Level* level, int x, int y, int z, Random* random); - void growCropsToMax(Level* level, int x, int y, int z); + virtual void growCrops(Level* level, int x, int y, int z); private: float getGrowthSpeed(Level* level, int x, int y, int z); diff --git a/Minecraft.World/Blocks/StoneButtonTile.cpp b/Minecraft.World/Blocks/StoneButtonTile.cpp new file mode 100644 index 000000000..99bfb96a0 --- /dev/null +++ b/Minecraft.World/Blocks/StoneButtonTile.cpp @@ -0,0 +1,9 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.h" +#include "StoneButtonTile.h" + +StoneButtonTile::StoneButtonTile(int id) : ButtonTile(id, false) {} + +Icon* StoneButtonTile::getTexture(int face, int data) { + return Tile::stone->getTexture(Facing::UP); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/StoneButtonTile.h b/Minecraft.World/Blocks/StoneButtonTile.h new file mode 100644 index 000000000..658564b87 --- /dev/null +++ b/Minecraft.World/Blocks/StoneButtonTile.h @@ -0,0 +1,10 @@ +#pragma once + +#include "ButtonTile.h" + +class StoneButtonTile : public ButtonTile { +public: + StoneButtonTile(int id); + + virtual Icon* getTexture(int face, int data); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/StoneMonsterTile.cpp b/Minecraft.World/Blocks/StoneMonsterTile.cpp index fa22ea7c7..09af1cf27 100644 --- a/Minecraft.World/Blocks/StoneMonsterTile.cpp +++ b/Minecraft.World/Blocks/StoneMonsterTile.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.monster.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.tile.h" #include "StoneMonsterTile.h" const unsigned int @@ -15,13 +16,18 @@ StoneMonsterTile::StoneMonsterTile(int id) : Tile(id, Material::clay) { } Icon* StoneMonsterTile::getTexture(int face, int data) { +#ifndef _CONTENT_PACKAGE + if (app.DebugArtToolsOn()) { + return Tile::fire->getTexture(face, 0); + } +#endif if (data == HOST_COBBLE) { - return Tile::stoneBrick->getTexture(face); + return Tile::cobblestone->getTexture(face); } if (data == HOST_STONEBRICK) { - return Tile::stoneBrickSmooth->getTexture(face); + return Tile::stoneBrick->getTexture(face); } - return Tile::rock->getTexture(face); + return Tile::stone->getTexture(face); } void StoneMonsterTile::registerIcons(IconRegister* iconRegister) { @@ -51,15 +57,15 @@ void StoneMonsterTile::destroy(Level* level, int x, int y, int z, int data) { int StoneMonsterTile::getResourceCount(Random* random) { return 0; } bool StoneMonsterTile::isCompatibleHostBlock(int block) { - return block == Tile::rock_Id || block == Tile::stoneBrick_Id || - block == Tile::stoneBrickSmooth_Id; + return block == Tile::stone_Id || block == Tile::cobblestone_Id || + block == Tile::stoneBrick_Id; } int StoneMonsterTile::getDataForHostBlock(int block) { - if (block == Tile::stoneBrick_Id) { + if (block == Tile::cobblestone_Id) { return HOST_COBBLE; } - if (block == Tile::stoneBrickSmooth_Id) { + if (block == Tile::stoneBrick_Id) { return HOST_STONEBRICK; } return HOST_ROCK; @@ -68,22 +74,22 @@ int StoneMonsterTile::getDataForHostBlock(int block) { Tile* StoneMonsterTile::getHostBlockForData(int data) { switch (data) { case HOST_COBBLE: - return Tile::stoneBrick; + return Tile::cobblestone; case HOST_STONEBRICK: - return Tile::stoneBrickSmooth; + return Tile::stoneBrick; default: - return Tile::rock; + return Tile::stone; } } std::shared_ptr StoneMonsterTile::getSilkTouchItemInstance( int data) { - Tile* tile = Tile::rock; + Tile* tile = Tile::stone; if (data == HOST_COBBLE) { - tile = Tile::stoneBrick; + tile = Tile::cobblestone; } if (data == HOST_STONEBRICK) { - tile = Tile::stoneBrickSmooth; + tile = Tile::stoneBrick; } return std::shared_ptr(new ItemInstance(tile)); } diff --git a/Minecraft.World/Blocks/StoneSlabTile.cpp b/Minecraft.World/Blocks/StoneSlabTile.cpp index 406debace..845bc1689 100644 --- a/Minecraft.World/Blocks/StoneSlabTile.cpp +++ b/Minecraft.World/Blocks/StoneSlabTile.cpp @@ -30,11 +30,11 @@ Icon* StoneSlabTile::getTexture(int face, int data) { case WOOD_SLAB: return Tile::wood->getTexture(face); case COBBLESTONE_SLAB: - return Tile::stoneBrick->getTexture(face); + return Tile::cobblestone->getTexture(face); case BRICK_SLAB: return Tile::redBrick->getTexture(face); case SMOOTHBRICK_SLAB: - return Tile::stoneBrickSmooth->getTexture( + return Tile::stoneBrick->getTexture( face, SmoothStoneBrickTile::TYPE_DEFAULT); case NETHERBRICK_SLAB: return Tile::netherBrick->getTexture(Facing::UP); diff --git a/Minecraft.World/Blocks/StoneTile.cpp b/Minecraft.World/Blocks/StoneTile.cpp index 6116ffd20..8d22a5879 100644 --- a/Minecraft.World/Blocks/StoneTile.cpp +++ b/Minecraft.World/Blocks/StoneTile.cpp @@ -4,5 +4,5 @@ StoneTile::StoneTile(int id) : Tile(id, Material::stone) {} int StoneTile::getResource(int data, Random* random, int playerBonusLevel) { - return Tile::stoneBrick_Id; + return Tile::cobblestone_Id; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/TallGrassPlantTile.cpp b/Minecraft.World/Blocks/TallGrassPlantTile.cpp index e77036d2c..ac0379d20 100644 --- a/Minecraft.World/Blocks/TallGrassPlantTile.cpp +++ b/Minecraft.World/Blocks/TallGrassPlantTile.cpp @@ -10,7 +10,7 @@ const unsigned int TallGrass::TALL_GRASS_TILE_NAMES[TALL_GRASS_TILE_NAMES_LENGTH] = { IDS_TILE_SHRUB, - IDS_TILE_GRASS, + IDS_TILE_TALL_GRASS, IDS_TILE_FERN, }; diff --git a/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp b/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp index 6197e9f69..a576f123c 100644 --- a/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "TheEndPortalFrameTile.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.world.h" #include "../Util/Facing.h" @@ -17,7 +18,7 @@ Icon* TheEndPortalFrameTile::getTexture(int face, int data) { return iconTop; } if (face == Facing::DOWN) { - return Tile::whiteStone->getTexture(face); + return Tile::endStone->getTexture(face); } return icon; } @@ -60,8 +61,22 @@ int TheEndPortalFrameTile::getResource(int data, Random* random, return 0; } -void TheEndPortalFrameTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { +void TheEndPortalFrameTile::setPlacedBy( + Level* level, int x, int y, int z, std::shared_ptr by, + std::shared_ptr itemInstance) { int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3) + 2) % 4; - level->setData(x, y, z, dir); + level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); } + +bool TheEndPortalFrameTile::hasAnalogOutputSignal() { return true; } + +int TheEndPortalFrameTile::getAnalogOutputSignal(Level* level, int x, int y, + int z, int dir) { + int data = level->getData(x, y, z); + + if (hasEye(data)) { + return Redstone::SIGNAL_MAX; + } else { + return Redstone::SIGNAL_NONE; + } +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TheEndPortalFrameTile.h b/Minecraft.World/Blocks/TheEndPortalFrameTile.h index 688c083f0..1e30d495d 100644 --- a/Minecraft.World/Blocks/TheEndPortalFrameTile.h +++ b/Minecraft.World/Blocks/TheEndPortalFrameTile.h @@ -23,5 +23,9 @@ public: static bool hasEye(int data); virtual int getResource(int data, Random* random, int playerBonusLevel); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TheEndPortalTile.cpp b/Minecraft.World/Blocks/TheEndPortalTile.cpp index 2249d6a14..a2fa0a5ad 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalTile.cpp @@ -53,7 +53,7 @@ void TheEndPortal::allowAnywhere(bool set) { } TheEndPortal::TheEndPortal(int id, Material* material) - : EntityTile(id, material, false) { + : BaseEntityTile(id, material, false) { this->setLightEmission(1.0f); } @@ -67,13 +67,13 @@ void TheEndPortal::updateShape( forceEntity) // 4J added forceData, forceEntity param { float r = 1 / 16.0f; - this->setShape(0, 0, 0, 1, r, 1); + setShape(0, 0, 0, 1, r, 1); } bool TheEndPortal::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { if (face != 0) return false; - return EntityTile::shouldRenderFace(level, x, y, z, face); + return BaseEntityTile::shouldRenderFace(level, x, y, z, face); } void TheEndPortal::addAABBs(Level* level, int x, int y, int z, AABB* box, @@ -87,9 +87,11 @@ int TheEndPortal::getResourceCount(Random* random) { return 0; } void TheEndPortal::entityInside(Level* level, int x, int y, int z, std::shared_ptr entity) { + if (entity->GetType() == eTYPE_EXPERIENCEORB) return; // 4J added + if (entity->riding == NULL && entity->rider.lock() == NULL) { - if (std::dynamic_pointer_cast(entity) != NULL) { - if (!level->isClientSide) { + if (!level->isClientSide) { + if (entity->instanceof(eTYPE_PLAYER)) { // 4J Stu - Update the level data position so that the // stronghold portal can be shown on the maps int x, z; @@ -102,9 +104,8 @@ void TheEndPortal::entityInside(Level* level, int x, int y, int z, level->getLevelData()->setZStrongholdEndPortal(z); level->getLevelData()->setHasStrongholdEndPortal(); } - - (std::dynamic_pointer_cast(entity))->changeDimension(1); } + entity->changeDimension(1); } } } @@ -127,7 +128,7 @@ void TheEndPortal::onPlace(Level* level, int x, int y, int z) { if (allowAnywhere()) return; if (level->dimension->id != 0) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return; } } diff --git a/Minecraft.World/Blocks/TheEndPortalTile.h b/Minecraft.World/Blocks/TheEndPortalTile.h index 7f10888f6..f5aefef57 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.h +++ b/Minecraft.World/Blocks/TheEndPortalTile.h @@ -6,7 +6,7 @@ #include #endif -class TheEndPortal : public EntityTile { +class TheEndPortal : public BaseEntityTile { public: #if defined(_WIN32) using TlsKey = std::uint32_t; @@ -40,4 +40,4 @@ public: virtual void onPlace(Level* level, int x, int y, int z); virtual int cloneTileId(Level* level, int x, int y, int z); void registerIcons(IconRegister* iconRegister); -}; +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/ThinFenceTile.cpp b/Minecraft.World/Blocks/ThinFenceTile.cpp index 17653166c..7e407a231 100644 --- a/Minecraft.World/Blocks/ThinFenceTile.cpp +++ b/Minecraft.World/Blocks/ThinFenceTile.cpp @@ -24,7 +24,10 @@ bool ThinFenceTile::isSolidRender(bool isServerLevel) { return false; } bool ThinFenceTile::isCubeShaped() { return false; } -int ThinFenceTile::getRenderShape() { return Tile::SHAPE_IRON_FENCE; } +int ThinFenceTile::getRenderShape() { + return material == Material::glass ? Tile::SHAPE_THIN_PANE + : Tile::SHAPE_IRON_FENCE; +} bool ThinFenceTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { @@ -101,7 +104,9 @@ void ThinFenceTile::updateShape( Icon* ThinFenceTile::getEdgeTexture() { return iconSide; } bool ThinFenceTile::attachsTo(int tile) { - return Tile::solid[tile] || tile == id || tile == Tile::glass_Id; + return Tile::solid[tile] || tile == id || tile == Tile::glass_Id || + tile == Tile::stained_glass_Id || + tile == Tile::stained_glass_pane_Id; } bool ThinFenceTile::isSilkTouchable() { return true; } diff --git a/Minecraft.World/Blocks/ThinFenceTile.h b/Minecraft.World/Blocks/ThinFenceTile.h index ff0bc2ccf..d7ba84fa0 100644 --- a/Minecraft.World/Blocks/ThinFenceTile.h +++ b/Minecraft.World/Blocks/ThinFenceTile.h @@ -33,5 +33,5 @@ protected: std::shared_ptr getSilkTouchItemInstance(int data); public: - void registerIcons(IconRegister* iconRegister); + virtual void registerIcons(IconRegister* iconRegister); }; diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index 3eb2dc70b..76091cdb3 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -10,6 +10,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.tile.entity.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.world.food.h" #include "../Headers/net.minecraft.world.h" @@ -71,10 +72,10 @@ bool Tile::propagate[TILE_NUM_COUNT]; Tile** Tile::tiles = NULL; -Tile* Tile::rock = NULL; +Tile* Tile::stone = NULL; GrassTile* Tile::grass = NULL; Tile* Tile::dirt = NULL; -Tile* Tile::stoneBrick = NULL; +Tile* Tile::cobblestone = NULL; Tile* Tile::wood = NULL; Tile* Tile::sapling = NULL; Tile* Tile::unbreakable = NULL; @@ -95,7 +96,7 @@ Tile* Tile::lapisOre = NULL; Tile* Tile::lapisBlock = NULL; Tile* Tile::dispenser = NULL; Tile* Tile::sandStone = NULL; -Tile* Tile::musicBlock = NULL; +Tile* Tile::noteblock = NULL; Tile* Tile::bed = NULL; Tile* Tile::goldenRail = NULL; Tile* Tile::detectorRail = NULL; @@ -105,12 +106,12 @@ TallGrass* Tile::tallgrass = NULL; DeadBushTile* Tile::deadBush = NULL; PistonBaseTile* Tile::pistonBase = NULL; PistonExtensionTile* Tile::pistonExtension = NULL; -Tile* Tile::cloth = NULL; +Tile* Tile::wool = NULL; PistonMovingPiece* Tile::pistonMovingPiece = NULL; Bush* Tile::flower = NULL; Bush* Tile::rose = NULL; -Bush* Tile::mushroom1 = NULL; -Bush* Tile::mushroom2 = NULL; +Bush* Tile::mushroom_brown = NULL; +Bush* Tile::mushroom_red = NULL; Tile* Tile::goldBlock = NULL; Tile* Tile::ironBlock = NULL; HalfSlabTile* Tile::stoneSlab = NULL; @@ -118,7 +119,7 @@ HalfSlabTile* Tile::stoneSlabHalf = NULL; Tile* Tile::redBrick = NULL; Tile* Tile::tnt = NULL; Tile* Tile::bookshelf = NULL; -Tile* Tile::mossStone = NULL; +Tile* Tile::mossyCobblestone = NULL; Tile* Tile::obsidian = NULL; Tile* Tile::torch = NULL; FireTile* Tile::fire = NULL; @@ -129,7 +130,7 @@ RedStoneDustTile* Tile::redStoneDust = NULL; Tile* Tile::diamondOre = NULL; Tile* Tile::diamondBlock = NULL; Tile* Tile::workBench = NULL; -Tile* Tile::crops = NULL; +Tile* Tile::wheat = NULL; Tile* Tile::farmland = NULL; Tile* Tile::furnace = NULL; Tile* Tile::furnace_lit = NULL; @@ -145,8 +146,8 @@ Tile* Tile::door_iron = NULL; Tile* Tile::pressurePlate_wood = NULL; Tile* Tile::redStoneOre = NULL; Tile* Tile::redStoneOre_lit = NULL; -Tile* Tile::notGate_off = NULL; -Tile* Tile::notGate_on = NULL; +Tile* Tile::redstoneTorch_off = NULL; +Tile* Tile::redstoneTorch_on = NULL; Tile* Tile::button = NULL; Tile* Tile::topSnow = NULL; Tile* Tile::ice = NULL; @@ -154,24 +155,24 @@ Tile* Tile::snow = NULL; Tile* Tile::cactus = NULL; Tile* Tile::clay = NULL; Tile* Tile::reeds = NULL; -Tile* Tile::recordPlayer = NULL; +Tile* Tile::jukebox = NULL; Tile* Tile::fence = NULL; Tile* Tile::pumpkin = NULL; -Tile* Tile::hellRock = NULL; -Tile* Tile::hellSand = NULL; -Tile* Tile::lightGem = NULL; +Tile* Tile::netherRack = NULL; +Tile* Tile::soulsand = NULL; +Tile* Tile::glowstone = NULL; PortalTile* Tile::portalTile = NULL; Tile* Tile::litPumpkin = NULL; Tile* Tile::cake = NULL; RepeaterTile* Tile::diode_off = NULL; RepeaterTile* Tile::diode_on = NULL; -Tile* Tile::aprilFoolsJoke = NULL; +Tile* Tile::stained_glass = NULL; Tile* Tile::trapdoor = NULL; Tile* Tile::monsterStoneEgg = NULL; -Tile* Tile::stoneBrickSmooth = NULL; -Tile* Tile::hugeMushroom1 = NULL; -Tile* Tile::hugeMushroom2 = NULL; +Tile* Tile::stoneBrick = NULL; +Tile* Tile::hugeMushroom_brown = NULL; +Tile* Tile::hugeMushroom_red = NULL; Tile* Tile::ironFence = NULL; Tile* Tile::thinGlass = NULL; Tile* Tile::melon = NULL; @@ -193,7 +194,7 @@ Tile* Tile::brewingStand = NULL; CauldronTile* Tile::cauldron = NULL; Tile* Tile::endPortalTile = NULL; Tile* Tile::endPortalFrameTile = NULL; -Tile* Tile::whiteStone = NULL; +Tile* Tile::endStone = NULL; Tile* Tile::dragonEgg = NULL; Tile* Tile::redstoneLight = NULL; Tile* Tile::redstoneLight_lit = NULL; @@ -203,7 +204,8 @@ Tile* Tile::stairs_sandstone = NULL; Tile* Tile::woodStairsDark = NULL; Tile* Tile::woodStairsBirch = NULL; Tile* Tile::woodStairsJungle = NULL; - +Tile* Tile::commandBlock = NULL; +BeaconTile* Tile::beacon = NULL; Tile* Tile::button_wood = NULL; HalfSlabTile* Tile::woodSlab = NULL; HalfSlabTile* Tile::woodSlabHalf = NULL; @@ -222,11 +224,28 @@ Tile* Tile::flowerPot = NULL; Tile* Tile::carrots = NULL; Tile* Tile::potatoes = NULL; Tile* Tile::anvil = NULL; +Tile* Tile::chest_trap = NULL; +Tile* Tile::weightedPlate_light = NULL; +Tile* Tile::weightedPlate_heavy = NULL; +ComparatorTile* Tile::comparator_off = NULL; +ComparatorTile* Tile::comparator_on = NULL; + +DaylightDetectorTile* Tile::daylightDetector = NULL; +Tile* Tile::redstoneBlock = NULL; + Tile* Tile::netherQuartz = NULL; +HopperTile* Tile::hopper = NULL; Tile* Tile::quartzBlock = NULL; Tile* Tile::stairs_quartz = NULL; +Tile* Tile::activatorRail = NULL; +Tile* Tile::dropper = NULL; +Tile* Tile::clayHardened_colored = NULL; +Tile* Tile::stained_glass_pane = NULL; +Tile* Tile::hayBlock = NULL; Tile* Tile::woolCarpet = NULL; +Tile* Tile::clayHardened = NULL; +Tile* Tile::coalBlock = NULL; #if defined(_WIN32) Tile::TlsKey Tile::tlsIdxShape = TlsAlloc(); @@ -272,22 +291,216 @@ void Tile::staticCtor() { Tile::tiles = new Tile*[TILE_NUM_COUNT]; memset(tiles, 0, sizeof(Tile*) * TILE_NUM_COUNT); - Tile::rail = (new RailTile(66, false)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, - Item::eMaterial_iron) - ->setDestroyTime(0.7f) - ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"rail") - ->setDescriptionId(IDS_TILE_RAIL) + Tile::stone = (new StoneTile(1)) + ->setDestroyTime(1.5f) + ->setExplodeable(10) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"stone") + ->setDescriptionId(IDS_TILE_STONE) + ->setUseDescriptionId(IDS_DESC_STONE); + Tile::grass = (GrassTile*)(new GrassTile(2)) + ->setDestroyTime(0.6f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"grass") + ->setDescriptionId(IDS_TILE_GRASS) + ->setUseDescriptionId(IDS_DESC_GRASS); + Tile::dirt = (new DirtTile(3)) + ->setDestroyTime(0.5f) + ->setSoundType(Tile::SOUND_GRAVEL) + ->setIconName(L"dirt") + ->setDescriptionId(IDS_TILE_DIRT) + ->setUseDescriptionId(IDS_DESC_DIRT); + Tile::cobblestone = + (new Tile(4, Material::stone)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, + Item::eMaterial_stone) + ->setDestroyTime(2.0f) + ->setExplodeable(10) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"cobblestone") + ->setDescriptionId(IDS_TILE_STONE_BRICK) + ->setUseDescriptionId(IDS_DESC_STONE_BRICK); + Tile::wood = + (new WoodTile(5)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structwoodstuff, + Item::eMaterial_wood) + ->setDestroyTime(2.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"planks") + ->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_WOODENPLANKS); + Tile::sapling = (new Sapling(6)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"sapling") + ->setDescriptionId(IDS_TILE_SAPLING) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_SAPLING) + ->disableMipmap(); + Tile::unbreakable = (new Tile(7, Material::stone)) + ->setIndestructible() + ->setExplodeable(6000000) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"bedrock") + ->setDescriptionId(IDS_TILE_BEDROCK) + ->setNotCollectStatistics() + ->setUseDescriptionId(IDS_DESC_BEDROCK); + Tile::water = (LiquidTile*)(new LiquidTileDynamic(8, Material::water)) + ->setDestroyTime(100.0f) + ->setLightBlock(3) + ->setIconName(L"water_flow") + ->setDescriptionId(IDS_TILE_WATER) + ->setNotCollectStatistics() + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_WATER); + Tile::calmWater = (new LiquidTileStatic(9, Material::water)) + ->setDestroyTime(100.0f) + ->setLightBlock(3) + ->setIconName(L"water_still") + ->setDescriptionId(IDS_TILE_WATER) + ->setNotCollectStatistics() + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_WATER); + Tile::lava = (LiquidTile*)(new LiquidTileDynamic(10, Material::lava)) + ->setDestroyTime(00.0f) + ->setLightEmission(1.0f) + ->setLightBlock(255) + ->setIconName(L"lava_flow") + ->setDescriptionId(IDS_TILE_LAVA) + ->setNotCollectStatistics() ->sendTileData() - ->setUseDescriptionId(IDS_DESC_RAIL) - ->disableMipmap(); - Tile::goldenRail = (new RailTile(27, true)) + ->setUseDescriptionId(IDS_DESC_LAVA); + + Tile::calmLava = (new LiquidTileStatic(11, Material::lava)) + ->setDestroyTime(100.0f) + ->setLightEmission(1.0f) + ->setLightBlock(255) + ->setIconName(L"lava_still") + ->setDescriptionId(IDS_TILE_LAVA) + ->setNotCollectStatistics() + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_LAVA); + Tile::sand = (new HeavyTile(12)) + ->setDestroyTime(0.5f) + ->setSoundType(Tile::SOUND_SAND) + ->setIconName(L"sand") + ->setDescriptionId(IDS_TILE_SAND) + ->setUseDescriptionId(IDS_DESC_SAND); + Tile::gravel = (new GravelTile(13)) + ->setDestroyTime(0.6f) + ->setSoundType(Tile::SOUND_GRAVEL) + ->setIconName(L"gravel") + ->setDescriptionId(IDS_TILE_GRAVEL) + ->setUseDescriptionId(IDS_DESC_GRAVEL); + Tile::goldOre = (new OreTile(14)) + ->setDestroyTime(3.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"gold_ore") + ->setDescriptionId(IDS_TILE_ORE_GOLD) + ->setUseDescriptionId(IDS_DESC_ORE_GOLD); + Tile::ironOre = (new OreTile(15)) + ->setDestroyTime(3.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"iron_ore") + ->setDescriptionId(IDS_TILE_ORE_IRON) + ->setUseDescriptionId(IDS_DESC_ORE_IRON); + Tile::coalOre = (new OreTile(16)) + ->setDestroyTime(3.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"coal_ore") + ->setDescriptionId(IDS_TILE_ORE_COAL) + ->setUseDescriptionId(IDS_DESC_ORE_COAL); + Tile::treeTrunk = (new TreeTile(17)) + ->setDestroyTime(2.0f) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"log") + ->setDescriptionId(IDS_TILE_LOG) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_LOG); + // 4J - for leaves, have specified that only the data bits that encode the + // type of leaf are important to be sent + Tile::leaves = (LeafTile*)(new LeafTile(18)) + ->setDestroyTime(0.2f) + ->setLightBlock(1) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"leaves") + ->setDescriptionId(IDS_TILE_LEAVES) + ->sendTileData(LeafTile::LEAF_TYPE_MASK) + ->setUseDescriptionId(IDS_DESC_LEAVES); + Tile::sponge = (new Sponge(19)) + ->setDestroyTime(0.6f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"sponge") + ->setDescriptionId(IDS_TILE_SPONGE) + ->setUseDescriptionId(IDS_DESC_SPONGE); + Tile::glass = (new GlassTile(20, Material::glass, false)) + ->setDestroyTime(0.3f) + ->setSoundType(Tile::SOUND_GLASS) + ->setIconName(L"glass") + ->setDescriptionId(IDS_TILE_GLASS) + ->setUseDescriptionId(IDS_DESC_GLASS); + + Tile::lapisOre = (new OreTile(21)) + ->setDestroyTime(3.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"lapis_ore") + ->setDescriptionId(IDS_TILE_ORE_LAPIS) + ->setUseDescriptionId(IDS_DESC_ORE_LAPIS); + Tile::lapisBlock = (new Tile(22, Material::stone)) + ->setBaseItemTypeAndMaterial( + Item::eBaseItemType_block, Item::eMaterial_lapis) + ->setDestroyTime(3.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"lapis_block") + ->setDescriptionId(IDS_TILE_BLOCK_LAPIS) + ->setUseDescriptionId(IDS_DESC_BLOCK_LAPIS); + Tile::dispenser = + (new DispenserTile(23)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, + Item::eMaterial_undefined) + ->setDestroyTime(3.5f) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"dispenser") + ->setDescriptionId(IDS_TILE_DISPENSER) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_DISPENSER); + Tile::sandStone = + (new SandStoneTile(24)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, + Item::eMaterial_sand) + ->setSoundType(Tile::SOUND_STONE) + ->setDestroyTime(0.8f) + ->sendTileData() + ->setIconName(L"sandstone") + ->setDescriptionId(IDS_TILE_SANDSTONE) + ->setUseDescriptionId(IDS_DESC_SANDSTONE) + ->sendTileData(); + Tile::noteblock = (new NoteBlockTile(25)) + ->setDestroyTime(0.8f) + ->setIconName(L"noteblock") + ->setDescriptionId(IDS_TILE_MUSIC_BLOCK) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_NOTEBLOCK); + Tile::bed = (new BedTile(26)) + ->setDestroyTime(0.2f) + ->setIconName(L"bed") + ->setDescriptionId(IDS_TILE_BED) + ->setNotCollectStatistics() + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_BED); + Tile::goldenRail = (new PoweredRailTile(27)) ->setBaseItemTypeAndMaterial( Item::eBaseItemType_rail, Item::eMaterial_gold) ->setDestroyTime(0.7f) ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"goldenRail") + ->setIconName(L"rail_golden") ->setDescriptionId(IDS_TILE_GOLDEN_RAIL) ->sendTileData() ->setUseDescriptionId(IDS_DESC_POWEREDRAIL) @@ -298,11 +511,93 @@ void Tile::staticCtor() { Item::eMaterial_detector) ->setDestroyTime(0.7f) ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"detectorRail") + ->setIconName(L"rail_detector") ->setDescriptionId(IDS_TILE_DETECTOR_RAIL) ->sendTileData() ->setUseDescriptionId(IDS_DESC_DETECTORRAIL) ->disableMipmap(); + Tile::pistonStickyBase = + (PistonBaseTile*)(new PistonBaseTile(29, true)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, + Item::eMaterial_stickypiston) + ->setIconName(L"pistonStickyBase") + ->setDescriptionId(IDS_TILE_PISTON_STICK_BASE) + ->setUseDescriptionId(IDS_DESC_STICKY_PISTON) + ->sendTileData(); + Tile::web = (new WebTile(30)) + ->setLightBlock(1) + ->setDestroyTime(4.0f) + ->setIconName(L"web") + ->setDescriptionId(IDS_TILE_WEB) + ->setUseDescriptionId(IDS_DESC_WEB); + + Tile::tallgrass = (TallGrass*)(new TallGrass(31)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"tallgrass") + ->setDescriptionId(IDS_TILE_TALL_GRASS) + ->setUseDescriptionId(IDS_DESC_TALL_GRASS) + ->disableMipmap(); + Tile::deadBush = (DeadBushTile*)(new DeadBushTile(32)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"deadbush") + ->setDescriptionId(IDS_TILE_DEAD_BUSH) + ->setUseDescriptionId(IDS_DESC_DEAD_BUSH) + ->disableMipmap(); + Tile::pistonBase = + (PistonBaseTile*)(new PistonBaseTile(33, false)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, + Item::eMaterial_piston) + ->setIconName(L"pistonBase") + ->setDescriptionId(IDS_TILE_PISTON_BASE) + ->setUseDescriptionId(IDS_DESC_PISTON) + ->sendTileData(); + Tile::pistonExtension = (PistonExtensionTile*)(new PistonExtensionTile(34)) + ->setDescriptionId(IDS_TILE_PISTON_BASE) + ->setUseDescriptionId(-1) + ->sendTileData(); + Tile::wool = (new ColoredTile(35, Material::cloth)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_cloth, + Item::eMaterial_cloth) + ->setDestroyTime(0.8f) + ->setSoundType(Tile::SOUND_CLOTH) + ->setIconName(L"wool_colored") + ->setDescriptionId(IDS_TILE_CLOTH) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_WOOL); + Tile::pistonMovingPiece = (PistonMovingPiece*)(new PistonMovingPiece(36)) + ->setDescriptionId(IDS_TILE_PISTON_BASE) + ->setUseDescriptionId(-1); + Tile::flower = (Bush*)(new Bush(37)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"flower_dandelion") + ->setDescriptionId(IDS_TILE_FLOWER) + ->setUseDescriptionId(IDS_DESC_FLOWER) + ->disableMipmap(); + Tile::rose = (Bush*)(new Bush(38)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"flower_rose") + ->setDescriptionId(IDS_TILE_ROSE) + ->setUseDescriptionId(IDS_DESC_FLOWER) + ->disableMipmap(); + Tile::mushroom_brown = (Bush*)(new Mushroom(39)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setLightEmission(2 / 16.0f) + ->setIconName(L"mushroom_brown") + ->setDescriptionId(IDS_TILE_MUSHROOM) + ->setUseDescriptionId(IDS_DESC_MUSHROOM) + ->disableMipmap(); + Tile::mushroom_red = (Bush*)(new Mushroom(40)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"mushroom_red") + ->setDescriptionId(IDS_TILE_MUSHROOM) + ->setUseDescriptionId(IDS_DESC_MUSHROOM) + ->disableMipmap(); Tile::goldBlock = (new MetalTile(41)) ->setBaseItemTypeAndMaterial( @@ -310,7 +605,7 @@ void Tile::staticCtor() { ->setDestroyTime(3.0f) ->setExplodeable(10) ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"blockGold") + ->setIconName(L"gold_block") ->setDescriptionId(IDS_TILE_BLOCK_GOLD) ->setUseDescriptionId(IDS_DESC_BLOCK_GOLD); Tile::ironBlock = (new MetalTile(42)) @@ -319,224 +614,29 @@ void Tile::staticCtor() { ->setDestroyTime(5.0f) ->setExplodeable(10) ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"blockIron") + ->setIconName(L"iron_block") ->setDescriptionId(IDS_TILE_BLOCK_IRON) ->setUseDescriptionId(IDS_DESC_BLOCK_IRON); - Tile::lapisBlock = (new Tile(22, Material::stone)) - ->setBaseItemTypeAndMaterial( - Item::eBaseItemType_block, Item::eMaterial_lapis) - ->setDestroyTime(3.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"blockLapis") - ->setDescriptionId(IDS_TILE_BLOCK_LAPIS) - ->setUseDescriptionId(IDS_DESC_BLOCK_LAPIS); - Tile::musicBlock = (new MusicTile(25)) - ->setDestroyTime(0.8f) - ->setTextureName(L"musicBlock") - ->setDescriptionId(IDS_TILE_MUSIC_BLOCK) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_NOTEBLOCK); - Tile::diamondBlock = - (new MetalTile(57)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, - Item::eMaterial_diamond) - ->setDestroyTime(5.0f) - ->setExplodeable(10) - ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"blockDiamond") - ->setDescriptionId(IDS_TILE_BLOCK_DIAMOND) - ->setUseDescriptionId(IDS_DESC_BLOCK_DIAMOND); - - Tile::goldOre = (new OreTile(14)) - ->setDestroyTime(3.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreGold") - ->setDescriptionId(IDS_TILE_ORE_GOLD) - ->setUseDescriptionId(IDS_DESC_ORE_GOLD); - Tile::ironOre = (new OreTile(15)) - ->setDestroyTime(3.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreIron") - ->setDescriptionId(IDS_TILE_ORE_IRON) - ->setUseDescriptionId(IDS_DESC_ORE_IRON); - Tile::coalOre = (new OreTile(16)) - ->setDestroyTime(3.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreCoal") - ->setDescriptionId(IDS_TILE_ORE_COAL) - ->setUseDescriptionId(IDS_DESC_ORE_COAL); - Tile::lapisOre = (new OreTile(21)) - ->setDestroyTime(3.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreLapis") - ->setDescriptionId(IDS_TILE_ORE_LAPIS) - ->setUseDescriptionId(IDS_DESC_ORE_LAPIS); - Tile::diamondOre = (new OreTile(56)) - ->setDestroyTime(3.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreDiamond") - ->setDescriptionId(IDS_TILE_ORE_DIAMOND) - ->setUseDescriptionId(IDS_DESC_ORE_DIAMOND); - - Tile::rock = (new StoneTile(1)) - ->setDestroyTime(1.5f) - ->setExplodeable(10) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"stone") - ->setDescriptionId(IDS_TILE_STONE) - ->setUseDescriptionId(IDS_DESC_STONE); - Tile::grass = (GrassTile*)(new GrassTile(2)) - ->setDestroyTime(0.6f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"grass") - ->setDescriptionId(IDS_TILE_GRASS) - ->setUseDescriptionId(IDS_DESC_GRASS); - Tile::dirt = (new DirtTile(3)) - ->setDestroyTime(0.5f) - ->setSoundType(Tile::SOUND_GRAVEL) - ->setTextureName(L"dirt") - ->setDescriptionId(IDS_TILE_DIRT) - ->setUseDescriptionId(IDS_DESC_DIRT); - Tile::sapling = (new Sapling(6)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"sapling") - ->setDescriptionId(IDS_TILE_SAPLING) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_SAPLING) - ->disableMipmap(); - Tile::unbreakable = (new Tile(7, Material::stone)) - ->setIndestructible() - ->setExplodeable(6000000) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"bedrock") - ->setDescriptionId(IDS_TILE_BEDROCK) - ->setNotCollectStatistics() - ->setUseDescriptionId(IDS_DESC_BEDROCK); - Tile::water = (LiquidTile*)(new LiquidTileDynamic(8, Material::water)) - ->setDestroyTime(100.0f) - ->setLightBlock(3) - ->setTextureName(L"water") - ->setDescriptionId(IDS_TILE_WATER) - ->setNotCollectStatistics() - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_WATER); - Tile::calmWater = (new LiquidTileStatic(9, Material::water)) - ->setDestroyTime(100.0f) - ->setLightBlock(3) - ->setTextureName(L"water") - ->setDescriptionId(IDS_TILE_WATER) - ->setNotCollectStatistics() - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_WATER); - Tile::lava = (LiquidTile*)(new LiquidTileDynamic(10, Material::lava)) - ->setDestroyTime(00.0f) - ->setLightEmission(1.0f) - ->setLightBlock(255) - ->setTextureName(L"lava") - ->setDescriptionId(IDS_TILE_LAVA) - ->setNotCollectStatistics() - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_LAVA); - Tile::calmLava = (new LiquidTileStatic(11, Material::lava)) - ->setDestroyTime(100.0f) - ->setLightEmission(1.0f) - ->setLightBlock(255) - ->setTextureName(L"lava") - ->setDescriptionId(IDS_TILE_LAVA) - ->setNotCollectStatistics() - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_LAVA); - Tile::sand = (new HeavyTile(12)) - ->setDestroyTime(0.5f) - ->setSoundType(Tile::SOUND_SAND) - ->setTextureName(L"sand") - ->setDescriptionId(IDS_TILE_SAND) - ->setUseDescriptionId(IDS_DESC_SAND); - Tile::gravel = (new GravelTile(13)) - ->setDestroyTime(0.6f) - ->setSoundType(Tile::SOUND_GRAVEL) - ->setTextureName(L"gravel") - ->setDescriptionId(IDS_TILE_GRAVEL) - ->setUseDescriptionId(IDS_DESC_GRAVEL); - Tile::treeTrunk = (new TreeTile(17)) - ->setDestroyTime(2.0f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"log") - ->setDescriptionId(IDS_TILE_LOG) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_LOG); - // 4J - for leaves, have specified that only the data bits that encode the - // type of leaf are important to be sent - Tile::leaves = (LeafTile*)(new LeafTile(18)) - ->setDestroyTime(0.2f) - ->setLightBlock(1) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"leaves") - ->setDescriptionId(IDS_TILE_LEAVES) - ->sendTileData(LeafTile::LEAF_TYPE_MASK) - ->setUseDescriptionId(IDS_DESC_LEAVES); - Tile::sponge = (new Sponge(19)) - ->setDestroyTime(0.6f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"sponge") - ->setDescriptionId(IDS_TILE_SPONGE) - ->setUseDescriptionId(IDS_DESC_SPONGE); - Tile::glass = (new GlassTile(20, Material::glass, false)) - ->setDestroyTime(0.3f) - ->setSoundType(Tile::SOUND_GLASS) - ->setTextureName(L"glass") - ->setDescriptionId(IDS_TILE_GLASS) - ->setUseDescriptionId(IDS_DESC_GLASS); - Tile::dispenser = (new DispenserTile(23)) - ->setDestroyTime(3.5f) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"dispenser") - ->setDescriptionId(IDS_TILE_DISPENSER) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_DISPENSER); - - // Tile::wood = (new Tile(5, 4, Material::wood)) - // ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structwoodstuff, - // Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_WOOD)->setDescriptionId(IDS_TILE_WOOD)->sendTileData()->setUseDescriptionId(IDS_DESC_WOODENPLANKS); - Tile::wood = - (new WoodTile(5)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structwoodstuff, - Item::eMaterial_wood) - ->setDestroyTime(2.0f) - ->setExplodeable(5) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"wood") - ->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_WOODENPLANKS); - Tile::sandStone = - (new SandStoneTile(24)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, - Item::eMaterial_sand) - ->setSoundType(Tile::SOUND_STONE) - ->setDestroyTime(0.8f) - ->sendTileData() - ->setTextureName(L"sandStone") - ->setDescriptionId(IDS_TILE_SANDSTONE) - ->setUseDescriptionId(IDS_DESC_SANDSTONE) - ->sendTileData(); - Tile::stoneBrick = - (new Tile(4, Material::stone)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, + Tile::stoneSlab = + (HalfSlabTile*)(new StoneSlabTile(Tile::stoneSlab_Id, true)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_stone) ->setDestroyTime(2.0f) ->setExplodeable(10) ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"stonebrick") - ->setDescriptionId(IDS_TILE_STONE_BRICK) - ->setUseDescriptionId(IDS_DESC_STONE_BRICK); + ->setIconName(L"stoneSlab") + ->setDescriptionId(IDS_TILE_STONESLAB) + ->setUseDescriptionId(IDS_DESC_SLAB); + Tile::stoneSlabHalf = + (HalfSlabTile*)(new StoneSlabTile(Tile::stoneSlabHalf_Id, false)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, + Item::eMaterial_stone) + ->setDestroyTime(2.0f) + ->setExplodeable(10) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"stoneSlab") + ->setDescriptionId(IDS_TILE_STONESLAB) + ->setUseDescriptionId(IDS_DESC_HALFSLAB); Tile::redBrick = (new Tile(45, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, @@ -544,262 +644,116 @@ void Tile::staticCtor() { ->setDestroyTime(2.0f) ->setExplodeable(10) ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"brick") + ->setIconName(L"brick") ->setDescriptionId(IDS_TILE_BRICK) ->setUseDescriptionId(IDS_DESC_BRICK); - Tile::clay = (new ClayTile(82)) - ->setBaseItemTypeAndMaterial( - Item::eBaseItemType_structblock, Item::eMaterial_clay) - ->setDestroyTime(0.6f) - ->setSoundType(Tile::SOUND_GRAVEL) - ->setTextureName(L"clay") - ->setDescriptionId(IDS_TILE_CLAY) - ->setUseDescriptionId(IDS_DESC_CLAY_TILE); - Tile::snow = (new SnowTile(80)) - ->setBaseItemTypeAndMaterial( - Item::eBaseItemType_structblock, Item::eMaterial_snow) - ->setDestroyTime(0.2f) - ->setSoundType(Tile::SOUND_CLOTH) - ->setTextureName(L"snow") - ->setDescriptionId(IDS_TILE_SNOW) - ->setUseDescriptionId(IDS_DESC_SNOW); - + Tile::tnt = (new TntTile(46)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_GRASS) + ->setIconName(L"tnt") + ->setDescriptionId(IDS_TILE_TNT) + ->setUseDescriptionId(IDS_DESC_TNT); + Tile::bookshelf = + (new BookshelfTile(47)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, + Item::eMaterial_bookshelf) + ->setDestroyTime(1.5f) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"bookshelf") + ->setDescriptionId(IDS_TILE_BOOKSHELF) + ->setUseDescriptionId(IDS_DESC_BOOKSHELF); + Tile::mossyCobblestone = (new Tile(48, Material::stone)) + ->setDestroyTime(2.0f) + ->setExplodeable(10) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"cobblestone_mossy") + ->setDescriptionId(IDS_TILE_STONE_MOSS) + ->setUseDescriptionId(IDS_DESC_MOSS_STONE); + Tile::obsidian = (new ObsidianTile(49)) + ->setDestroyTime(50.0f) + ->setExplodeable(2000) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"obsidian") + ->setDescriptionId(IDS_TILE_OBSIDIAN) + ->setUseDescriptionId(IDS_DESC_OBSIDIAN); Tile::torch = (new TorchTile(50)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, Item::eMaterial_wood) ->setDestroyTime(0.0f) ->setLightEmission(15 / 16.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"torch") + ->setIconName(L"torch_on") ->setDescriptionId(IDS_TILE_TORCH) - ->sendTileData() ->setUseDescriptionId(IDS_DESC_TORCH) ->disableMipmap(); - Tile::litPumpkin = - (new PumpkinTile(91, true)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, - Item::eMaterial_pumpkin) - ->setDestroyTime(1.0f) - ->setSoundType(Tile::SOUND_WOOD) - ->setLightEmission(1.0f) - ->setTextureName(L"litpumpkin") - ->setDescriptionId(IDS_TILE_LIT_PUMPKIN) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_JACKOLANTERN); - Tile::lightGem = (new LightGemTile(89, Material::glass)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, - Item::eMaterial_glowstone) - ->setDestroyTime(0.3f) - ->setSoundType(Tile::SOUND_GLASS) - ->setLightEmission(1.0f) - ->setTextureName(L"lightgem") - ->setDescriptionId(IDS_TILE_LIGHT_GEM) - ->setUseDescriptionId(IDS_DESC_GLOWSTONE); - - Tile::trapdoor = (new TrapDoorTile(96, Material::wood)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, - Item::eMaterial_trap) - ->setDestroyTime(3.0f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"trapdoor") - ->setDescriptionId(IDS_TILE_TRAPDOOR) - ->setNotCollectStatistics() - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_TRAPDOOR); - - Tile::bed = (new BedTile(26)) - ->setDestroyTime(0.2f) - ->setTextureName(L"bed") - ->setDescriptionId(IDS_TILE_BED) - ->setNotCollectStatistics() - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_BED); - Tile::pistonStickyBase = - (PistonBaseTile*)(new PistonBaseTile(29, true)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, - Item::eMaterial_stickypiston) - ->setTextureName(L"pistonStickyBase") - ->setDescriptionId(IDS_TILE_PISTON_STICK_BASE) - ->setUseDescriptionId(IDS_DESC_STICKY_PISTON) - ->sendTileData(); - Tile::web = (new WebTile(30)) - ->setLightBlock(1) - ->setDestroyTime(4.0f) - ->setTextureName(L"web") - ->setDescriptionId(IDS_TILE_WEB) - ->setUseDescriptionId(IDS_DESC_WEB); - Tile::tallgrass = (TallGrass*)(new TallGrass(31)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"tallgrass") - ->setDescriptionId(IDS_TILE_TALL_GRASS) - ->setUseDescriptionId(IDS_DESC_TALL_GRASS) - ->disableMipmap(); - Tile::deadBush = (DeadBushTile*)(new DeadBushTile(32)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"deadbush") - ->setDescriptionId(IDS_TILE_DEAD_BUSH) - ->setUseDescriptionId(IDS_DESC_DEAD_BUSH) - ->disableMipmap(); - Tile::pistonBase = - (PistonBaseTile*)(new PistonBaseTile(33, false)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, - Item::eMaterial_piston) - ->setTextureName(L"pistonBase") - ->setDescriptionId(IDS_TILE_PISTON_BASE) - ->setUseDescriptionId(IDS_DESC_PISTON) - ->sendTileData(); - Tile::pistonExtension = (PistonExtensionTile*)(new PistonExtensionTile(34)) - ->setDescriptionId(IDS_TILE_PISTON_BASE) - ->setUseDescriptionId(-1) - ->sendTileData(); - - Tile::cloth = (new ClothTile()) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_cloth, - Item::eMaterial_cloth) - ->setDestroyTime(0.8f) - ->setSoundType(Tile::SOUND_CLOTH) - ->setTextureName(L"cloth") - ->setDescriptionId(IDS_TILE_CLOTH) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_WOOL); - Tile::pistonMovingPiece = (PistonMovingPiece*)(new PistonMovingPiece(36)) - ->setDescriptionId(IDS_TILE_PISTON_BASE) - ->setUseDescriptionId(-1); - - Tile::pressurePlate_stone = - (Tile*)(new PressurePlateTile(70, L"stone", Material::stone, - PressurePlateTile::mobs)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, - Item::eMaterial_stone) - ->setDestroyTime(0.5f) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"pressurePlate") - ->setDescriptionId(IDS_TILE_PRESSURE_PLATE) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); - Tile::pressurePlate_wood = - (new PressurePlateTile(72, L"wood", Material::wood, - PressurePlateTile::everything)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, - Item::eMaterial_wood) - ->setDestroyTime(0.5f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"pressurePlate") - ->setDescriptionId(IDS_TILE_PRESSURE_PLATE) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); - - Tile::flower = (Bush*)(new Bush(37)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"flower") - ->setDescriptionId(IDS_TILE_FLOWER) - ->setUseDescriptionId(IDS_DESC_FLOWER) - ->disableMipmap(); - Tile::rose = (Bush*)(new Bush(38)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"rose") - ->setDescriptionId(IDS_TILE_ROSE) - ->setUseDescriptionId(IDS_DESC_FLOWER) - ->disableMipmap(); - Tile::mushroom1 = (Bush*)(new Mushroom(39, L"mushroom_brown")) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setLightEmission(2 / 16.0f) - ->setTextureName(L"mushroom") - ->setDescriptionId(IDS_TILE_MUSHROOM) - ->setUseDescriptionId(IDS_DESC_MUSHROOM) - ->disableMipmap(); - Tile::mushroom2 = (Bush*)(new Mushroom(40, L"mushroom_red")) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"mushroom") - ->setDescriptionId(IDS_TILE_MUSHROOM) - ->setUseDescriptionId(IDS_DESC_MUSHROOM) - ->disableMipmap(); - - // Tile::stoneSlab = (new StoneSlabTile(43, true)) - // ->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, - // Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB); - // Tile::stoneSlabHalf = (new StoneSlabTile(44, false)) - // ->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, - // Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB); - - Tile::tnt = (new TntTile(46)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"tnt") - ->setDescriptionId(IDS_TILE_TNT) - ->setUseDescriptionId(IDS_DESC_TNT); - Tile::bookshelf = (new BookshelfTile(47)) - ->setDestroyTime(1.5f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"bookshelf") - ->setDescriptionId(IDS_TILE_BOOKSHELF) - ->setUseDescriptionId(IDS_DESC_BOOKSHELF); - Tile::mossStone = (new Tile(48, Material::stone)) - ->setDestroyTime(2.0f) - ->setExplodeable(10) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"stoneMoss") - ->setDescriptionId(IDS_TILE_STONE_MOSS) - ->setUseDescriptionId(IDS_DESC_MOSS_STONE); - // 4J - change of destroy time from 10.0f -> 50.0f for obsidian brought - // forward from 1.2.3 - Tile::obsidian = (new ObsidianTile(49)) - ->setDestroyTime(50.0f) - ->setExplodeable(2000) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"obsidian") - ->setDescriptionId(IDS_TILE_OBSIDIAN) - ->setUseDescriptionId(IDS_DESC_OBSIDIAN); Tile::fire = (FireTile*)((new FireTile(51)) ->setDestroyTime(0.0f) ->setLightEmission(1.0f) ->setSoundType(Tile::SOUND_WOOD)) - ->setTextureName(L"fire") + ->setIconName(L"fire") ->setDescriptionId(IDS_TILE_FIRE) ->setNotCollectStatistics() ->setUseDescriptionId(-1); Tile::mobSpawner = (new MobSpawnerTile(52)) ->setDestroyTime(5.0f) ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"mobSpawner") + ->setIconName(L"mob_spawner") ->setDescriptionId(IDS_TILE_MOB_SPAWNER) ->setNotCollectStatistics() ->setUseDescriptionId(IDS_DESC_MOB_SPAWNER); - - Tile::chest = (ChestTile*)(new ChestTile(54)) + Tile::stairs_wood = + (new StairTile(53, Tile::wood, 0)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, + Item::eMaterial_wood) + ->setIconName(L"stairsWood") + ->setDescriptionId(IDS_TILE_STAIRS_WOOD) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::chest = (ChestTile*)(new ChestTile(54, ChestTile::TYPE_BASIC)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_chest, - Item::eMaterial_ender) + Item::eMaterial_wood) ->setDestroyTime(2.5f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"chest") + ->setIconName(L"chest") ->setDescriptionId(IDS_TILE_CHEST) ->sendTileData() ->setUseDescriptionId(IDS_DESC_CHEST); Tile::redStoneDust = (RedStoneDustTile*)(new RedStoneDustTile(55)) ->setDestroyTime(0.0f) ->setSoundType(Tile::SOUND_NORMAL) - ->setTextureName(L"redstoneDust") + ->setIconName(L"redstone_dust") ->setDescriptionId(IDS_TILE_REDSTONE_DUST) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_REDSTONE_DUST); + Tile::diamondOre = (new OreTile(56)) + ->setDestroyTime(3.0f) + ->setExplodeable(5) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"diamond_ore") + ->setDescriptionId(IDS_TILE_ORE_DIAMOND) + ->setUseDescriptionId(IDS_DESC_ORE_DIAMOND); + Tile::diamondBlock = + (new MetalTile(57)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, + Item::eMaterial_diamond) + ->setDestroyTime(5.0f) + ->setExplodeable(10) + ->setSoundType(Tile::SOUND_METAL) + ->setIconName(L"diamond_block") + ->setDescriptionId(IDS_TILE_BLOCK_DIAMOND) + ->setUseDescriptionId(IDS_DESC_BLOCK_DIAMOND); Tile::workBench = (new WorkbenchTile(58)) ->setBaseItemTypeAndMaterial( Item::eBaseItemType_device, Item::eMaterial_wood) ->setDestroyTime(2.5f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"workbench") + ->setIconName(L"crafting_table") ->setDescriptionId(IDS_TILE_WORKBENCH) ->setUseDescriptionId(IDS_DESC_CRAFTINGTABLE); - Tile::crops = (new CropTile(59)) - ->setTextureName(L"crops") + Tile::wheat = (new CropTile(59)) + ->setIconName(L"wheat") ->setDescriptionId(IDS_TILE_CROPS) ->setNotCollectStatistics() ->sendTileData() @@ -808,16 +762,17 @@ void Tile::staticCtor() { Tile::farmland = (new FarmTile(60)) ->setDestroyTime(0.6f) ->setSoundType(Tile::SOUND_GRAVEL) - ->setTextureName(L"farmland") + ->setIconName(L"farmland") ->setDescriptionId(IDS_TILE_FARMLAND) ->setUseDescriptionId(IDS_DESC_FARMLAND) ->sendTileData(); + Tile::furnace = (new FurnaceTile(61, false)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_stone) ->setDestroyTime(3.5f) ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"furnace") + ->setIconName(L"furnace") ->setDescriptionId(IDS_TILE_FURNACE) ->sendTileData() ->setUseDescriptionId(IDS_DESC_FURNACE); @@ -825,14 +780,14 @@ void Tile::staticCtor() { ->setDestroyTime(3.5f) ->setSoundType(Tile::SOUND_STONE) ->setLightEmission(14 / 16.0f) - ->setTextureName(L"furnace") + ->setIconName(L"furnace") ->setDescriptionId(IDS_TILE_FURNACE) ->sendTileData() ->setUseDescriptionId(IDS_DESC_FURNACE); Tile::sign = (new SignTile(63, eTYPE_SIGNTILEENTITY, true)) ->setDestroyTime(1.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"sign") + ->setIconName(L"sign") ->setDescriptionId(IDS_TILE_SIGN) ->setNotCollectStatistics() ->sendTileData() @@ -840,47 +795,88 @@ void Tile::staticCtor() { Tile::door_wood = (new DoorTile(64, Material::wood)) ->setDestroyTime(3.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"doorWood") + ->setIconName(L"door_wood") ->setDescriptionId(IDS_TILE_DOOR_WOOD) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_DOOR_WOOD); Tile::ladder = (new LadderTile(65)) ->setDestroyTime(0.4f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"ladder") + ->setSoundType(Tile::SOUND_LADDER) + ->setIconName(L"ladder") ->setDescriptionId(IDS_TILE_LADDER) ->sendTileData() ->setUseDescriptionId(IDS_DESC_LADDER) ->disableMipmap(); + Tile::rail = (new RailTile(66)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, + Item::eMaterial_iron) + ->setDestroyTime(0.7f) + ->setSoundType(Tile::SOUND_METAL) + ->setIconName(L"rail_normal") + ->setDescriptionId(IDS_TILE_RAIL) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_RAIL) + ->disableMipmap(); + Tile::stairs_stone = + (new StairTile(67, Tile::cobblestone, 0)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, + Item::eMaterial_stone) + ->setIconName(L"stairsStone") + ->setDescriptionId(IDS_TILE_STAIRS_STONE) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_STAIRS); Tile::wallSign = (new SignTile(68, eTYPE_SIGNTILEENTITY, false)) ->setDestroyTime(1.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"sign") + ->setIconName(L"sign") ->setDescriptionId(IDS_TILE_SIGN) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_SIGN); Tile::lever = (new LeverTile(69)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_lever, + Item::eMaterial_wood) ->setDestroyTime(0.5f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"lever") + ->setIconName(L"lever") ->setDescriptionId(IDS_TILE_LEVER) ->sendTileData() ->setUseDescriptionId(IDS_DESC_LEVER); + Tile::pressurePlate_stone = + (Tile*)(new PressurePlateTile(70, L"stone", Material::stone, + PressurePlateTile::mobs)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, + Item::eMaterial_stone) + ->setDestroyTime(0.5f) + ->setSoundType(Tile::SOUND_STONE) + ->setDescriptionId(IDS_TILE_PRESSURE_PLATE) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); + Tile::door_iron = (new DoorTile(71, Material::metal)) ->setDestroyTime(5.0f) ->setSoundType(Tile::SOUND_METAL) - ->setTextureName(L"doorIron") + ->setIconName(L"door_iron") ->setDescriptionId(IDS_TILE_DOOR_IRON) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_DOOR_IRON); + Tile::pressurePlate_wood = + (new PressurePlateTile(72, L"planks_oak", Material::wood, + PressurePlateTile::everything)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, + Item::eMaterial_wood) + ->setDestroyTime(0.5f) + ->setSoundType(Tile::SOUND_WOOD) + ->setDescriptionId(IDS_TILE_PRESSURE_PLATE) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); Tile::redStoneOre = (new RedStoneOreTile(73, false)) ->setDestroyTime(3.0f) ->setExplodeable(5) ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreRedstone") + ->setIconName(L"redstone_ore") ->setDescriptionId(IDS_TILE_ORE_REDSTONE) ->sendTileData() ->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); @@ -889,219 +885,268 @@ void Tile::staticCtor() { ->setDestroyTime(3.0f) ->setExplodeable(5) ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"oreRedstone") + ->setIconName(L"redstone_ore") ->setDescriptionId(IDS_TILE_ORE_REDSTONE) ->sendTileData() ->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); - Tile::notGate_off = (new NotGateTile(75, false)) - ->setDestroyTime(0.0f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"notGate") - ->setDescriptionId(IDS_TILE_NOT_GATE) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_REDSTONETORCH) - ->disableMipmap(); - Tile::notGate_on = (new NotGateTile(76, true)) - ->setDestroyTime(0.0f) - ->setLightEmission(8 / 16.0f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"notGate") - ->setDescriptionId(IDS_TILE_NOT_GATE) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_REDSTONETORCH) - ->disableMipmap(); - Tile::button = (new ButtonTile(77, false)) + Tile::redstoneTorch_off = (new NotGateTile(75, false)) + ->setDestroyTime(0.0f) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"redstone_torch_off") + ->setDescriptionId(IDS_TILE_NOT_GATE) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_REDSTONETORCH) + ->disableMipmap(); + Tile::redstoneTorch_on = (new NotGateTile(76, true)) + ->setDestroyTime(0.0f) + ->setLightEmission(8 / 16.0f) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"redstone_torch_on") + ->setDescriptionId(IDS_TILE_NOT_GATE) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_REDSTONETORCH) + ->disableMipmap(); + Tile::button = (new StoneButtonTile(77)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_button, Item::eMaterial_stone) ->setDestroyTime(0.5f) ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"button") + ->setIconName(L"button") ->setDescriptionId(IDS_TILE_BUTTON) ->sendTileData() ->setUseDescriptionId(IDS_DESC_BUTTON); - Tile::topSnow = (new TopSnowTile(78)) - ->setDestroyTime(0.1f) - ->setSoundType(Tile::SOUND_CLOTH) - ->setTextureName(L"snow") - ->setDescriptionId(IDS_TILE_SNOW) - ->setUseDescriptionId(IDS_DESC_TOP_SNOW) - ->sendTileData() - ->setLightBlock(0); + Tile::topSnow = + (new TopSnowTile(78)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, + Item::eMaterial_snow) + ->setDestroyTime(0.1f) + ->setSoundType(Tile::SOUND_SNOW) + ->setIconName(L"snow") + ->setDescriptionId(IDS_TILE_SNOW) + ->setUseDescriptionId(IDS_DESC_TOP_SNOW) + ->sendTileData() + ->setLightBlock(0); Tile::ice = (new IceTile(79)) ->setDestroyTime(0.5f) ->setLightBlock(3) ->setSoundType(Tile::SOUND_GLASS) - ->setTextureName(L"ice") + ->setIconName(L"ice") ->setDescriptionId(IDS_TILE_ICE) ->setUseDescriptionId(IDS_DESC_ICE); + Tile::snow = (new SnowTile(80)) + ->setBaseItemTypeAndMaterial( + Item::eBaseItemType_structblock, Item::eMaterial_snow) + ->setDestroyTime(0.2f) + ->setSoundType(Tile::SOUND_CLOTH) + ->setIconName(L"snow") + ->setDescriptionId(IDS_TILE_SNOW) + ->setUseDescriptionId(IDS_DESC_SNOW); + Tile::cactus = (new CactusTile(81)) ->setDestroyTime(0.4f) ->setSoundType(Tile::SOUND_CLOTH) - ->setTextureName(L"cactus") + ->setIconName(L"cactus") ->setDescriptionId(IDS_TILE_CACTUS) ->setUseDescriptionId(IDS_DESC_CACTUS) ->disableMipmap(); + Tile::clay = (new ClayTile(82)) + ->setBaseItemTypeAndMaterial( + Item::eBaseItemType_structblock, Item::eMaterial_clay) + ->setDestroyTime(0.6f) + ->setSoundType(Tile::SOUND_GRAVEL) + ->setIconName(L"clay") + ->setDescriptionId(IDS_TILE_CLAY) + ->setUseDescriptionId(IDS_DESC_CLAY_TILE); Tile::reeds = (new ReedTile(83)) ->setDestroyTime(0.0f) ->setSoundType(Tile::SOUND_GRASS) - ->setTextureName(L"reeds") + ->setIconName(L"reeds") ->setDescriptionId(IDS_TILE_REEDS) ->setNotCollectStatistics() ->setUseDescriptionId(IDS_DESC_REEDS) ->disableMipmap(); - Tile::recordPlayer = (new RecordPlayerTile(84)) - ->setDestroyTime(2.0f) - ->setExplodeable(10) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"jukebox") - ->setDescriptionId(IDS_TILE_JUKEBOX) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_JUKEBOX); - Tile::fence = (new FenceTile(85, L"wood", Material::wood)) + Tile::jukebox = (new JukeboxTile(84)) + ->setDestroyTime(2.0f) + ->setExplodeable(10) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"jukebox") + ->setDescriptionId(IDS_TILE_JUKEBOX) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_JUKEBOX); + Tile::fence = (new FenceTile(85, L"planks_oak", Material::wood)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_wood) ->setDestroyTime(2.0f) ->setExplodeable(5) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"fence") ->setDescriptionId(IDS_TILE_FENCE) ->setUseDescriptionId(IDS_DESC_FENCE); - Tile::pumpkin = (new PumpkinTile(86, false)) ->setDestroyTime(1.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"pumpkin") + ->setIconName(L"pumpkin") ->setDescriptionId(IDS_TILE_PUMPKIN) ->sendTileData() ->setUseDescriptionId(IDS_DESC_PUMPKIN); - - Tile::hellRock = (new HellStoneTile(87)) - ->setDestroyTime(0.4f) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"hellrock") - ->setDescriptionId(IDS_TILE_HELL_ROCK) - ->setUseDescriptionId(IDS_DESC_HELL_ROCK); - Tile::hellSand = (new HellSandTile(88)) + Tile::netherRack = (new NetherrackTile(87)) + ->setDestroyTime(0.4f) + ->setSoundType(Tile::SOUND_STONE) + ->setIconName(L"netherrack") + ->setDescriptionId(IDS_TILE_HELL_ROCK) + ->setUseDescriptionId(IDS_DESC_HELL_ROCK); + Tile::soulsand = (new SoulSandTile(88)) ->setDestroyTime(0.5f) ->setSoundType(Tile::SOUND_SAND) - ->setTextureName(L"hellsand") + ->setIconName(L"soul_sand") ->setDescriptionId(IDS_TILE_HELL_SAND) ->setUseDescriptionId(IDS_DESC_HELL_SAND); + Tile::glowstone = + (new Glowstonetile(89, Material::glass)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, + Item::eMaterial_glowstone) + ->setDestroyTime(0.3f) + ->setSoundType(Tile::SOUND_GLASS) + ->setLightEmission(1.0f) + ->setIconName(L"glowstone") + ->setDescriptionId(IDS_TILE_LIGHT_GEM) + ->setUseDescriptionId(IDS_DESC_GLOWSTONE); Tile::portalTile = (PortalTile*)((new PortalTile(90)) ->setDestroyTime(-1) ->setSoundType(Tile::SOUND_GLASS) ->setLightEmission(0.75f)) - ->setTextureName(L"portal") + ->setIconName(L"portal") ->setDescriptionId(IDS_TILE_PORTAL) ->setUseDescriptionId(IDS_DESC_PORTAL); + + Tile::litPumpkin = + (new PumpkinTile(91, true)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, + Item::eMaterial_pumpkin) + ->setDestroyTime(1.0f) + ->setSoundType(Tile::SOUND_WOOD) + ->setLightEmission(1.0f) + ->setIconName(L"pumpkin") + ->setDescriptionId(IDS_TILE_LIT_PUMPKIN) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_JACKOLANTERN); Tile::cake = (new CakeTile(92)) ->setDestroyTime(0.5f) ->setSoundType(Tile::SOUND_CLOTH) - ->setTextureName(L"cake") + ->setIconName(L"cake") ->setDescriptionId(IDS_TILE_CAKE) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_CAKE); - - // TODO Copy the translations from IDS_ITEM_DIODE to IDS_TILE_DIODE - Tile::diode_off = (RepeaterTile*)(new DiodeTile(93, false)) + Tile::diode_off = (RepeaterTile*)(new RepeaterTile(93, false)) ->setDestroyTime(0.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"diode") + ->setIconName(L"repeater_off") ->setDescriptionId(IDS_ITEM_DIODE) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER) ->disableMipmap(); - Tile::diode_on = (RepeaterTile*)(new DiodeTile(94, true)) + Tile::diode_on = (RepeaterTile*)(new RepeaterTile(94, true)) ->setDestroyTime(0.0f) ->setLightEmission(10 / 16.0f) ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"diode") + ->setIconName(L"repeater_on") ->setDescriptionId(IDS_ITEM_DIODE) ->setNotCollectStatistics() ->sendTileData() ->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER) ->disableMipmap(); - Tile::aprilFoolsJoke = (new LockedChestTile(95)) - ->setDestroyTime(0.0f) - ->setLightEmission(16 / 16.0f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"lockedchest") - ->setDescriptionId(IDS_TILE_LOCKED_CHEST) - ->setTicking(true) - ->sendTileData() - ->setUseDescriptionId(-1); - + Tile::stained_glass = + (new StainedGlassBlock(95, Material::glass)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, + Item::eMaterial_glass) + ->setDestroyTime(0.3f) + ->setSoundType(SOUND_GLASS) + ->setIconName(L"glass") + ->setDescriptionId(IDS_TILE_STAINED_GLASS) + ->setUseDescriptionId(IDS_DESC_STAINED_GLASS); + Tile::trapdoor = (new TrapDoorTile(96, Material::wood)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, + Item::eMaterial_trap) + ->setDestroyTime(3.0f) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"trapdoor") + ->setDescriptionId(IDS_TILE_TRAPDOOR) + ->setNotCollectStatistics() + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_TRAPDOOR); Tile::monsterStoneEgg = (new StoneMonsterTile(97)) ->setDestroyTime(0.75f) - ->setTextureName(L"monsterStoneEgg") + ->setIconName(L"monsterStoneEgg") ->setDescriptionId(IDS_TILE_STONE_SILVERFISH) ->setUseDescriptionId(IDS_DESC_STONE_SILVERFISH); - Tile::stoneBrickSmooth = + Tile::stoneBrick = (new SmoothStoneBrickTile(98)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stoneSmooth) ->setDestroyTime(1.5f) ->setExplodeable(10) ->setSoundType(SOUND_STONE) - ->setTextureName(L"stonebricksmooth") + ->setIconName(L"stonebrick") ->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH) ->setUseDescriptionId(IDS_DESC_STONE_BRICK_SMOOTH); - Tile::hugeMushroom1 = (new HugeMushroomTile(99, Material::wood, 0)) - ->setDestroyTime(0.2f) - ->setSoundType(SOUND_WOOD) - ->setTextureName(L"mushroom") - ->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_1) - ->setUseDescriptionId(IDS_DESC_MUSHROOM) - ->sendTileData(); - Tile::hugeMushroom2 = (new HugeMushroomTile(100, Material::wood, 1)) - ->setDestroyTime(0.2f) - ->setSoundType(SOUND_WOOD) - ->setTextureName(L"mushroom") - ->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_2) - ->setUseDescriptionId(IDS_DESC_MUSHROOM) - ->sendTileData(); - Tile::ironFence = (new ThinFenceTile(101, L"fenceIron", L"fenceIron", + Tile::hugeMushroom_brown = + (new HugeMushroomTile(99, Material::wood, + HugeMushroomTile::MUSHROOM_TYPE_BROWN)) + ->setDestroyTime(0.2f) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"mushroom_block") + ->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_1) + ->setUseDescriptionId(IDS_DESC_MUSHROOM) + ->sendTileData(); + Tile::hugeMushroom_red = + (new HugeMushroomTile(100, Material::wood, + HugeMushroomTile::MUSHROOM_TYPE_RED)) + ->setDestroyTime(0.2f) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"mushroom_block") + ->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_2) + ->setUseDescriptionId(IDS_DESC_MUSHROOM) + ->sendTileData(); + + Tile::ironFence = (new ThinFenceTile(101, L"iron_bars", L"iron_bars", Material::metal, true)) ->setBaseItemTypeAndMaterial( Item::eBaseItemType_fence, Item::eMaterial_iron) ->setDestroyTime(5.0f) ->setExplodeable(10) ->setSoundType(SOUND_METAL) - ->setTextureName(L"fenceIron") ->setDescriptionId(IDS_TILE_IRON_FENCE) ->setUseDescriptionId(IDS_DESC_IRON_FENCE); - Tile::thinGlass = (new ThinFenceTile(102, L"glass", L"thinglass_top", + Tile::thinGlass = (new ThinFenceTile(102, L"glass", L"glass_pane_top", Material::glass, false)) ->setDestroyTime(0.3f) ->setSoundType(SOUND_GLASS) - ->setTextureName(L"thinGlass") ->setDescriptionId(IDS_TILE_THIN_GLASS) ->setUseDescriptionId(IDS_DESC_THIN_GLASS); Tile::melon = (new MelonTile(103)) ->setDestroyTime(1.0f) ->setSoundType(SOUND_WOOD) - ->setTextureName(L"melon") + ->setIconName(L"melon") ->setDescriptionId(IDS_TILE_MELON) ->setUseDescriptionId(IDS_DESC_MELON_BLOCK); Tile::pumpkinStem = (new StemTile(104, Tile::pumpkin)) ->setDestroyTime(0.0f) ->setSoundType(SOUND_WOOD) - ->setTextureName(L"pumpkinStem") + ->setIconName(L"pumpkin_stem") ->setDescriptionId(IDS_TILE_PUMPKIN_STEM) ->sendTileData(); Tile::melonStem = (new StemTile(105, Tile::melon)) ->setDestroyTime(0.0f) ->setSoundType(SOUND_WOOD) - ->setTextureName(L"pumpkinStem") + ->setIconName(L"melon_stem") ->setDescriptionId(IDS_TILE_MELON_STEM) ->sendTileData(); Tile::vine = (new VineTile(106)) ->setDestroyTime(0.2f) ->setSoundType(SOUND_GRASS) - ->setTextureName(L"vine") + ->setIconName(L"vine") ->setDescriptionId(IDS_TILE_VINE) ->setUseDescriptionId(IDS_DESC_VINE) ->sendTileData(); @@ -1109,54 +1154,37 @@ void Tile::staticCtor() { ->setDestroyTime(2.0f) ->setExplodeable(5) ->setSoundType(SOUND_WOOD) - ->setTextureName(L"fenceGate") + ->setIconName(L"fenceGate") ->setDescriptionId(IDS_TILE_FENCE_GATE) ->sendTileData() ->setUseDescriptionId(IDS_DESC_FENCE_GATE); - - Tile::stairs_wood = - (new StairTile(53, Tile::wood, 0)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, - Item::eMaterial_wood) - ->setTextureName(L"stairsWood") - ->setDescriptionId(IDS_TILE_STAIRS_WOOD) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::stairs_stone = - (new StairTile(67, Tile::stoneBrick, 0)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, - Item::eMaterial_stone) - ->setTextureName(L"stairsStone") - ->setDescriptionId(IDS_TILE_STAIRS_STONE) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_STAIRS); Tile::stairs_bricks = (new StairTile(108, Tile::redBrick, 0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_brick) - ->setTextureName(L"stairsBrick") + ->setIconName(L"stairsBrick") ->setDescriptionId(IDS_TILE_STAIRS_BRICKS) ->sendTileData() ->setUseDescriptionId(IDS_DESC_STAIRS); Tile::stairs_stoneBrickSmooth = - (new StairTile(109, Tile::stoneBrickSmooth, 0)) + (new StairTile(109, Tile::stoneBrick, 0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_stoneSmooth) - ->setTextureName(L"stairsStoneBrickSmooth") + ->setIconName(L"stairsStoneBrickSmooth") ->setDescriptionId(IDS_TILE_STAIRS_STONE_BRICKS_SMOOTH) ->sendTileData() ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::mycel = (MycelTile*)(new MycelTile(110)) ->setDestroyTime(0.6f) ->setSoundType(SOUND_GRASS) - ->setTextureName(L"mycel") + ->setIconName(L"mycelium") ->setDescriptionId(IDS_TILE_MYCEL) ->setUseDescriptionId(IDS_DESC_MYCEL); + Tile::waterLily = (new WaterlilyTile(111)) ->setDestroyTime(0.0f) ->setSoundType(SOUND_GRASS) - ->setTextureName(L"waterlily") + ->setIconName(L"waterlily") ->setDescriptionId(IDS_TILE_WATERLILY) ->setUseDescriptionId(IDS_DESC_WATERLILY); Tile::netherBrick = @@ -1166,29 +1194,28 @@ void Tile::staticCtor() { ->setDestroyTime(2.0f) ->setExplodeable(10) ->setSoundType(SOUND_STONE) - ->setTextureName(L"netherBrick") + ->setIconName(L"nether_brick") ->setDescriptionId(IDS_TILE_NETHERBRICK) ->setUseDescriptionId(IDS_DESC_NETHERBRICK); Tile::netherFence = - (new FenceTile(113, L"netherBrick", Material::stone)) + (new FenceTile(113, L"nether_brick", Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_netherbrick) ->setDestroyTime(2.0f) ->setExplodeable(10) ->setSoundType(SOUND_STONE) - ->setTextureName(L"netherFence") ->setDescriptionId(IDS_TILE_NETHERFENCE) ->setUseDescriptionId(IDS_DESC_NETHERFENCE); Tile::stairs_netherBricks = (new StairTile(114, Tile::netherBrick, 0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_netherbrick) - ->setTextureName(L"stairsNetherBrick") + ->setIconName(L"stairsNetherBrick") ->setDescriptionId(IDS_TILE_STAIRS_NETHERBRICK) ->sendTileData() ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::netherStalk = (new NetherStalkTile(115)) - ->setTextureName(L"netherStalk") + Tile::netherStalk = (new NetherWartTile(115)) + ->setIconName(L"nether_wart") ->setDescriptionId(IDS_TILE_NETHERSTALK) ->sendTileData() ->setUseDescriptionId(IDS_DESC_NETHERSTALK); @@ -1198,7 +1225,7 @@ void Tile::staticCtor() { Item::eMaterial_magic) ->setDestroyTime(5.0f) ->setExplodeable(2000) - ->setTextureName(L"enchantmentTable") + ->setIconName(L"enchanting_table") ->setDescriptionId(IDS_TILE_ENCHANTMENTTABLE) ->setUseDescriptionId(IDS_DESC_ENCHANTMENTTABLE); Tile::brewingStand = @@ -1207,13 +1234,13 @@ void Tile::staticCtor() { Item::eMaterial_blaze) ->setDestroyTime(0.5f) ->setLightEmission(2 / 16.0f) - ->setTextureName(L"brewingStand") + ->setIconName(L"brewing_stand") ->setDescriptionId(IDS_TILE_BREWINGSTAND) ->sendTileData() ->setUseDescriptionId(IDS_DESC_BREWING_STAND); Tile::cauldron = (CauldronTile*)(new CauldronTile(118)) ->setDestroyTime(2.0f) - ->setTextureName(L"cauldron") + ->setIconName(L"cauldron") ->setDescriptionId(IDS_TILE_CAULDRON) ->sendTileData() ->setUseDescriptionId(IDS_DESC_CAULDRON); @@ -1227,91 +1254,47 @@ void Tile::staticCtor() { ->setSoundType(SOUND_GLASS) ->setLightEmission(2 / 16.0f) ->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME) - ->setTextureName(L"endPortalFrame") + ->setIconName(L"endframe") ->setDescriptionId(IDS_TILE_ENDPORTALFRAME) ->sendTileData() ->setExplodeable(6000000) ->setUseDescriptionId(IDS_DESC_ENDPORTALFRAME); - Tile::whiteStone = (new Tile(121, Material::stone)) - ->setDestroyTime(3.0f) - ->setExplodeable(15) - ->setSoundType(SOUND_STONE) - ->setTextureName(L"whiteStone") - ->setDescriptionId(IDS_TILE_WHITESTONE) - ->setUseDescriptionId(IDS_DESC_WHITESTONE); + + Tile::endStone = (new Tile(121, Material::stone)) + ->setDestroyTime(3.0f) + ->setExplodeable(15) + ->setSoundType(SOUND_STONE) + ->setIconName(L"end_stone") + ->setDescriptionId(IDS_TILE_WHITESTONE) + ->setUseDescriptionId(IDS_DESC_WHITESTONE); Tile::dragonEgg = (new EggTile(122)) ->setDestroyTime(3.0f) ->setExplodeable(15) ->setSoundType(SOUND_STONE) ->setLightEmission(2.0f / 16.0f) - ->setTextureName(L"dragonEgg") + ->setIconName(L"dragon_egg") ->setDescriptionId(IDS_TILE_DRAGONEGG) ->setUseDescriptionId(IDS_DESC_DRAGONEGG); Tile::redstoneLight = (new RedlightTile(123, false)) ->setDestroyTime(0.3f) ->setSoundType(SOUND_GLASS) - ->setTextureName(L"redstoneLight") + ->setIconName(L"redstone_lamp_off") ->setDescriptionId(IDS_TILE_REDSTONE_LIGHT) ->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); Tile::redstoneLight_lit = (new RedlightTile(124, true)) ->setDestroyTime(0.3f) ->setSoundType(SOUND_GLASS) - ->setTextureName(L"redstoneLight") + ->setIconName(L"redstone_lamp_on") ->setDescriptionId(IDS_TILE_REDSTONE_LIGHT) ->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); - - // TU9 - Tile::stairs_sandstone = - (new StairTile(128, Tile::sandStone, 0)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, - Item::eMaterial_sand) - ->setTextureName(L"stairsSandstone") - ->setDescriptionId(IDS_TILE_STAIRS_SANDSTONE) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::woodStairsDark = - (new StairTile(134, Tile::wood, TreeTile::DARK_TRUNK)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, - Item::eMaterial_sprucewood) - ->setTextureName(L"stairsWoodSpruce") - ->setDescriptionId(IDS_TILE_STAIRS_SPRUCEWOOD) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::woodStairsBirch = - (new StairTile(135, Tile::wood, TreeTile::BIRCH_TRUNK)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, - Item::eMaterial_birchwood) - ->setTextureName(L"stairsWoodBirch") - ->setDescriptionId(IDS_TILE_STAIRS_BIRCHWOOD) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::woodStairsJungle = - (new StairTile(136, Tile::wood, TreeTile::JUNGLE_TRUNK)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, - Item::eMaterial_junglewood) - ->setTextureName(L"stairsWoodJungle") - ->setDescriptionId(IDS_TILE_STAIRS_JUNGLEWOOD) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::button_wood = - (new ButtonTile(143, true)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_button, - Item::eMaterial_wood) - ->setDestroyTime(0.5f) - ->setSoundType(Tile::SOUND_WOOD) - ->setTextureName(L"button") - ->setDescriptionId(IDS_TILE_BUTTON) - ->sendTileData() - ->setUseDescriptionId(IDS_DESC_BUTTON); - Tile::woodSlab = (HalfSlabTile*)(new WoodSlabTile(Tile::woodSlab_Id, true)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_wood) ->setDestroyTime(2.0f) ->setExplodeable(5) ->setSoundType(SOUND_WOOD) - ->setTextureName(L"woodSlab") + ->setIconName(L"woodSlab") ->setDescriptionId(IDS_DESC_WOODSLAB) ->setUseDescriptionId(IDS_DESC_WOODSLAB); Tile::woodSlabHalf = @@ -1321,35 +1304,30 @@ void Tile::staticCtor() { ->setDestroyTime(2.0f) ->setExplodeable(5) ->setSoundType(SOUND_WOOD) - ->setTextureName(L"woodSlab") + ->setIconName(L"woodSlab") ->setDescriptionId(IDS_DESC_WOODSLAB) ->setUseDescriptionId(IDS_DESC_WOODSLAB); - Tile::stoneSlab = - (HalfSlabTile*)(new StoneSlabTile(Tile::stoneSlab_Id, true)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, - Item::eMaterial_stone) - ->setDestroyTime(2.0f) - ->setExplodeable(10) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"stoneSlab") - ->setDescriptionId(IDS_TILE_STONESLAB) - ->setUseDescriptionId(IDS_DESC_SLAB); - Tile::stoneSlabHalf = - (HalfSlabTile*)(new StoneSlabTile(Tile::stoneSlabHalf_Id, false)) - ->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, - Item::eMaterial_stone) - ->setDestroyTime(2.0f) - ->setExplodeable(10) - ->setSoundType(Tile::SOUND_STONE) - ->setTextureName(L"stoneSlab") - ->setDescriptionId(IDS_TILE_STONESLAB) - ->setUseDescriptionId(IDS_DESC_HALFSLAB); - + Tile::cocoa = (new CocoaTile(127)) + ->setDestroyTime(0.2f) + ->setExplodeable(5) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"cocoa") + ->sendTileData() + ->setDescriptionId(IDS_TILE_COCOA) + ->setUseDescriptionId(IDS_DESC_COCOA); + Tile::stairs_sandstone = + (new StairTile(128, Tile::sandStone, 0)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, + Item::eMaterial_sand) + ->setIconName(L"stairsSandstone") + ->setDescriptionId(IDS_TILE_STAIRS_SANDSTONE) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_STAIRS); Tile::emeraldOre = (new OreTile(129)) ->setDestroyTime(3.0f) ->setExplodeable(5) ->setSoundType(SOUND_STONE) - ->setTextureName(L"oreEmerald") + ->setIconName(L"emerald_ore") ->setDescriptionId(IDS_TILE_EMERALDORE) ->setUseDescriptionId(IDS_DESC_EMERALDORE); Tile::enderChest = (new EnderChestTile(130)) @@ -1358,18 +1336,22 @@ void Tile::staticCtor() { ->setDestroyTime(22.5f) ->setExplodeable(1000) ->setSoundType(SOUND_STONE) - ->setTextureName(L"enderChest") + ->setIconName(L"enderChest") ->sendTileData() ->setLightEmission(.5f) ->setDescriptionId(IDS_TILE_ENDERCHEST) ->setUseDescriptionId(IDS_DESC_ENDERCHEST); - Tile::tripWireSource = (TripWireSourceTile*)(new TripWireSourceTile(131)) - ->setTextureName(L"tripWireSource") - ->sendTileData() - ->setDescriptionId(IDS_TILE_TRIPWIRE_SOURCE) - ->setUseDescriptionId(IDS_DESC_TRIPWIRE_SOURCE); + + Tile::tripWireSource = + (TripWireSourceTile*)(new TripWireSourceTile(131)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_lever, + Item::eMaterial_undefined) + ->setIconName(L"trip_wire_source") + ->sendTileData() + ->setDescriptionId(IDS_TILE_TRIPWIRE_SOURCE) + ->setUseDescriptionId(IDS_DESC_TRIPWIRE_SOURCE); Tile::tripWire = (new TripWireTile(132)) - ->setTextureName(L"tripWire") + ->setIconName(L"trip_wire") ->sendTileData() ->setDescriptionId(IDS_TILE_TRIPWIRE) ->setUseDescriptionId(IDS_DESC_TRIPWIRE); @@ -1380,200 +1362,380 @@ void Tile::staticCtor() { ->setDestroyTime(5.0f) ->setExplodeable(10) ->setSoundType(SOUND_METAL) - ->setTextureName(L"blockEmerald") + ->setIconName(L"emerald_block") ->setDescriptionId(IDS_TILE_EMERALDBLOCK) ->setUseDescriptionId(IDS_DESC_EMERALDBLOCK); - - Tile::cocoa = (new CocoaTile(127)) - ->setDestroyTime(0.2f) - ->setExplodeable(5) - ->setSoundType(SOUND_WOOD) - ->setTextureName(L"cocoa") - ->sendTileData() - ->setDescriptionId(IDS_TILE_COCOA) - ->setUseDescriptionId(IDS_DESC_COCOA); - Tile::skull = (new SkullTile(144)) - ->setDestroyTime(1.0f) - ->setSoundType(SOUND_STONE) - ->setTextureName(L"skull") - ->setDescriptionId(IDS_TILE_SKULL) - ->setUseDescriptionId(IDS_DESC_SKULL); - + Tile::woodStairsDark = + (new StairTile(134, Tile::wood, TreeTile::DARK_TRUNK)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, + Item::eMaterial_sprucewood) + ->setIconName(L"stairsWoodSpruce") + ->setDescriptionId(IDS_TILE_STAIRS_SPRUCEWOOD) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::woodStairsBirch = + (new StairTile(135, Tile::wood, TreeTile::BIRCH_TRUNK)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, + Item::eMaterial_birchwood) + ->setIconName(L"stairsWoodBirch") + ->setDescriptionId(IDS_TILE_STAIRS_BIRCHWOOD) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::woodStairsJungle = + (new StairTile(136, Tile::wood, TreeTile::JUNGLE_TRUNK)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, + Item::eMaterial_junglewood) + ->setIconName(L"stairsWoodJungle") + ->setDescriptionId(IDS_TILE_STAIRS_JUNGLEWOOD) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::commandBlock = (new CommandBlock(137)) + ->setIndestructible() + ->setExplodeable(6000000) + ->setIconName(L"command_block") + ->setDescriptionId(IDS_TILE_COMMAND_BLOCK) + ->setUseDescriptionId(IDS_DESC_COMMAND_BLOCK); + Tile::beacon = (BeaconTile*)(new BeaconTile(138)) + ->setLightEmission(1.0f) + ->setIconName(L"beacon") + ->setDescriptionId(IDS_TILE_BEACON) + ->setUseDescriptionId(IDS_DESC_BEACON); Tile::cobbleWall = (new WallTile(139, Tile::stoneBrick)) ->setBaseItemTypeAndMaterial( Item::eBaseItemType_fence, Item::eMaterial_stone) - ->setTextureName(L"cobbleWall") + ->setIconName(L"cobbleWall") ->setDescriptionId(IDS_TILE_COBBLESTONE_WALL) ->setUseDescriptionId(IDS_DESC_COBBLESTONE_WALL); Tile::flowerPot = (new FlowerPotTile(140)) ->setDestroyTime(0.0f) ->setSoundType(SOUND_NORMAL) - ->setTextureName(L"flowerPot") + ->setIconName(L"flower_pot") ->setDescriptionId(IDS_TILE_FLOWERPOT) ->setUseDescriptionId(IDS_DESC_FLOWERPOT); + Tile::carrots = (new CarrotTile(141)) - ->setTextureName(L"carrots") + ->setIconName(L"carrots") ->setDescriptionId(IDS_TILE_CARROTS) ->setUseDescriptionId(IDS_DESC_CARROTS) ->disableMipmap(); Tile::potatoes = (new PotatoTile(142)) - ->setTextureName(L"potatoes") + ->setIconName(L"potatoes") ->setDescriptionId(IDS_TILE_POTATOES) ->setUseDescriptionId(IDS_DESC_POTATO) ->disableMipmap(); + Tile::button_wood = + (new WoodButtonTile(143)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_button, + Item::eMaterial_wood) + ->setDestroyTime(0.5f) + ->setSoundType(Tile::SOUND_WOOD) + ->setIconName(L"button") + ->setDescriptionId(IDS_TILE_BUTTON) + ->sendTileData() + ->setUseDescriptionId(IDS_DESC_BUTTON); + Tile::skull = (new SkullTile(144)) + ->setDestroyTime(1.0f) + ->setSoundType(SOUND_STONE) + ->setIconName(L"skull") + ->setDescriptionId(IDS_TILE_SKULL) + ->setUseDescriptionId(IDS_DESC_SKULL); Tile::anvil = (new AnvilTile(145)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_iron) ->setDestroyTime(5.0f) ->setSoundType(SOUND_ANVIL) ->setExplodeable(2000) - ->setTextureName(L"anvil") + ->setIconName(L"anvil") ->sendTileData() ->setDescriptionId(IDS_TILE_ANVIL) ->setUseDescriptionId(IDS_DESC_ANVIL); + Tile::chest_trap = (new ChestTile(146, ChestTile::TYPE_TRAP)) + ->setBaseItemTypeAndMaterial( + Item::eBaseItemType_chest, Item::eMaterial_trap) + ->setDestroyTime(2.5f) + ->setSoundType(SOUND_WOOD) + ->setDescriptionId(IDS_TILE_CHEST_TRAP) + ->setUseDescriptionId(IDS_DESC_CHEST_TRAP); + Tile::weightedPlate_light = + (new WeightedPressurePlateTile(147, L"gold_block", Material::metal, + Redstone::SIGNAL_MAX)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, + Item::eMaterial_gold) + ->setDestroyTime(0.5f) + ->setSoundType(SOUND_WOOD) + ->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_LIGHT) + ->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_LIGHT); + Tile::weightedPlate_heavy = + (new WeightedPressurePlateTile(148, L"iron_block", Material::metal, + Redstone::SIGNAL_MAX * 10)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, + Item::eMaterial_iron) + ->setDestroyTime(0.5f) + ->setSoundType(SOUND_WOOD) + ->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_HEAVY) + ->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_HEAVY); + Tile::comparator_off = (ComparatorTile*)(new ComparatorTile(149, false)) + ->setDestroyTime(0.0f) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"comparator_off") + ->setDescriptionId(IDS_TILE_COMPARATOR) + ->setUseDescriptionId(IDS_DESC_COMPARATOR); + Tile::comparator_on = (ComparatorTile*)(new ComparatorTile(150, true)) + ->setDestroyTime(0.0f) + ->setLightEmission(10 / 16.0f) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"comparator_on") + ->setDescriptionId(IDS_TILE_COMPARATOR) + ->setUseDescriptionId(IDS_DESC_COMPARATOR); + + Tile::daylightDetector = + (DaylightDetectorTile*)(new DaylightDetectorTile(151)) + ->setDestroyTime(0.2f) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"daylight_detector") + ->setDescriptionId(IDS_TILE_DAYLIGHT_DETECTOR) + ->setUseDescriptionId(IDS_DESC_DAYLIGHT_DETECTOR); + Tile::redstoneBlock = + (new PoweredMetalTile(152)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, + Item::eMaterial_redstone) + ->setDestroyTime(5.0f) + ->setExplodeable(10) + ->setSoundType(SOUND_METAL) + ->setIconName(L"redstone_block") + ->setDescriptionId(IDS_TILE_REDSTONE_BLOCK) + ->setUseDescriptionId(IDS_DESC_REDSTONE_BLOCK); Tile::netherQuartz = (new OreTile(153)) ->setDestroyTime(3.0f) ->setExplodeable(5) ->setSoundType(SOUND_STONE) - ->setTextureName(L"netherquartz") + ->setIconName(L"quartz_ore") ->setDescriptionId(IDS_TILE_NETHER_QUARTZ) ->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ_ORE); + Tile::hopper = + (HopperTile*)(new HopperTile(154)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, + Item::eMaterial_undefined) + ->setDestroyTime(3.0f) + ->setExplodeable(8) + ->setSoundType(SOUND_WOOD) + ->setIconName(L"hopper") + ->setDescriptionId(IDS_TILE_HOPPER) + ->setUseDescriptionId(IDS_DESC_HOPPER); Tile::quartzBlock = (new QuartzBlockTile(155)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_quartz) ->setSoundType(SOUND_STONE) ->setDestroyTime(0.8f) - ->setTextureName(L"quartzBlock") + ->setIconName(L"quartz_block") ->setDescriptionId(IDS_TILE_QUARTZ_BLOCK) ->setUseDescriptionId(IDS_DESC_QUARTZ_BLOCK); Tile::stairs_quartz = (new StairTile(156, Tile::quartzBlock, QuartzBlockTile::TYPE_DEFAULT)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_quartz) - ->setTextureName(L"stairsQuartz") + ->setIconName(L"stairsQuartz") ->setDescriptionId(IDS_TILE_STAIRS_QUARTZ) ->setUseDescriptionId(IDS_DESC_STAIRS); + Tile::activatorRail = (new PoweredRailTile(157)) + ->setDestroyTime(0.7f) + ->setSoundType(SOUND_METAL) + ->setIconName(L"rail_activator") + ->setDescriptionId(IDS_TILE_ACTIVATOR_RAIL) + ->setUseDescriptionId(IDS_DESC_ACTIVATOR_RAIL); + Tile::dropper = + (new DropperTile(158)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, + Item::eMaterial_undefined) + ->setDestroyTime(3.5f) + ->setSoundType(SOUND_STONE) + ->setIconName(L"dropper") + ->setDescriptionId(IDS_TILE_DROPPER) + ->setUseDescriptionId(IDS_DESC_DROPPER); + Tile::clayHardened_colored = + (new ColoredTile(159, Material::stone)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, + Item::eMaterial_clay) + ->setDestroyTime(1.25f) + ->setExplodeable(7) + ->setSoundType(SOUND_STONE) + ->setIconName(L"hardened_clay_stained") + ->setDescriptionId(IDS_TILE_STAINED_CLAY) + ->setUseDescriptionId(IDS_DESC_STAINED_CLAY); + Tile::stained_glass_pane = + (new StainedGlassPaneBlock(160)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, + Item::eMaterial_glass) + ->setDestroyTime(0.3f) + ->setSoundType(SOUND_GLASS) + ->setIconName(L"glass") + ->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE) + ->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); + Tile::hayBlock = (new HayBlockTile(170)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, + Item::eMaterial_wheat) + ->setDestroyTime(0.5f) + ->setSoundType(SOUND_GRASS) + ->setIconName(L"hay_block") + ->setDescriptionId(IDS_TILE_HAY) + ->setUseDescriptionId(IDS_DESC_HAY); Tile::woolCarpet = (new WoolCarpetTile(171)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_carpet, Item::eMaterial_cloth) ->setDestroyTime(0.1f) ->setSoundType(SOUND_CLOTH) - ->setTextureName(L"woolCarpet") + ->setIconName(L"woolCarpet") ->setLightBlock(0) ->setDescriptionId(IDS_TILE_CARPET) ->setUseDescriptionId(IDS_DESC_CARPET); + Tile::clayHardened = (new Tile(172, Material::stone)) + ->setBaseItemTypeAndMaterial( + Item::eBaseItemType_clay, Item::eMaterial_clay) + ->setDestroyTime(1.25f) + ->setExplodeable(7) + ->setSoundType(SOUND_STONE) + ->setIconName(L"hardened_clay") + ->setDescriptionId(IDS_TILE_HARDENED_CLAY) + ->setUseDescriptionId(IDS_DESC_HARDENED_CLAY); + Tile::coalBlock = (new Tile(173, Material::stone)) + ->setBaseItemTypeAndMaterial( + Item::eBaseItemType_block, Item::eMaterial_coal) + ->setDestroyTime(5.0f) + ->setExplodeable(10) + ->setSoundType(SOUND_STONE) + ->setIconName(L"coal_block") + ->setDescriptionId(IDS_TILE_COAL) + ->setUseDescriptionId(IDS_DESC_COAL_BLOCK); // Special cases for certain items since they can have different icons - Item::items[Tile::cloth_Id] = (new ClothTileItem(Tile::cloth_Id - 256)) - ->setTextureName(L"cloth") - ->setDescriptionId(IDS_TILE_CLOTH) - ->setUseDescriptionId(IDS_DESC_WOOL); - Item::items[Tile::woolCarpet_Id] = - (new ClothTileItem(Tile::woolCarpet_Id - 256)) - ->setTextureName(L"woolCarpet") - ->setDescriptionId(IDS_TILE_CARPET) - ->setUseDescriptionId(IDS_DESC_CARPET); - Item::items[Tile::treeTrunk_Id] = - (new TreeTileItem(Tile::treeTrunk_Id - 256, treeTrunk)) - ->setTextureName(L"log") + Item::items[wool_Id] = (new WoolTileItem(Tile::wool_Id - 256)) + ->setIconName(L"cloth") + ->setDescriptionId(IDS_TILE_CLOTH) + ->setUseDescriptionId(IDS_DESC_WOOL); + Item::items[clayHardened_colored_Id] = + (new WoolTileItem(Tile::clayHardened_colored_Id - 256)) + ->setIconName(L"clayHardenedStained") + ->setDescriptionId(IDS_TILE_STAINED_CLAY) + ->setUseDescriptionId(IDS_DESC_STAINED_CLAY); + Item::items[stained_glass_Id] = + (new WoolTileItem(Tile::stained_glass_Id - 256)) + ->setIconName(L"stainedGlass") + ->setDescriptionId(IDS_TILE_STAINED_GLASS) + ->setUseDescriptionId(IDS_DESC_STAINED_GLASS); + Item::items[stained_glass_pane_Id] = + (new WoolTileItem(Tile::stained_glass_pane_Id - 256)) + ->setIconName(L"stainedGlassPane") + ->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE) + ->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); + Item::items[woolCarpet_Id] = (new WoolTileItem(Tile::woolCarpet_Id - 256)) + ->setIconName(L"woolCarpet") + ->setDescriptionId(IDS_TILE_CARPET) + ->setUseDescriptionId(IDS_DESC_CARPET); + Item::items[treeTrunk_Id] = + (new MultiTextureTileItem(Tile::treeTrunk_Id - 256, treeTrunk, + (int*)TreeTile::TREE_NAMES, 4)) + ->setIconName(L"log") ->setDescriptionId(IDS_TILE_LOG) ->setUseDescriptionId(IDS_DESC_LOG); - Item::items[Tile::wood_Id] = - (new MultiTextureTileItem(Tile::wood_Id - 256, Tile::wood, - (int*)WoodTile::WOOD_NAMES, 4)) - ->setTextureName(L"wood") - ->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS) - ->setUseDescriptionId(IDS_DESC_LOG); // <- TODO - Item::items[Tile::monsterStoneEgg_Id] = - (new StoneMonsterTileItem(Tile::monsterStoneEgg_Id - 256)) - ->setTextureName(L"monsterStoneEgg") + Item::items[wood_Id] = (new MultiTextureTileItem( + Tile::wood_Id - 256, Tile::wood, + (int*)WoodTile::WOOD_NAMES, 4, IDS_TILE_PLANKS)) + ->setIconName(L"wood") + ->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS) + ->setUseDescriptionId(IDS_DESC_LOG); // <- TODO + Item::items[monsterStoneEgg_Id] = + (new MultiTextureTileItem( + Tile::monsterStoneEgg_Id - 256, monsterStoneEgg, + (int*)StoneMonsterTile::STONE_MONSTER_NAMES, 3)) + ->setIconName(L"monsterStoneEgg") ->setDescriptionId(IDS_TILE_STONE_SILVERFISH) ->setUseDescriptionId( IDS_DESC_STONE_SILVERFISH); // 4J - Brought forward from // post-1.2 to fix stacking problem - Item::items[Tile::stoneBrickSmooth_Id] = - (new SmoothStoneBrickTileItem(Tile::stoneBrickSmooth_Id - 256, - stoneBrickSmooth)) - ->setTextureName(L"stonebricksmooth") + Item::items[stoneBrick_Id] = + (new MultiTextureTileItem( + Tile::stoneBrick_Id - 256, stoneBrick, + (int*)SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES, 4)) + ->setIconName(L"stonebricksmooth") ->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH); - Item::items[Tile::sandStone_Id] = + Item::items[sandStone_Id] = (new MultiTextureTileItem(sandStone_Id - 256, sandStone, SandStoneTile::SANDSTONE_NAMES, SandStoneTile::SANDSTONE_BLOCK_NAMES)) - ->setTextureName(L"sandStone") + ->setIconName(L"sandStone") ->setDescriptionId(IDS_TILE_SANDSTONE) ->setUseDescriptionId(IDS_DESC_SANDSTONE); - Item::items[Tile::quartzBlock_Id] = + Item::items[quartzBlock_Id] = (new MultiTextureTileItem(quartzBlock_Id - 256, quartzBlock, QuartzBlockTile::BLOCK_NAMES, QuartzBlockTile::QUARTZ_BLOCK_NAMES)) - ->setTextureName(L"quartzBlock") + ->setIconName(L"quartzBlock") ->setDescriptionId(IDS_TILE_QUARTZ_BLOCK) ->setUseDescriptionId(IDS_DESC_QUARTZ_BLOCK); - Item::items[Tile::stoneSlabHalf_Id] = + Item::items[stoneSlabHalf_Id] = (new StoneSlabTileItem(Tile::stoneSlabHalf_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, false)) - ->setTextureName(L"stoneSlab") + ->setIconName(L"stoneSlab") ->setDescriptionId(IDS_TILE_STONESLAB) ->setUseDescriptionId(IDS_DESC_HALFSLAB); - Item::items[Tile::stoneSlab_Id] = + Item::items[stoneSlab_Id] = (new StoneSlabTileItem(Tile::stoneSlab_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, true)) - ->setTextureName(L"stoneSlab") + ->setIconName(L"stoneSlab") ->setDescriptionId(IDS_DESC_STONESLAB) ->setUseDescriptionId(IDS_DESC_SLAB); - Item::items[Tile::woodSlabHalf_Id] = + Item::items[woodSlabHalf_Id] = (new StoneSlabTileItem(Tile::woodSlabHalf_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, false)) - ->setTextureName(L"woodSlab") + ->setIconName(L"woodSlab") ->setDescriptionId(IDS_DESC_WOODSLAB) ->setUseDescriptionId(IDS_DESC_WOODSLAB); - Item::items[Tile::woodSlab_Id] = + Item::items[woodSlab_Id] = (new StoneSlabTileItem(Tile::woodSlab_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, true)) - ->setTextureName(L"woodSlab") + ->setIconName(L"woodSlab") ->setDescriptionId(IDS_DESC_WOODSLAB) ->setUseDescriptionId(IDS_DESC_WOODSLAB); - Item::items[Tile::sapling_Id] = - (new SaplingTileItem(Tile::sapling_Id - 256)) - ->setTextureName(L"sapling") + Item::items[sapling_Id] = + (new MultiTextureTileItem(Tile::sapling_Id - 256, Tile::sapling, + Sapling::SAPLING_NAMES, 4)) + ->setIconName(L"sapling") ->setDescriptionId(IDS_TILE_SAPLING) ->setUseDescriptionId(IDS_DESC_SAPLING); - Item::items[Tile::leaves_Id] = (new LeafTileItem(Tile::leaves_Id - 256)) - ->setTextureName(L"leaves") - ->setDescriptionId(IDS_TILE_LEAVES) - ->setUseDescriptionId(IDS_DESC_LEAVES); - Item::items[Tile::vine_Id] = - (new ColoredTileItem(Tile::vine_Id - 256, false)) - ->setDescriptionId(IDS_TILE_VINE) - ->setUseDescriptionId(IDS_DESC_VINE); - int idsData[3] = {IDS_TILE_SHRUB, IDS_TILE_GRASS, IDS_TILE_FERN}; + Item::items[leaves_Id] = (new LeafTileItem(Tile::leaves_Id - 256)) + ->setIconName(L"leaves") + ->setDescriptionId(IDS_TILE_LEAVES) + ->setUseDescriptionId(IDS_DESC_LEAVES); + Item::items[vine_Id] = (new ColoredTileItem(Tile::vine_Id - 256, false)) + ->setDescriptionId(IDS_TILE_VINE) + ->setUseDescriptionId(IDS_DESC_VINE); + int idsData[3] = {IDS_TILE_SHRUB, IDS_TILE_TALL_GRASS, IDS_TILE_FERN}; intArray ids = intArray(idsData, 3); - Item::items[Tile::tallgrass_Id] = + Item::items[tallgrass_Id] = ((ColoredTileItem*)(new ColoredTileItem(Tile::tallgrass_Id - 256, true)) ->setDescriptionId(IDS_TILE_TALL_GRASS)) ->setDescriptionPostfixes(ids); - Item::items[Tile::waterLily_Id] = + Item::items[topSnow_Id] = (new SnowItem(topSnow_Id - 256, topSnow)); + Item::items[waterLily_Id] = (new WaterLilyTileItem(Tile::waterLily_Id - 256)); - Item::items[Tile::pistonBase_Id] = - (new PistonTileItem(Tile::pistonBase_Id - 256)) - ->setDescriptionId(IDS_TILE_PISTON_BASE) - ->setUseDescriptionId(IDS_DESC_PISTON); - Item::items[Tile::pistonStickyBase_Id] = + Item::items[pistonBase_Id] = (new PistonTileItem(Tile::pistonBase_Id - 256)) + ->setDescriptionId(IDS_TILE_PISTON_BASE) + ->setUseDescriptionId(IDS_DESC_PISTON); + Item::items[pistonStickyBase_Id] = (new PistonTileItem(Tile::pistonStickyBase_Id - 256)) ->setDescriptionId(IDS_TILE_PISTON_STICK_BASE) ->setUseDescriptionId(IDS_DESC_STICKY_PISTON); - Item::items[Tile::cobbleWall_Id] = + Item::items[cobbleWall_Id] = (new MultiTextureTileItem(cobbleWall_Id - 256, cobbleWall, (int*)WallTile::COBBLE_NAMES, 2)) ->setDescriptionId(IDS_TILE_COBBLESTONE_WALL) ->setUseDescriptionId(IDS_DESC_COBBLESTONE_WALL); - Item::items[Tile::anvil_Id] = (new AnvilTileItem(anvil)) - ->setDescriptionId(IDS_TILE_ANVIL) - ->setUseDescriptionId(IDS_DESC_ANVIL); + Item::items[anvil_Id] = (new AnvilTileItem(anvil)) + ->setDescriptionId(IDS_TILE_ANVIL) + ->setUseDescriptionId(IDS_DESC_ANVIL); for (int i = 0; i < 256; i++) { if (Tile::tiles[i] != NULL) { @@ -1639,7 +1801,7 @@ void Tile::_init(int id, Material* material, bool isSolidRender) { lightBlock[id] = isSolidRender ? 255 : 0; transculent[id] = !material->blocksLight(); mipmapEnable[id] = true; // 4J added - m_textureName = L""; + iconName = L""; } Tile::Tile(int id, Material* material, bool isSolidRender) { @@ -1694,7 +1856,8 @@ Tile* Tile::setExplodeable(float explosionResistance) { bool Tile::isSolidBlockingTile(int t) { Tile* tile = Tile::tiles[t]; if (tile == NULL) return false; - return tile->material->isSolidBlocking() && tile->isCubeShaped(); + return tile->material->isSolidBlocking() && tile->isCubeShaped() && + !tile->isSignalSource(); } bool Tile::isCubeShaped() { return true; } @@ -1760,7 +1923,7 @@ float Tile::getBrightness(LevelSource* level, int x, int y, int z) { // lightEmission level for this tile rather than getting the for the passed // in x/y/z coords return level->getBrightness(x, y, z, - Tile::lightEmission[level->getTile(x, y, z)]); + lightEmission[level->getTile(x, y, z)]); } // 4J - brought forward from 1.8.2 @@ -1770,11 +1933,10 @@ int Tile::getLightColor(LevelSource* level, int x, int y, int z, // lightEmission level for this tile rather than getting the for the passed // in x/y/z coords if (tileId == -1) { - return level->getLightColor( - x, y, z, Tile::lightEmission[level->getTile(x, y, z)], -1); + return level->getLightColor(x, y, z, + lightEmission[level->getTile(x, y, z)], -1); } else { - return level->getLightColor(x, y, z, Tile::lightEmission[tileId], - tileId); + return level->getLightColor(x, y, z, lightEmission[tileId], tileId); } } @@ -1920,7 +2082,7 @@ void Tile::neighborChanged(Level* level, int x, int y, int z, int type) {} void Tile::addLights(Level* level, int x, int y, int z) {} -int Tile::getTickDelay() { return 10; } +int Tile::getTickDelay(Level* level) { return 10; } void Tile::onPlace(Level* level, int x, int y, int z) {} @@ -1936,8 +2098,10 @@ float Tile::getDestroyProgress(std::shared_ptr player, Level* level, int x, int y, int z) { float destroySpeed = getDestroySpeed(level, x, y, z); if (destroySpeed < 0) return 0; - if (!player->canDestroy(this)) return 1 / destroySpeed / 100.0f; - return (player->getDestroySpeed(this) / destroySpeed) / 30; + if (!player->canDestroy(this)) { + return player->getDestroySpeed(this, false) / destroySpeed / 100.0f; + } + return (player->getDestroySpeed(this, true) / destroySpeed) / 30; } void Tile::spawnResources(Level* level, int x, int y, int z, int data, @@ -1962,7 +2126,9 @@ void Tile::spawnResources(Level* level, int x, int y, int z, int data, void Tile::popResource(Level* level, int x, int y, int z, std::shared_ptr itemInstance) { - if (level->isClientSide) return; + if (level->isClientSide || + !level->getGameRules()->getBoolean(GameRules::RULE_DOTILEDROPS)) + return; float s = 0.7f; double xo = level->random->nextFloat() * s + (1 - s) * 0.5; @@ -2077,7 +2243,13 @@ bool Tile::containsZ(Vec3* v) { v->y <= tls->yy1; } -void Tile::wasExploded(Level* level, int x, int y, int z) {} +void Tile::wasExploded(Level* level, int x, int y, int z, + Explosion* explosion) {} + +bool Tile::mayPlace(Level* level, int x, int y, int z, int face, + std::shared_ptr item) { + return mayPlace(level, x, y, z, face); +} int Tile::getRenderLayer() { return 0; } @@ -2192,10 +2364,8 @@ int Tile::getColor(LevelSource* level, int x, int y, int z, int data) { return 0xffffff; } -bool Tile::getSignal(LevelSource* level, int x, int y, int z) { return false; } - -bool Tile::getSignal(LevelSource* level, int x, int y, int z, int dir) { - return false; +int Tile::getSignal(LevelSource* level, int x, int y, int z, int dir) { + return Redstone::SIGNAL_NONE; } bool Tile::isSignalSource() { return false; } @@ -2203,8 +2373,8 @@ bool Tile::isSignalSource() { return false; } void Tile::entityInside(Level* level, int x, int y, int z, std::shared_ptr entity) {} -bool Tile::getDirectSignal(Level* level, int x, int y, int z, int dir) { - return false; +int Tile::getDirectSignal(LevelSource* level, int x, int y, int z, int dir) { + return Redstone::SIGNAL_NONE; } void Tile::updateDefaultShape() { setShape(0, 0, 0, 1, 1, 1); } @@ -2212,8 +2382,8 @@ void Tile::updateDefaultShape() { setShape(0, 0, 0, 1, 1, 1); } void Tile::playerDestroy(Level* level, std::shared_ptr player, int x, int y, int z, int data) { // 4J Stu - Special case - only record a crop destroy if is fully grown - if (id == Tile::crops_Id) { - if (Tile::crops->getResource(data, NULL, 0) > 0) + if (id == Tile::wheat_Id) { + if (Tile::wheat->getResource(data, NULL, 0) > 0) player->awardStat(GenericStats::blocksMined(id), GenericStats::param_blocksMined(id, data, 1)); } else if (id == Tile::potatoes_Id) { @@ -2237,15 +2407,13 @@ void Tile::playerDestroy(Level* level, std::shared_ptr player, int x, player->awardStat(GenericStats::mineWood(), GenericStats::param_noArgs()); - if (isSilkTouchable() && - EnchantmentHelper::hasSilkTouch(player->inventory)) { + if (isSilkTouchable() && EnchantmentHelper::hasSilkTouch(player)) { std::shared_ptr item = getSilkTouchItemInstance(data); if (item != NULL) { popResource(level, x, y, z, item); } } else { - int playerBonusLevel = - EnchantmentHelper::getDiggingLootBonus(player->inventory); + int playerBonusLevel = EnchantmentHelper::getDiggingLootBonus(player); spawnResources(level, x, y, z, data, playerBonusLevel); } } @@ -2268,7 +2436,8 @@ int Tile::getResourceCountForLootBonus(int bonusLevel, Random* random) { bool Tile::canSurvive(Level* level, int x, int y, int z) { return true; } void Tile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) {} + std::shared_ptr by, + std::shared_ptr itemInstance) {} void Tile::finalizePlacement(Level* level, int x, int y, int z, int data) {} @@ -2292,7 +2461,9 @@ Tile* Tile::setUseDescriptionId(unsigned int id) { unsigned int Tile::getUseDescriptionId() { return useDescriptionId; } -void Tile::triggerEvent(Level* level, int x, int y, int z, int b0, int b1) {} +bool Tile::triggerEvent(Level* level, int x, int y, int z, int b0, int b1) { + return false; +} bool Tile::isCollectStatistics() { return collectStatistics; } @@ -2326,17 +2497,48 @@ void Tile::handleRain(Level* level, int x, int y, int z) {} void Tile::levelTimeChanged(Level* level, __int64 delta, __int64 newTime) {} +bool Tile::useOwnCloneData() { return false; } + +bool Tile::canInstantlyTick() { return true; } + +bool Tile::dropFromExplosion(Explosion* explosion) { return true; } + +bool Tile::isMatching(int id) { return this->id == id; } + +bool Tile::isMatching(int tileIdA, int tileIdB) { + if (tileIdA == tileIdB) { + return true; + } + if (tileIdA == 0 || tileIdB == 0 || tiles[tileIdA] == NULL || + tiles[tileIdB] == NULL) { + return false; + } + return tiles[tileIdA]->isMatching(tileIdB); +} + +bool Tile::hasAnalogOutputSignal() { return false; } + +int Tile::getAnalogOutputSignal(Level* level, int x, int y, int z, int dir) { + return Redstone::SIGNAL_NONE; +} + +Tile* Tile::setIconName(const std::wstring& iconName) { + this->iconName = iconName; + return this; +} + +std::wstring Tile::getIconName() { + return iconName.empty() ? L"MISSING_ICON_TILE_" + _toString(id) + + L"_" + _toString(descriptionId) + : iconName; +} + void Tile::registerIcons(IconRegister* iconRegister) { - icon = iconRegister->registerIcon(m_textureName); + icon = iconRegister->registerIcon(getIconName()); } std::wstring Tile::getTileItemIconName() { return L""; } -Tile* Tile::setTextureName(const std::wstring& name) { - m_textureName = name; - return this; -} - Tile::SoundType::SoundType(eMATERIALSOUND_TYPE eMaterialSound, float volume, float pitch, int iBreakSound, int iPlaceSound) { this->eMaterialSound = eMaterialSound; @@ -2430,22 +2632,21 @@ Tile::SoundType::SoundType(eMATERIALSOUND_TYPE eMaterialSound, float volume, float Tile::SoundType::getVolume() const { return volume; } float Tile::SoundType::getPitch() const { return pitch; } -// std::wstring getBreakSound() const { return breakSound; } -// std::wstring getStepSound() const { return stepSound; } +// wstring getBreakSound() const { return breakSound; } +// wstring getStepSound() const { return stepSound; } int Tile::SoundType::getBreakSound() const { return iBreakSound; } int Tile::SoundType::getStepSound() const { return iStepSound; } int Tile::SoundType::getPlaceSound() const { return iPlaceSound; } /* - 4J: These are necessary on the PS3. - (and 4 and Vita). +4J: These are necessary on the PS3. +(and 4 and Vita). */ -#if (defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || \ - defined __linux__) -const int Tile::rock_Id; +#if (defined __PS3__ || defined __ORBIS__ || defined __PSVITA__) +const int Tile::stone_Id; const int Tile::grass_Id; const int Tile::dirt_Id; -const int Tile::stoneBrick_Id; +// 4 const int Tile::wood_Id; const int Tile::sapling_Id; const int Tile::unbreakable_Id; @@ -2466,7 +2667,7 @@ const int Tile::lapisOre_Id; const int Tile::lapisBlock_Id; const int Tile::dispenser_Id; const int Tile::sandStone_Id; -const int Tile::musicBlock_Id; +// 25 const int Tile::bed_Id; const int Tile::goldenRail_Id; const int Tile::detectorRail_Id; @@ -2476,12 +2677,12 @@ const int Tile::tallgrass_Id; const int Tile::deadBush_Id; const int Tile::pistonBase_Id; const int Tile::pistonExtensionPiece_Id; -const int Tile::cloth_Id; +const int Tile::wool_Id; const int Tile::pistonMovingPiece_Id; const int Tile::flower_Id; const int Tile::rose_Id; -const int Tile::mushroom1_Id; -const int Tile::mushroom2_Id; +const int Tile::mushroom_brown_Id; +const int Tile::mushroom_red_Id; const int Tile::goldBlock_Id; const int Tile::ironBlock_Id; const int Tile::stoneSlab_Id; @@ -2489,7 +2690,7 @@ const int Tile::stoneSlabHalf_Id; const int Tile::redBrick_Id; const int Tile::tnt_Id; const int Tile::bookshelf_Id; -const int Tile::mossStone_Id; +const int Tile::mossyCobblestone_Id; const int Tile::obsidian_Id; const int Tile::torch_Id; const int Tile::fire_Id; @@ -2500,7 +2701,7 @@ const int Tile::redStoneDust_Id; const int Tile::diamondOre_Id; const int Tile::diamondBlock_Id; const int Tile::workBench_Id; -const int Tile::crops_Id; +const int Tile::wheat_Id; const int Tile::farmland_Id; const int Tile::furnace_Id; const int Tile::furnace_lit_Id; @@ -2516,8 +2717,8 @@ const int Tile::door_iron_Id; const int Tile::pressurePlate_wood_Id; const int Tile::redStoneOre_Id; const int Tile::redStoneOre_lit_Id; -const int Tile::notGate_off_Id; -const int Tile::notGate_on_Id; +const int Tile::redstoneTorch_off_Id; +const int Tile::redstoneTorch_on_Id; const int Tile::button_stone_Id; const int Tile::topSnow_Id; const int Tile::ice_Id; @@ -2525,23 +2726,23 @@ const int Tile::snow_Id; const int Tile::cactus_Id; const int Tile::clay_Id; const int Tile::reeds_Id; -const int Tile::recordPlayer_Id; +const int Tile::jukebox_Id; const int Tile::fence_Id; const int Tile::pumpkin_Id; -const int Tile::hellRock_Id; -const int Tile::hellSand_Id; -const int Tile::lightGem_Id; +const int Tile::netherRack_Id; +const int Tile::soulsand_Id; +const int Tile::glowstone_Id; const int Tile::portalTile_Id; const int Tile::litPumpkin_Id; const int Tile::cake_Id; const int Tile::diode_off_Id; const int Tile::diode_on_Id; -const int Tile::aprilFoolsJoke_Id; +const int Tile::stained_glass_Id; const int Tile::trapdoor_Id; const int Tile::monsterStoneEgg_Id; -const int Tile::stoneBrickSmooth_Id; -const int Tile::hugeMushroom1_Id; -const int Tile::hugeMushroom2_Id; +const int Tile::stoneBrick_Id; +const int Tile::hugeMushroom_brown_Id; +const int Tile::hugeMushroom_red_Id; const int Tile::ironFence_Id; const int Tile::thinGlass_Id; const int Tile::melon_Id; @@ -2550,7 +2751,7 @@ const int Tile::melonStem_Id; const int Tile::vine_Id; const int Tile::fenceGate_Id; const int Tile::stairs_bricks_Id; -const int Tile::stairs_stoneBrickSmooth_Id; +const int Tile::stairs_stoneBrick_Id; const int Tile::mycel_Id; const int Tile::waterLily_Id; const int Tile::netherBrick_Id; @@ -2562,7 +2763,7 @@ const int Tile::brewingStand_Id; const int Tile::cauldron_Id; const int Tile::endPortalTile_Id; const int Tile::endPortalFrameTile_Id; -const int Tile::whiteStone_Id; +const int Tile::endStone_Id; const int Tile::dragonEgg_Id; const int Tile::redstoneLight_Id; const int Tile::redstoneLight_lit_Id; diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index b761f9049..de191e764 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -28,10 +28,13 @@ class RedStoneDustTile; class RepeaterTile; class CauldronTile; class TripWireSourceTile; +class BeaconTile; +class ComparatorTile; +class DaylightDetectorTile; class Random; class HitResult; class Level; - +class HopperTile; class Player; class LevelSource; class Mob; @@ -76,6 +79,19 @@ public: static const int TILE_NUM_MASK = 0xfff; // 4096 - 1 static const int TILE_NUM_SHIFT = 12; // 4096 is 12 bits + // tile update flags + // neighbors: notify neighbors the block changed + static const int UPDATE_NEIGHBORS = (1 << 0); + // clients: send tile update over network connections + static const int UPDATE_CLIENTS = (1 << 1); + // invisible: this update is invisible, so don't rebuild graphics + static const int UPDATE_INVISIBLE = (1 << 2); + // clients: send tile update over network connections + static const int UPDATE_INVISIBLE_NO_LIGHT = (1 << 3) | UPDATE_INVISIBLE; + + static const int UPDATE_NONE = UPDATE_INVISIBLE; + static const int UPDATE_ALL = UPDATE_NEIGHBORS | UPDATE_CLIENTS; + private: // 4J Stu - Was const but had to change it so that we can initialise it in // TileStaticInit @@ -84,6 +100,8 @@ private: protected: static const float INDESTRUCTIBLE_DESTROY_TIME; + std::wstring iconName; + public: class SoundType { public: @@ -136,7 +154,7 @@ public: static const int SHAPE_LEVER = 12; static const int SHAPE_CACTUS = 13; static const int SHAPE_BED = 14; - static const int SHAPE_DIODE = 15; + static const int SHAPE_REPEATER = 15; static const int SHAPE_PISTON_BASE = 16; static const int SHAPE_PISTON_EXTENSION = 17; static const int SHAPE_IRON_FENCE = 18; @@ -157,7 +175,13 @@ public: static const int SHAPE_FLOWER_POT = 33; static const int SHAPE_BEACON = 34; static const int SHAPE_ANVIL = 35; + static const int SHAPE_DIODE = 36; + static const int SHAPE_COMPARATOR = 37; + static const int SHAPE_HOPPER = 38; static const int SHAPE_QUARTZ = 39; + static const int SHAPE_THIN_PANE = 40; + + static const int SHAPE_COUNT = 41; static Tile** tiles; @@ -175,16 +199,17 @@ public: // 4J - this array of simple constants made so the compiler can optimise // references to Ids that were previous of the form Tile::->id, // and are now simply Tile::whatever_Id - static const int rock_Id = 1; + static const int stone_Id = 1; static const int grass_Id = 2; static const int dirt_Id = 3; - static const int stoneBrick_Id = 4; + static const int cobblestone_Id = 4; static const int wood_Id = 5; static const int sapling_Id = 6; static const int unbreakable_Id = 7; static const int water_Id = 8; static const int calmWater_Id = 9; static const int lava_Id = 10; + static const int calmLava_Id = 11; static const int sand_Id = 12; static const int gravel_Id = 13; @@ -195,26 +220,29 @@ public: static const int leaves_Id = 18; static const int sponge_Id = 19; static const int glass_Id = 20; + static const int lapisOre_Id = 21; static const int lapisBlock_Id = 22; static const int dispenser_Id = 23; static const int sandStone_Id = 24; - static const int musicBlock_Id = 25; + static const int noteblock_Id = 25; static const int bed_Id = 26; static const int goldenRail_Id = 27; static const int detectorRail_Id = 28; static const int pistonStickyBase_Id = 29; static const int web_Id = 30; + static const int tallgrass_Id = 31; static const int deadBush_Id = 32; static const int pistonBase_Id = 33; static const int pistonExtensionPiece_Id = 34; - static const int cloth_Id = 35; + static const int wool_Id = 35; static const int pistonMovingPiece_Id = 36; static const int flower_Id = 37; static const int rose_Id = 38; - static const int mushroom1_Id = 39; - static const int mushroom2_Id = 40; + static const int mushroom_brown_Id = 39; + static const int mushroom_red_Id = 40; + static const int goldBlock_Id = 41; static const int ironBlock_Id = 42; static const int stoneSlab_Id = 43; @@ -222,9 +250,10 @@ public: static const int redBrick_Id = 45; static const int tnt_Id = 46; static const int bookshelf_Id = 47; - static const int mossStone_Id = 48; + static const int mossyCobblestone_Id = 48; static const int obsidian_Id = 49; static const int torch_Id = 50; + static const int fire_Id = 51; static const int mobSpawner_Id = 52; static const int stairs_wood_Id = 53; @@ -233,8 +262,9 @@ public: static const int diamondOre_Id = 56; static const int diamondBlock_Id = 57; static const int workBench_Id = 58; - static const int crops_Id = 59; + static const int wheat_Id = 59; static const int farmland_Id = 60; + static const int furnace_Id = 61; static const int furnace_lit_Id = 62; static const int sign_Id = 63; @@ -245,37 +275,40 @@ public: static const int wallSign_Id = 68; static const int lever_Id = 69; static const int pressurePlate_stone_Id = 70; + static const int door_iron_Id = 71; static const int pressurePlate_wood_Id = 72; static const int redStoneOre_Id = 73; static const int redStoneOre_lit_Id = 74; - static const int notGate_off_Id = 75; - static const int notGate_on_Id = 76; + static const int redstoneTorch_off_Id = 75; + static const int redstoneTorch_on_Id = 76; static const int button_stone_Id = 77; static const int topSnow_Id = 78; static const int ice_Id = 79; static const int snow_Id = 80; + static const int cactus_Id = 81; static const int clay_Id = 82; static const int reeds_Id = 83; - static const int recordPlayer_Id = 84; + static const int jukebox_Id = 84; static const int fence_Id = 85; static const int pumpkin_Id = 86; - static const int hellRock_Id = 87; - static const int hellSand_Id = 88; - static const int lightGem_Id = 89; + static const int netherRack_Id = 87; + static const int soulsand_Id = 88; + static const int glowstone_Id = 89; static const int portalTile_Id = 90; + static const int litPumpkin_Id = 91; static const int cake_Id = 92; static const int diode_off_Id = 93; static const int diode_on_Id = 94; - static const int aprilFoolsJoke_Id = 95; + static const int stained_glass_Id = 95; static const int trapdoor_Id = 96; - static const int monsterStoneEgg_Id = 97; - static const int stoneBrickSmooth_Id = 98; - static const int hugeMushroom1_Id = 99; - static const int hugeMushroom2_Id = 100; + static const int stoneBrick_Id = 98; + static const int hugeMushroom_brown_Id = 99; + static const int hugeMushroom_red_Id = 100; + static const int ironFence_Id = 101; static const int thinGlass_Id = 102; static const int melon_Id = 103; @@ -284,9 +317,9 @@ public: static const int vine_Id = 106; static const int fenceGate_Id = 107; static const int stairs_bricks_Id = 108; - static const int stairs_stoneBrickSmooth_Id = 109; - + static const int stairs_stoneBrick_Id = 109; static const int mycel_Id = 110; + static const int waterLily_Id = 111; static const int netherBrick_Id = 112; static const int netherFence_Id = 113; @@ -297,41 +330,60 @@ public: static const int cauldron_Id = 118; static const int endPortalTile_Id = 119; static const int endPortalFrameTile_Id = 120; - static const int whiteStone_Id = 121; + + static const int endStone_Id = 121; static const int dragonEgg_Id = 122; static const int redstoneLight_Id = 123; static const int redstoneLight_lit_Id = 124; - static const int woodSlab_Id = 125; static const int woodSlabHalf_Id = 126; static const int cocoa_Id = 127; static const int stairs_sandstone_Id = 128; - static const int stairs_sprucewood_Id = 134; - static const int stairs_birchwood_Id = 135; - static const int stairs_junglewood_Id = 136; static const int emeraldOre_Id = 129; static const int enderChest_Id = 130; + static const int tripWireSource_Id = 131; static const int tripWire_Id = 132; static const int emeraldBlock_Id = 133; - + static const int stairs_sprucewood_Id = 134; + static const int stairs_birchwood_Id = 135; + static const int stairs_junglewood_Id = 136; + static const int commandBlock_Id = 137; + static const int beacon_Id = 138; static const int cobbleWall_Id = 139; static const int flowerPot_Id = 140; + static const int carrots_Id = 141; static const int potatoes_Id = 142; - static const int anvil_Id = 145; static const int button_wood_Id = 143; static const int skull_Id = 144; + static const int anvil_Id = 145; + static const int chest_trap_Id = 146; + static const int weightedPlate_light_Id = 147; + static const int weightedPlate_heavy_Id = 148; + static const int comparator_off_Id = 149; + static const int comparator_on_Id = 150; + + static const int daylightDetector_Id = 151; + static const int redstoneBlock_Id = 152; static const int netherQuartz_Id = 153; + static const int hopper_Id = 154; static const int quartzBlock_Id = 155; static const int stairs_quartz_Id = 156; + static const int activatorRail_Id = 157; + static const int dropper_Id = 158; + static const int clayHardened_colored_Id = 159; + static const int stained_glass_pane_Id = 160; + static const int hayBlock_Id = 170; static const int woolCarpet_Id = 171; + static const int clayHardened_Id = 172; + static const int coalBlock_Id = 173; - static Tile* rock; + static Tile* stone; static GrassTile* grass; static Tile* dirt; - static Tile* stoneBrick; + static Tile* cobblestone; static Tile* wood; static Tile* sapling; static Tile* unbreakable; @@ -352,7 +404,7 @@ public: static Tile* lapisBlock; static Tile* dispenser; static Tile* sandStone; - static Tile* musicBlock; + static Tile* noteblock; static Tile* bed; static Tile* goldenRail; static Tile* detectorRail; @@ -362,12 +414,12 @@ public: static DeadBushTile* deadBush; static PistonBaseTile* pistonBase; static PistonExtensionTile* pistonExtension; - static Tile* cloth; + static Tile* wool; static PistonMovingPiece* pistonMovingPiece; static Bush* flower; static Bush* rose; - static Bush* mushroom1; - static Bush* mushroom2; + static Bush* mushroom_brown; + static Bush* mushroom_red; static Tile* goldBlock; static Tile* ironBlock; // static Tile *stoneSlab; @@ -375,7 +427,7 @@ public: static Tile* redBrick; static Tile* tnt; static Tile* bookshelf; - static Tile* mossStone; + static Tile* mossyCobblestone; static Tile* obsidian; static Tile* torch; static FireTile* fire; @@ -386,7 +438,7 @@ public: static Tile* diamondOre; static Tile* diamondBlock; static Tile* workBench; - static Tile* crops; + static Tile* wheat; static Tile* farmland; static Tile* furnace; static Tile* furnace_lit; @@ -402,8 +454,8 @@ public: static Tile* pressurePlate_wood; static Tile* redStoneOre; static Tile* redStoneOre_lit; - static Tile* notGate_off; - static Tile* notGate_on; + static Tile* redstoneTorch_off; + static Tile* redstoneTorch_on; static Tile* button; static Tile* topSnow; static Tile* ice; @@ -411,24 +463,24 @@ public: static Tile* cactus; static Tile* clay; static Tile* reeds; - static Tile* recordPlayer; + static Tile* jukebox; static Tile* fence; static Tile* pumpkin; - static Tile* hellRock; - static Tile* hellSand; - static Tile* lightGem; + static Tile* netherRack; + static Tile* soulsand; + static Tile* glowstone; static PortalTile* portalTile; static Tile* litPumpkin; static Tile* cake; static RepeaterTile* diode_off; static RepeaterTile* diode_on; - static Tile* aprilFoolsJoke; + static Tile* stained_glass; static Tile* trapdoor; static Tile* monsterStoneEgg; - static Tile* stoneBrickSmooth; - static Tile* hugeMushroom1; - static Tile* hugeMushroom2; + static Tile* stoneBrick; + static Tile* hugeMushroom_brown; + static Tile* hugeMushroom_red; static Tile* ironFence; static Tile* thinGlass; static Tile* melon; @@ -450,7 +502,7 @@ public: static CauldronTile* cauldron; static Tile* endPortalTile; static Tile* endPortalFrameTile; - static Tile* whiteStone; + static Tile* endStone; static Tile* dragonEgg; static Tile* redstoneLight; static Tile* redstoneLight_lit; @@ -459,6 +511,8 @@ public: static Tile* woodStairsDark; static Tile* woodStairsBirch; static Tile* woodStairsJungle; + static Tile* commandBlock; + static BeaconTile* beacon; static Tile* button_wood; static HalfSlabTile* woodSlab; static HalfSlabTile* woodSlabHalf; @@ -478,11 +532,28 @@ public: static Tile* carrots; static Tile* potatoes; static Tile* anvil; + static Tile* chest_trap; + static Tile* weightedPlate_light; + static Tile* weightedPlate_heavy; + static ComparatorTile* comparator_off; + static ComparatorTile* comparator_on; + + static DaylightDetectorTile* daylightDetector; + static Tile* redstoneBlock; + static Tile* netherQuartz; + static HopperTile* hopper; static Tile* quartzBlock; static Tile* stairs_quartz; + static Tile* activatorRail; + static Tile* dropper; + static Tile* clayHardened_colored; + static Tile* stained_glass_pane; + static Tile* hayBlock; static Tile* woolCarpet; + static Tile* clayHardened; + static Tile* coalBlock; static void staticCtor(); @@ -512,8 +583,6 @@ private: unsigned int descriptionId; unsigned int useDescriptionId; // 4J Added - std::wstring m_textureName; - protected: Icon* icon; @@ -583,14 +652,13 @@ public: virtual void destroy(Level* level, int x, int y, int z, int data); virtual void neighborChanged(Level* level, int x, int y, int z, int type); virtual void addLights(Level* level, int x, int y, int z); - virtual int getTickDelay(); + virtual int getTickDelay(Level* level); virtual void onPlace(Level* level, int x, int y, int z); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); virtual int getResourceCount(Random* random); virtual int getResource(int data, Random* random, int playerBonusLevel); virtual float getDestroyProgress(std::shared_ptr player, - Level* level = nullptr, int x = 0, - int y = 0, int z = 0); + Level* level, int x, int y, int z); virtual void spawnResources(Level* level, int x, int y, int z, int data, int playerBonusLevel); virtual void spawnResources(Level* level, int x, int y, int z, int data, @@ -613,17 +681,19 @@ private: virtual bool containsZ(Vec3* v); public: - virtual void wasExploded(Level* level, int x, int y, int z); + virtual void wasExploded(Level* level, int x, int y, int z, + Explosion* explosion); virtual int getRenderLayer(); + virtual bool mayPlace(Level* level, int x, int y, int z, int face, + std::shared_ptr item); virtual bool mayPlace(Level* level, int x, int y, int z, int face); virtual bool mayPlace(Level* level, int x, int y, int z); virtual bool TestUse(); virtual bool TestUse(Level* level, int x, int y, int z, std::shared_ptr player); virtual bool use(Level* level, int x, int y, int z, - std::shared_ptr player, int clickedFace = 0, - float clickX = 0.0f, float clickY = 0.0f, - float clickZ = 0.0f, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, bool soundOnly = false); // 4J added soundOnly param virtual void stepOn(Level* level, int x, int y, int z, std::shared_ptr entity); @@ -650,12 +720,12 @@ public: virtual int getColor(LevelSource* level, int x, int y, int z); virtual int getColor(LevelSource* level, int x, int y, int z, int data); // 4J added - virtual bool getSignal(LevelSource* level, int x, int y, int z); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); virtual bool isSignalSource(); virtual void entityInside(Level* level, int x, int y, int z, std::shared_ptr entity); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); virtual void updateDefaultShape(); virtual void playerDestroy(Level* level, std::shared_ptr player, int x, int y, int z, int data); @@ -668,14 +738,15 @@ protected: public: virtual int getResourceCountForLootBonus(int bonusLevel, Random* random); virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); + std::shared_ptr by, + std::shared_ptr itemInstance); virtual void finalizePlacement(Level* level, int x, int y, int z, int data); virtual Tile* setDescriptionId(unsigned int id); virtual std::wstring getName(); virtual unsigned int getDescriptionId(int iData = -1); virtual Tile* setUseDescriptionId(unsigned int id); // 4J Added virtual unsigned int getUseDescriptionId(); // 4J Added - virtual void triggerEvent(Level* level, int x, int y, int z, int b0, + virtual bool triggerEvent(Level* level, int x, int y, int z, int b0, int b1); virtual bool isCollectStatistics(); @@ -702,10 +773,23 @@ public: virtual void onRemoving(Level* level, int x, int y, int z, int data); virtual void handleRain(Level* level, int x, int y, int z); virtual void levelTimeChanged(Level* level, __int64 delta, __int64 newTime); + virtual bool useOwnCloneData(); + virtual bool canInstantlyTick(); + virtual bool dropFromExplosion(Explosion* explosion); + virtual bool isMatching(int id); + static bool isMatching(int tileIdA, int tileIdB); + virtual bool hasAnalogOutputSignal(); + virtual int getAnalogOutputSignal(Level* level, int x, int y, int z, + int dir); + +protected: + virtual Tile* setIconName(const std::wstring& iconName); + virtual std::wstring getIconName(); + +public: virtual void registerIcons(IconRegister* iconRegister); virtual std::wstring getTileItemIconName(); - // 4J Using per-item textures now - Tile* setTextureName(const std::wstring& name); + // AP - added this function so we can generate the faceFlags for a block in // a single fast function int getFaceFlags(LevelSource* level, int x, int y, int z); diff --git a/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp new file mode 100644 index 000000000..5b160f153 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp @@ -0,0 +1,302 @@ +#include "../../Platform/stdafx.h" +#include "../../Headers/net.minecraft.network.packet.h" +#include "../../Headers/net.minecraft.world.effect.h" +#include "../../Headers/net.minecraft.world.entity.player.h" +#include "../../Headers/net.minecraft.world.item.h" +#include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.tile.h" +#include "../../Headers/net.minecraft.world.phys.h" +#include "BeaconTileEntity.h" + +std::shared_ptr BeaconTileEntity::clone() { + std::shared_ptr result = + std::shared_ptr(new BeaconTileEntity()); + TileEntity::clone(result); + + result->primaryPower = primaryPower; + result->secondaryPower = secondaryPower; + result->levels = levels; + + return result; +} + +MobEffect* + BeaconTileEntity::BEACON_EFFECTS[BeaconTileEntity::BEACON_EFFECTS_TIERS] + [BeaconTileEntity::BEACON_EFFECTS_EFFECTS]; + +void BeaconTileEntity::staticCtor() { + for (unsigned int tier = 0; tier < BEACON_EFFECTS_TIERS; ++tier) { + for (unsigned int effect = 0; effect < BEACON_EFFECTS_EFFECTS; + ++effect) { + BEACON_EFFECTS[tier][effect] = NULL; + } + } + BEACON_EFFECTS[0][0] = MobEffect::movementSpeed; + BEACON_EFFECTS[0][1] = MobEffect::digSpeed; + BEACON_EFFECTS[1][0] = MobEffect::damageResistance; + BEACON_EFFECTS[1][1] = MobEffect::jump; + BEACON_EFFECTS[2][0] = MobEffect::damageBoost; + BEACON_EFFECTS[3][0] = MobEffect::regeneration; +} + +BeaconTileEntity::BeaconTileEntity() { + clientSideRenderTick = 0; + clientSideRenderScale = 0.0f; + + isActive = false; + levels = -1; + + primaryPower = 0; + secondaryPower = 0; + + paymentItem = nullptr; + name = L""; +} + +void BeaconTileEntity::tick() { + // 4J Stu - Added levels check to force an initial tick + if ((!level->isClientSide && levels < 0) || + (level->getGameTime() % (SharedConstants::TICKS_PER_SECOND * 4)) == 0) { + updateShape(); + applyEffects(); + } +} + +void BeaconTileEntity::applyEffects() { + if (isActive && levels > 0 && !level->isClientSide && primaryPower > 0) { + double range = (levels * 10) + 10; + int baseAmp = 0; + if (levels >= 4 && primaryPower == secondaryPower) { + baseAmp = 1; + } + + AABB* bb = AABB::newTemp(x, y, z, x + 1, y + 1, z + 1) + ->grow(range, range, range); + bb->y1 = level->getMaxBuildHeight(); + std::vector >* players = + level->getEntitiesOfClass(typeid(Player), bb); + for (AUTO_VAR(it, players->begin()); it != players->end(); ++it) { + std::shared_ptr player = + std::dynamic_pointer_cast(*it); + player->addEffect(new MobEffectInstance( + primaryPower, SharedConstants::TICKS_PER_SECOND * 9, baseAmp, + true)); + } + + if (levels >= 4 && primaryPower != secondaryPower && + secondaryPower > 0) { + for (AUTO_VAR(it, players->begin()); it != players->end(); ++it) { + std::shared_ptr player = + std::dynamic_pointer_cast(*it); + player->addEffect(new MobEffectInstance( + secondaryPower, SharedConstants::TICKS_PER_SECOND * 9, 0, + true)); + } + } + delete players; + } +} + +void BeaconTileEntity::updateShape() { + if (!level->canSeeSky(x, y + 1, z)) { + isActive = false; + levels = 0; + } else { + isActive = true; + + levels = 0; + for (int step = 1; step <= 4; step++) { + int ly = y - step; + if (ly < 0) { + break; + } + + bool isOk = true; + for (int lx = x - step; lx <= x + step && isOk; lx++) { + for (int lz = z - step; lz <= z + step; lz++) { + int tile = level->getTile(lx, ly, lz); + if (tile != Tile::emeraldBlock_Id && + tile != Tile::goldBlock_Id && + tile != Tile::diamondBlock_Id && + tile != Tile::ironBlock_Id) { + isOk = false; + break; + } + } + } + if (isOk) { + levels = step; + } else { + break; + } + } + if (levels == 0) { + isActive = false; + } + } +} + +float BeaconTileEntity::getAndUpdateClientSideScale() { + if (!isActive) { + return 0; + } + + int renderDelta = (int)(level->getGameTime() - clientSideRenderTick); + clientSideRenderTick = level->getGameTime(); + if (renderDelta > 1) { + clientSideRenderScale -= ((float)renderDelta / (float)SCALE_TIME); + + if (clientSideRenderScale < 0) { + clientSideRenderScale = 0; + } + } + clientSideRenderScale += (1.0f / (float)SCALE_TIME); + if (clientSideRenderScale > 1) { + clientSideRenderScale = 1; + } + return clientSideRenderScale; +} + +int BeaconTileEntity::getPrimaryPower() { return primaryPower; } + +int BeaconTileEntity::getSecondaryPower() { return secondaryPower; } + +int BeaconTileEntity::getLevels() { return levels; } + +// client-side method used by GUI +void BeaconTileEntity::setLevels(int levels) { this->levels = levels; } + +void BeaconTileEntity::setPrimaryPower(int primaryPower) { + this->primaryPower = 0; + + // verify power + for (int tier = 0; tier < levels && tier < 3; tier++) { + for (unsigned int e = 0; e < BEACON_EFFECTS_EFFECTS; ++e) { + MobEffect* effect = BEACON_EFFECTS[tier][e]; + if (effect == NULL) break; + + if (effect->id == primaryPower) { + this->primaryPower = primaryPower; + return; + } + } + } +} + +void BeaconTileEntity::setSecondaryPower(int secondaryPower) { + this->secondaryPower = 0; + + // verify power + if (levels >= 4) { + for (int tier = 0; tier < 4; tier++) { + for (unsigned int e = 0; e < BEACON_EFFECTS_EFFECTS; ++e) { + MobEffect* effect = BEACON_EFFECTS[tier][e]; + if (effect == NULL) break; + + if (effect->id == secondaryPower) { + this->secondaryPower = secondaryPower; + return; + } + } + } + } +} + +std::shared_ptr BeaconTileEntity::getUpdatePacket() { + CompoundTag* tag = new CompoundTag(); + save(tag); + return std::shared_ptr(new TileEntityDataPacket( + x, y, z, TileEntityDataPacket::TYPE_BEACON, tag)); +} + +double BeaconTileEntity::getViewDistance() { return 256 * 256; } + +void BeaconTileEntity::load(CompoundTag* tag) { + TileEntity::load(tag); + + primaryPower = tag->getInt(L"Primary"); + secondaryPower = tag->getInt(L"Secondary"); + levels = tag->getInt(L"Levels"); +} + +void BeaconTileEntity::save(CompoundTag* tag) { + TileEntity::save(tag); + + tag->putInt(L"Primary", primaryPower); + tag->putInt(L"Secondary", secondaryPower); + // this value is re-calculated, but save it anyway to avoid update lag + tag->putInt(L"Levels", levels); +} + +unsigned int BeaconTileEntity::getContainerSize() { return 1; } + +std::shared_ptr BeaconTileEntity::getItem(unsigned int slot) { + if (slot == 0) { + return paymentItem; + } + return nullptr; +} + +std::shared_ptr BeaconTileEntity::removeItem(unsigned int slot, + int count) { + if (slot == 0 && paymentItem != NULL) { + if (count >= paymentItem->count) { + std::shared_ptr returnItem = paymentItem; + paymentItem = nullptr; + return returnItem; + } else { + paymentItem->count -= count; + return std::shared_ptr(new ItemInstance( + paymentItem->id, count, paymentItem->getAuxValue())); + } + } + return nullptr; +} + +std::shared_ptr BeaconTileEntity::removeItemNoUpdate(int slot) { + if (slot == 0 && paymentItem != NULL) { + std::shared_ptr returnItem = paymentItem; + paymentItem = nullptr; + return returnItem; + } + return nullptr; +} + +void BeaconTileEntity::setItem(unsigned int slot, + std::shared_ptr item) { + if (slot == 0) { + paymentItem = item; + } +} + +std::wstring BeaconTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_CONTAINER_BEACON); +} + +std::wstring BeaconTileEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +bool BeaconTileEntity::hasCustomName() { return !name.empty(); } + +void BeaconTileEntity::setCustomName(const std::wstring& name) { + this->name = name; +} + +int BeaconTileEntity::getMaxStackSize() { return 1; } + +bool BeaconTileEntity::stillValid(std::shared_ptr player) { + if (level->getTileEntity(x, y, z) != shared_from_this()) return false; + if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; + return true; +} + +void BeaconTileEntity::startOpen() {} + +void BeaconTileEntity::stopOpen() {} + +bool BeaconTileEntity::canPlaceItem(int slot, + std::shared_ptr item) { + return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || + item->id == Item::goldIngot_Id || item->id == Item::ironIngot_Id); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.h b/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.h new file mode 100644 index 000000000..7006360f1 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.h @@ -0,0 +1,75 @@ +#pragma once +#include "TileEntity.h" +#include "../../Containers/Container.h" + +class BeaconTileEntity : public TileEntity, public Container { +public: + eINSTANCEOF GetType() { return eTYPE_BEACONTILEENTITY; } + static TileEntity* create() { return new BeaconTileEntity(); } + // 4J Added + virtual std::shared_ptr clone(); + +private: + static const int SCALE_TIME = SharedConstants::TICKS_PER_SECOND * 2; + +public: + static const int BEACON_EFFECTS_TIERS = 4; + static const int BEACON_EFFECTS_EFFECTS = 3; + static MobEffect* BEACON_EFFECTS[BEACON_EFFECTS_TIERS] + [BEACON_EFFECTS_EFFECTS]; + + static void staticCtor(); + +private: + __int64 clientSideRenderTick; + float clientSideRenderScale; + + bool isActive; + int levels; + + int primaryPower; + int secondaryPower; + + std::shared_ptr paymentItem; + std::wstring name; + +public: + BeaconTileEntity(); + + void tick(); + +private: + void applyEffects(); + void updateShape(); + +public: + float getAndUpdateClientSideScale(); + int getPrimaryPower(); + int getSecondaryPower(); + int getLevels(); + // client-side method used by GUI + void setLevels(int levels); + void setPrimaryPower(int primaryPower); + void setSecondaryPower(int secondaryPower); + std::shared_ptr getUpdatePacket(); + double getViewDistance(); + void load(CompoundTag* tag); + void save(CompoundTag* tag); + unsigned int getContainerSize(); + std::shared_ptr getItem(unsigned int slot); + std::shared_ptr removeItem(unsigned int slot, int count); + std::shared_ptr removeItemNoUpdate(int slot); + void setItem(unsigned int slot, std::shared_ptr item); + std::wstring getName(); + std::wstring getCustomName(); + bool hasCustomName(); + void setCustomName(const std::wstring& name); + int getMaxStackSize(); + bool stillValid(std::shared_ptr player); + void startOpen(); + void stopOpen(); + bool canPlaceItem(int slot, std::shared_ptr item); + + // 4J Stu - For container + virtual void setChanged() { TileEntity::setChanged(); } +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp index da34405c8..09d36fc35 100644 --- a/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp @@ -2,18 +2,39 @@ #include "../../Headers/com.mojang.nbt.h" #include "BrewingStandTileEntity.h" #include "../../Util/SharedConstants.h" +#include "../../Headers/net.minecraft.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.alchemy.h" +int slotsForUp[] = {BrewingStandTileEntity::INGREDIENT_SLOT}; +int slotsForOtherFaces[] = {0, 1, 2}; + +intArray BrewingStandTileEntity::SLOTS_FOR_UP = intArray(slotsForUp, 1); +intArray BrewingStandTileEntity::SLOTS_FOR_OTHER_FACES = + intArray(slotsForOtherFaces, 3); + BrewingStandTileEntity::BrewingStandTileEntity() { brewTime = 0; items = ItemInstanceArray(4); + name = L""; } BrewingStandTileEntity::~BrewingStandTileEntity() { delete[] items.data; } -int BrewingStandTileEntity::getName() { return IDS_TILE_BREWINGSTAND; } +std::wstring BrewingStandTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_TILE_BREWINGSTAND); +} + +std::wstring BrewingStandTileEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +bool BrewingStandTileEntity::hasCustomName() { return !name.empty(); } + +void BrewingStandTileEntity::setCustomName(const std::wstring& name) { + this->name = name; +} unsigned int BrewingStandTileEntity::getContainerSize() { return items.length; } @@ -41,7 +62,7 @@ void BrewingStandTileEntity::tick() { int newCount = getPotionBits(); if (newCount != lastPotionCount) { lastPotionCount = newCount; - level->setData(x, y, z, newCount); + level->setData(x, y, z, newCount, Tile::UPDATE_CLIENTS); } TileEntity::tick(); @@ -106,7 +127,7 @@ bool BrewingStandTileEntity::isBrewable() { } else { if (!Item::items[ingredient->id]->hasPotionBrewingFormula() && ingredient->id != Item::bucket_water_Id && - ingredient->id != Item::netherStalkSeeds_Id) { + ingredient->id != Item::netherwart_seeds_Id) { return false; } bool isWater = ingredient->id == Item::bucket_water_Id; @@ -220,7 +241,7 @@ int BrewingStandTileEntity::applyIngredient( return PotionBrewing::applyBrew(currentBrew, PotionBrewing::MOD_WATER); } - if (ingredient->id == Item::netherStalkSeeds_Id) { + if (ingredient->id == Item::netherwart_seeds_Id) { return PotionBrewing::stirr(currentBrew); } #endif @@ -236,18 +257,19 @@ int BrewingStandTileEntity::applyIngredient( void BrewingStandTileEntity::load(CompoundTag* base) { TileEntity::load(base); - ListTag* inventoryList = base->getList(L"Items"); - + ListTag* inventoryList = + (ListTag*)base->getList(L"Items"); delete[] items.data; items = ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { - CompoundTag* tag = (CompoundTag*)inventoryList->get(i); + CompoundTag* tag = inventoryList->get(i); int slot = tag->getByte(L"Slot"); if (slot >= 0 && slot < items.length) items[slot] = ItemInstance::fromTag(tag); } brewTime = base->getShort(L"BrewTime"); + if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); } void BrewingStandTileEntity::save(CompoundTag* base) { @@ -265,6 +287,7 @@ void BrewingStandTileEntity::save(CompoundTag* base) { } } base->put(L"Items", listTag); + if (hasCustomName()) base->putString(L"CustomName", name); } std::shared_ptr BrewingStandTileEntity::getItem( @@ -319,7 +342,10 @@ void BrewingStandTileEntity::setItem(unsigned int slot, } } -int BrewingStandTileEntity::getMaxStackSize() { return 1; } +int BrewingStandTileEntity::getMaxStackSize() { + // this value is not used for the potion slots + return 64; +} bool BrewingStandTileEntity::stillValid(std::shared_ptr player) { if (level->getTileEntity(x, y, z) != shared_from_this()) return false; @@ -331,7 +357,22 @@ void BrewingStandTileEntity::startOpen() {} void BrewingStandTileEntity::stopOpen() {} -void BrewingStandTileEntity::setBrewTime(int value) { this->brewTime = value; } +bool BrewingStandTileEntity::canPlaceItem(int slot, + std::shared_ptr item) { + if (slot == INGREDIENT_SLOT) { + if (PotionBrewing::SIMPLIFIED_BREWING) { + return Item::items[item->id]->hasPotionBrewingFormula(); + } else { + return Item::items[item->id]->hasPotionBrewingFormula() || + item->id == Item::netherwart_seeds_Id || + item->id == Item::bucket_water_Id; + } + } + + return item->id == Item::potion_Id || item->id == Item::glassBottle_Id; +} + +void BrewingStandTileEntity::setBrewTime(int value) { brewTime = value; } int BrewingStandTileEntity::getPotionBits() { int newCount = 0; @@ -343,6 +384,24 @@ int BrewingStandTileEntity::getPotionBits() { return newCount; } +intArray BrewingStandTileEntity::getSlotsForFace(int face) { + if (face == Facing::UP) { + return SLOTS_FOR_UP; + } + + return SLOTS_FOR_OTHER_FACES; +} + +bool BrewingStandTileEntity::canPlaceItemThroughFace( + int slot, std::shared_ptr item, int face) { + return canPlaceItem(slot, item); +} + +bool BrewingStandTileEntity::canTakeItemThroughFace( + int slot, std::shared_ptr item, int face) { + return true; +} + // 4J Added std::shared_ptr BrewingStandTileEntity::clone() { std::shared_ptr result = @@ -359,4 +418,4 @@ std::shared_ptr BrewingStandTileEntity::clone() { } } return result; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.h b/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.h index cfe569fd5..13f689576 100644 --- a/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.h @@ -1,24 +1,31 @@ #pragma once #include "TileEntity.h" -#include "../../Containers/Container.h" +#include "../../Containers/WorldlyContainer.h" -class BrewingStandTileEntity : public TileEntity, public Container { +class BrewingStandTileEntity : public TileEntity, public WorldlyContainer { public: eINSTANCEOF GetType() { return eTYPE_BREWINGSTANDTILEENTITY; } static TileEntity* create() { return new BrewingStandTileEntity(); } + static const int INGREDIENT_SLOT = 3; + private: ItemInstanceArray items; - static const int INGREDIENT_SLOT = 3; + static intArray SLOTS_FOR_UP; + static intArray SLOTS_FOR_OTHER_FACES; int brewTime; int lastPotionCount; int ingredientId; + std::wstring name; public: BrewingStandTileEntity(); ~BrewingStandTileEntity(); - virtual int getName(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual void setCustomName(const std::wstring& name); virtual unsigned int getContainerSize(); virtual void tick(); @@ -42,9 +49,17 @@ public: virtual bool stillValid(std::shared_ptr player); virtual void startOpen(); virtual void stopOpen(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); virtual void setBrewTime(int value); - virtual void setChanged() {} // 4J added + virtual void setChanged() { TileEntity::setChanged(); } // 4J added int getPotionBits(); + virtual intArray getSlotsForFace(int face); + virtual bool canPlaceItemThroughFace(int slot, + std::shared_ptr item, + int face); + virtual bool canTakeItemThroughFace(int slot, + std::shared_ptr item, + int face); // 4J Added virtual std::shared_ptr clone(); diff --git a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp index 35ad31166..d1cbd500b 100644 --- a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp @@ -1,18 +1,26 @@ - - #include "../../Platform/stdafx.h" #include "../../Headers/com.mojang.nbt.h" +#include "../../Headers/net.minecraft.world.h" #include "../../Headers/net.minecraft.world.level.h" #include "TileEntity.h" #include "../../Headers/net.minecraft.world.entity.item.h" #include "../../Headers/net.minecraft.world.entity.player.h" #include "../../Headers/net.minecraft.world.item.h" +#include "../../Headers/net.minecraft.world.inventory.h" #include "../../Headers/net.minecraft.world.level.tile.h" +#include "../../Headers/net.minecraft.world.phys.h" #include "ChestTileEntity.h" +#include "../../Network/Packets/ContainerOpenPacket.h" #include "../../Util/SoundTypes.h" -ChestTileEntity::ChestTileEntity(bool isBonusChest /* = false*/) - : TileEntity() { +int ChestTileEntity::getContainerType() { + if (isBonusChest) + return ContainerOpenPacket::BONUS_CHEST; + else + return ContainerOpenPacket::CONTAINER; +} + +void ChestTileEntity::_init(bool isBonusChest) { items = new ItemInstanceArray(9 * 4); hasCheckedNeighbors = false; @@ -22,6 +30,21 @@ ChestTileEntity::ChestTileEntity(bool isBonusChest /* = false*/) oOpenness = 0.0f; openCount = 0; tickInterval = 0; + + type = -1; + name = L""; +} + +ChestTileEntity::ChestTileEntity(bool isBonusChest /* = false*/) + : TileEntity() { + _init(isBonusChest); +} + +ChestTileEntity::ChestTileEntity(int type, bool isBonusChest /* = false*/) + : TileEntity() { + _init(isBonusChest); + + this->type = type; } ChestTileEntity::~ChestTileEntity() { @@ -41,14 +64,14 @@ std::shared_ptr ChestTileEntity::removeItem(unsigned int slot, if (items->data[slot]->count <= count) { std::shared_ptr item = items->data[slot]; items->data[slot] = nullptr; - this->setChanged(); + setChanged(); // 4J Stu - Fix for duplication glitch if (item->count <= 0) return nullptr; return item; } else { std::shared_ptr i = items->data[slot]->remove(count); if (items->data[slot]->count == 0) items->data[slot] = nullptr; - this->setChanged(); + setChanged(); // 4J Stu - Fix for duplication glitch if (i->count <= 0) return nullptr; return i; @@ -74,22 +97,32 @@ void ChestTileEntity::setItem(unsigned int slot, this->setChanged(); } -int ChestTileEntity::getName() { return IDS_TILE_CHEST; } +std::wstring ChestTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_TILE_CHEST); +} + +std::wstring ChestTileEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +bool ChestTileEntity::hasCustomName() { return !name.empty(); } + +void ChestTileEntity::setCustomName(const std::wstring& name) { + this->name = name; +} void ChestTileEntity::load(CompoundTag* base) { TileEntity::load(base); - - // 4jcraft, fixed cast of templated List to get the tag list - // and cast it to CompoundTag inside the loop - ListTag* inventoryList = base->getList(L"Items"); - + ListTag* inventoryList = + (ListTag*)base->getList(L"Items"); if (items) { delete[] items->data; delete items; } items = new ItemInstanceArray(getContainerSize()); + if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); for (int i = 0; i < inventoryList->size(); i++) { - CompoundTag* tag = (CompoundTag*)inventoryList->get(i); + CompoundTag* tag = inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot") & 0xff; if (slot >= 0 && slot < items->length) (*items)[slot] = ItemInstance::fromTag(tag); @@ -110,6 +143,7 @@ void ChestTileEntity::save(CompoundTag* base) { } } base->put(L"Items", listTag); + if (hasCustomName()) base->putString(L"CustomName", name); base->putBoolean(L"bonus", isBonusChest); } @@ -130,6 +164,28 @@ void ChestTileEntity::clearCache() { hasCheckedNeighbors = false; } +void ChestTileEntity::heyImYourNeighbor( + std::shared_ptr neighbor, int from) { + if (neighbor->isRemoved()) { + hasCheckedNeighbors = false; + } else if (hasCheckedNeighbors) { + switch (from) { + case Direction::NORTH: + if (n.lock() != neighbor) hasCheckedNeighbors = false; + break; + case Direction::SOUTH: + if (s.lock() != neighbor) hasCheckedNeighbors = false; + break; + case Direction::EAST: + if (e.lock() != neighbor) hasCheckedNeighbors = false; + break; + case Direction::WEST: + if (w.lock() != neighbor) hasCheckedNeighbors = false; + break; + } + } +} + void ChestTileEntity::checkNeighbors() { if (hasCheckedNeighbors) return; @@ -139,36 +195,79 @@ void ChestTileEntity::checkNeighbors() { w = std::weak_ptr(); s = std::weak_ptr(); - if (level->getTile(x - 1, y, z) == Tile::chest_Id) { + if (isSameChest(x - 1, y, z)) { w = std::dynamic_pointer_cast( level->getTileEntity(x - 1, y, z)); } - if (level->getTile(x + 1, y, z) == Tile::chest_Id) { + if (isSameChest(x + 1, y, z)) { e = std::dynamic_pointer_cast( level->getTileEntity(x + 1, y, z)); } - if (level->getTile(x, y, z - 1) == Tile::chest_Id) { + if (isSameChest(x, y, z - 1)) { n = std::dynamic_pointer_cast( level->getTileEntity(x, y, z - 1)); } - if (level->getTile(x, y, z + 1) == Tile::chest_Id) { + if (isSameChest(x, y, z + 1)) { s = std::dynamic_pointer_cast( level->getTileEntity(x, y, z + 1)); } - if (n.lock() != NULL) n.lock()->clearCache(); - if (s.lock() != NULL) s.lock()->clearCache(); - if (e.lock() != NULL) e.lock()->clearCache(); - if (w.lock() != NULL) w.lock()->clearCache(); + std::shared_ptr cteThis = + std::dynamic_pointer_cast(shared_from_this()); + if (n.lock() != NULL) + n.lock()->heyImYourNeighbor(cteThis, Direction::SOUTH); + if (s.lock() != NULL) + s.lock()->heyImYourNeighbor(cteThis, Direction::NORTH); + if (e.lock() != NULL) e.lock()->heyImYourNeighbor(cteThis, Direction::WEST); + if (w.lock() != NULL) w.lock()->heyImYourNeighbor(cteThis, Direction::EAST); +} + +bool ChestTileEntity::isSameChest(int x, int y, int z) { + Tile* tile = Tile::tiles[level->getTile(x, y, z)]; + if (tile == NULL || !(dynamic_cast(tile) != NULL)) return false; + return ((ChestTile*)tile)->type == getType(); } void ChestTileEntity::tick() { TileEntity::tick(); checkNeighbors(); - if (++tickInterval % 20 * 4 == 0) { - // level->tileEvent(x, y, z, ChestTile::EVENT_SET_OPEN_COUNT, - // openCount); + ++tickInterval; + if (!level->isClientSide && openCount != 0 && + (tickInterval + x + y + z) % (SharedConstants::TICKS_PER_SECOND * 10) == + 0) { + // level.tileEvent(x, y, z, Tile.chest.id, + // ChestTile.EVENT_SET_OPEN_COUNT, openCount); + + openCount = 0; + + float range = 5; + std::vector >* players = + level->getEntitiesOfClass( + typeid(Player), + AABB::newTemp(x - range, y - range, z - range, x + 1 + range, + y + 1 + range, z + 1 + range)); + for (AUTO_VAR(it, players->begin()); it != players->end(); ++it) { + std::shared_ptr player = + std::dynamic_pointer_cast(*it); + + ContainerMenu* containerMenu = + dynamic_cast(player->containerMenu); + if (containerMenu != NULL) { + std::shared_ptr container = + containerMenu->getContainer(); + std::shared_ptr thisContainer = + std::dynamic_pointer_cast(shared_from_this()); + std::shared_ptr compoundContainer = + std::dynamic_pointer_cast(container); + if ((container == thisContainer) || + (compoundContainer != NULL && + compoundContainer->contains(thisContainer))) { + openCount++; + } + } + } + delete players; } oOpenness = openness; @@ -220,28 +319,56 @@ void ChestTileEntity::tick() { } } -void ChestTileEntity::triggerEvent(int b0, int b1) { +bool ChestTileEntity::triggerEvent(int b0, int b1) { if (b0 == ChestTile::EVENT_SET_OPEN_COUNT) { openCount = b1; + return true; } + return TileEntity::triggerEvent(b0, b1); } void ChestTileEntity::startOpen() { + if (openCount < 0) { + openCount = 0; + } openCount++; - level->tileEvent(x, y, z, Tile::chest_Id, ChestTile::EVENT_SET_OPEN_COUNT, + level->tileEvent(x, y, z, getTile()->id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); + level->updateNeighborsAt(x, y, z, getTile()->id); + level->updateNeighborsAt(x, y - 1, z, getTile()->id); } void ChestTileEntity::stopOpen() { + if (getTile() == NULL || !(dynamic_cast(getTile()) != NULL)) + return; openCount--; - level->tileEvent(x, y, z, Tile::chest_Id, ChestTile::EVENT_SET_OPEN_COUNT, + level->tileEvent(x, y, z, getTile()->id, ChestTile::EVENT_SET_OPEN_COUNT, openCount); + level->updateNeighborsAt(x, y, z, getTile()->id); + level->updateNeighborsAt(x, y - 1, z, getTile()->id); +} + +bool ChestTileEntity::canPlaceItem(int slot, + std::shared_ptr item) { + return true; } void ChestTileEntity::setRemoved() { + TileEntity::setRemoved(); clearCache(); checkNeighbors(); - TileEntity::setRemoved(); +} + +int ChestTileEntity::getType() { + if (type == -1) { + if (level != NULL && dynamic_cast(getTile()) != NULL) { + type = ((ChestTile*)getTile())->type; + } else { + return ChestTile::TYPE_BASIC; + } + } + + return type; } // 4J Added @@ -256,4 +383,4 @@ std::shared_ptr ChestTileEntity::clone() { } } return result; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.h b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.h index 83f4d3b3e..5705aa8e2 100644 --- a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.h @@ -13,10 +13,16 @@ public: eINSTANCEOF GetType() { return eTYPE_CHESTTILEENTITY; } static TileEntity* create() { return new ChestTileEntity(); } + int getContainerType(); // 4J-Added; + using TileEntity::setChanged; +private: + void _init(bool isBonusChest); + public: - ChestTileEntity(bool isBonusChest = false); // 4J added param + ChestTileEntity(bool isBonusChest = false); // 4J added param + ChestTileEntity(int type, bool isBonusChest = false); // 4J added param virtual ~ChestTileEntity(); private: @@ -36,6 +42,9 @@ public: private: int tickInterval; + int type; + std::wstring name; + public: virtual unsigned int getContainerSize(); virtual std::shared_ptr getItem(unsigned int slot); @@ -43,19 +52,35 @@ public: int count); virtual std::shared_ptr removeItemNoUpdate(int slot); virtual void setItem(unsigned int slot, std::shared_ptr item); - virtual int getName(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual void setCustomName(const std::wstring& name); virtual void load(CompoundTag* base); virtual void save(CompoundTag* base); virtual int getMaxStackSize(); virtual bool stillValid(std::shared_ptr player); virtual void setChanged(); virtual void clearCache(); + +private: + virtual void heyImYourNeighbor(std::shared_ptr neighbor, + int from); + +public: virtual void checkNeighbors(); + +private: + bool isSameChest(int x, int y, int z); + +public: virtual void tick(); - virtual void triggerEvent(int b0, int b1); + virtual bool triggerEvent(int b0, int b1); virtual void startOpen(); virtual void stopOpen(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); virtual void setRemoved(); + virtual int getType(); // 4J Added virtual std::shared_ptr clone(); diff --git a/Minecraft.World/Blocks/TileEntities/CommandBlockEntity.cpp b/Minecraft.World/Blocks/TileEntities/CommandBlockEntity.cpp new file mode 100644 index 000000000..8734c8404 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/CommandBlockEntity.cpp @@ -0,0 +1,99 @@ +#include "../../Platform/stdafx.h" +#include "../../Headers/net.minecraft.network.packet.h" +#include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.commands.h" +#include "../../../Minecraft.Client/MinecraftServer.h" +#include "CommandBlockEntity.h" + +CommandBlockEntity::CommandBlockEntity() { + successCount = 0; + command = L""; + name = L"@"; +} + +void CommandBlockEntity::setCommand(const std::wstring& command) { + this->command = command; + setChanged(); +} + +std::wstring CommandBlockEntity::getCommand() { return command; } + +int CommandBlockEntity::performCommand(Level* level) { +#if 0 + if (level->isClientSide) + { + return 0; + } + + MinecraftServer *instance = MinecraftServer::getInstance(); + if (instance != NULL && instance->isCommandBlockEnabled()) + { + CommandDispatcher *commandDispatcher = instance->getCommandDispatcher(); + return commandDispatcher->performCommand(std::dynamic_pointer_cast(shared_from_this()), command, byteArray() ); + } + return 0; +#else + // 4J-JEV: Cannot decide what to do with the command field. + assert(false); + return 0; +#endif +} + +std::wstring CommandBlockEntity::getName() { return name; } + +void CommandBlockEntity::setName(const std::wstring& name) { + this->name = name; +} + +void CommandBlockEntity::sendMessage(const std::wstring& message, + ChatPacket::EChatPacketMessage type, + int customData, + const std::wstring& additionalMessage) {} + +bool CommandBlockEntity::hasPermission(EGameCommand command) { return false; } + +void CommandBlockEntity::save(CompoundTag* tag) { + TileEntity::save(tag); + tag->putString(L"Command", command); + tag->putInt(L"SuccessCount", successCount); + tag->putString(L"CustomName", name); +} + +void CommandBlockEntity::load(CompoundTag* tag) { + TileEntity::load(tag); + command = tag->getString(L"Command"); + successCount = tag->getInt(L"SuccessCount"); + if (tag->contains(L"CustomName")) name = tag->getString(L"CustomName"); +} + +Pos* CommandBlockEntity::getCommandSenderWorldPosition() { + return new Pos(x, y, z); +} + +Level* CommandBlockEntity::getCommandSenderWorld() { return getLevel(); } + +std::shared_ptr CommandBlockEntity::getUpdatePacket() { + CompoundTag* tag = new CompoundTag(); + save(tag); + return std::shared_ptr(new TileEntityDataPacket( + x, y, z, TileEntityDataPacket::TYPE_ADV_COMMAND, tag)); +} + +int CommandBlockEntity::getSuccessCount() { return successCount; } + +void CommandBlockEntity::setSuccessCount(int successCount) { + this->successCount = successCount; +} + +// 4J Added +std::shared_ptr CommandBlockEntity::clone() { + std::shared_ptr result = + std::shared_ptr(new CommandBlockEntity()); + TileEntity::clone(result); + + result->successCount = successCount; + result->command = command; + result->name = name; + + return result; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/CommandBlockEntity.h b/Minecraft.World/Blocks/TileEntities/CommandBlockEntity.h new file mode 100644 index 000000000..c6d4fae6f --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/CommandBlockEntity.h @@ -0,0 +1,43 @@ +#pragma once + +#include "TileEntity.h" +#include "../../Commands/CommandSender.h" + +class ChatMessageComponent; + +class CommandBlockEntity : public TileEntity, public CommandSender { +public: + eINSTANCEOF GetType() { return eTYPE_COMMANDBLOCKTILEENTITY; } + static TileEntity* create() { return new CommandBlockEntity(); } + + // 4J Added + virtual std::shared_ptr clone(); + +private: + int successCount; + std::wstring command; + std::wstring name; + +public: + CommandBlockEntity(); + + void setCommand(const std::wstring& command); + std::wstring getCommand(); + int performCommand(Level* level); + std::wstring getName(); + void setName(const std::wstring& name); + virtual void sendMessage( + const std::wstring& message, + ChatPacket::EChatPacketMessage type = ChatPacket::e_ChatCustom, + int customData = -1, const std::wstring& additionalMessage = L""); + virtual bool hasPermission(EGameCommand command); + // void sendMessage(ChatMessageComponent *message); + // bool hasPermission(int permissionLevel, const std::wstring &commandName); + void save(CompoundTag* tag); + void load(CompoundTag* tag); + Pos* getCommandSenderWorldPosition(); + Level* getCommandSenderWorld(); + std::shared_ptr getUpdatePacket(); + int getSuccessCount(); + void setSuccessCount(int successCount); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.cpp new file mode 100644 index 000000000..35aa56b83 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.cpp @@ -0,0 +1,28 @@ +#include "../../Platform/stdafx.h" + +#include "ComparatorTileEntity.h" + +void ComparatorTileEntity::save(CompoundTag* tag) { + TileEntity::save(tag); + tag->putInt(L"OutputSignal", output); +} + +void ComparatorTileEntity::load(CompoundTag* tag) { + TileEntity::load(tag); + output = tag->getInt(L"OutputSignal"); +} + +int ComparatorTileEntity::getOutputSignal() { return output; } + +void ComparatorTileEntity::setOutputSignal(int value) { output = value; } + +// 4J Added +std::shared_ptr ComparatorTileEntity::clone() { + std::shared_ptr result = + std::shared_ptr(new ComparatorTileEntity()); + TileEntity::clone(result); + + result->output = output; + + return result; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.h b/Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.h new file mode 100644 index 000000000..13f3bda82 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/ComparatorTileEntity.h @@ -0,0 +1,21 @@ +#pragma once + +#include "TileEntity.h" + +class ComparatorTileEntity : public TileEntity { +public: + eINSTANCEOF GetType() { return eTYPE_COMPARATORTILEENTITY; } + static TileEntity* create() { return new ComparatorTileEntity(); } + + // 4J Added + virtual std::shared_ptr clone(); + +private: + int output; + +public: + void save(CompoundTag* tag); + void load(CompoundTag* tag); + int getOutputSignal(); + void setOutputSignal(int value); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.cpp new file mode 100644 index 000000000..745c99a4a --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.cpp @@ -0,0 +1,26 @@ +#include "../../Platform/stdafx.h" +#include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.tile.h" +#include "DaylightDetectorTileEntity.h" + +DaylightDetectorTileEntity::DaylightDetectorTileEntity() {} + +void DaylightDetectorTileEntity::tick() { + if (level != NULL && !level->isClientSide && + (level->getGameTime() % SharedConstants::TICKS_PER_SECOND) == 0) { + tile = getTile(); + if (tile != NULL && dynamic_cast(tile) != NULL) { + ((DaylightDetectorTile*)tile)->updateSignalStrength(level, x, y, z); + } + } +} + +// 4J Added +std::shared_ptr DaylightDetectorTileEntity::clone() { + std::shared_ptr result = + std::shared_ptr( + new DaylightDetectorTileEntity()); + TileEntity::clone(result); + + return result; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.h b/Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.h new file mode 100644 index 000000000..29a377b2e --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/DaylightDetectorTileEntity.h @@ -0,0 +1,15 @@ +#pragma once + +class DaylightDetectorTileEntity : public TileEntity { +public: + eINSTANCEOF GetType() { return eTYPE_DAYLIGHTDETECTORTILEENTITY; } + static TileEntity* create() { return new DaylightDetectorTileEntity(); } + + // 4J Added + virtual std::shared_ptr clone(); + +public: + DaylightDetectorTileEntity(); + + void tick(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.cpp index e1c79cc57..b87e7dd56 100644 --- a/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.cpp @@ -1,5 +1,3 @@ - - #include "../../Platform/stdafx.h" #include "../../Headers/com.mojang.nbt.h" #include "TileEntity.h" @@ -10,13 +8,13 @@ #include "DispenserTileEntity.h" DispenserTileEntity::DispenserTileEntity() : TileEntity() { - items = new ItemInstanceArray(9); + items = ItemInstanceArray(9); random = new Random(); + name = L""; } DispenserTileEntity::~DispenserTileEntity() { - delete[] items->data; - delete items; + delete[] items.data; delete random; } @@ -24,23 +22,23 @@ DispenserTileEntity::~DispenserTileEntity() { unsigned int DispenserTileEntity::getContainerSize() { return 9; } std::shared_ptr DispenserTileEntity::getItem(unsigned int slot) { - return items->data[slot]; + return items[slot]; } std::shared_ptr DispenserTileEntity::removeItem(unsigned int slot, int count) { - if (items->data[slot] != NULL) { - if (items->data[slot]->count <= count) { - std::shared_ptr item = items->data[slot]; - items->data[slot] = nullptr; - this->setChanged(); + if (items[slot] != NULL) { + if (items[slot]->count <= count) { + std::shared_ptr item = items[slot]; + items[slot] = nullptr; + setChanged(); // 4J Stu - Fix for duplication glitch if (item->count <= 0) return nullptr; return item; } else { - std::shared_ptr i = items->data[slot]->remove(count); - if (items->data[slot]->count == 0) items->data[slot] = nullptr; - this->setChanged(); + std::shared_ptr i = items[slot]->remove(count); + if (items[slot]->count == 0) items[slot] = nullptr; + setChanged(); // 4J Stu - Fix for duplication glitch if (i->count <= 0) return nullptr; return i; @@ -51,9 +49,9 @@ std::shared_ptr DispenserTileEntity::removeItem(unsigned int slot, std::shared_ptr DispenserTileEntity::removeItemNoUpdate( int slot) { - if (items->data[slot] != NULL) { - std::shared_ptr item = items->data[slot]; - items->data[slot] = nullptr; + if (items[slot] != NULL) { + std::shared_ptr item = items[slot]; + items[slot] = nullptr; return item; } return nullptr; @@ -63,17 +61,17 @@ std::shared_ptr DispenserTileEntity::removeItemNoUpdate( // again void DispenserTileEntity::AddItemBack(std::shared_ptr item, unsigned int slot) { - if (items->data[slot] != NULL) { + if (items[slot] != NULL) { // just increment the count of the items - if (item->id == items->data[slot]->id) { - items->data[slot]->count++; - this->setChanged(); + if (item->id == items[slot]->id) { + items[slot]->count++; + setChanged(); } } else { - items->data[slot] = item; + items[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); - this->setChanged(); + setChanged(); } } /** @@ -83,8 +81,8 @@ void DispenserTileEntity::AddItemBack(std::shared_ptr item, * @return */ bool DispenserTileEntity::removeProjectile(int itemId) { - for (unsigned int i = 0; i < items->length; i++) { - if (items->data[i] != NULL && items->data[i]->id == itemId) { + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL && items[i]->id == itemId) { std::shared_ptr removedItem = removeItem(i, 1); return removedItem != NULL; } @@ -95,8 +93,8 @@ bool DispenserTileEntity::removeProjectile(int itemId) { int DispenserTileEntity::getRandomSlot() { int replaceSlot = -1; int replaceOdds = 1; - for (unsigned int i = 0; i < items->length; i++) { - if (items->data[i] != NULL && random->nextInt(replaceOdds++) == 0) { + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL && random->nextInt(replaceOdds++) == 0) { replaceSlot = i; } } @@ -106,16 +104,16 @@ int DispenserTileEntity::getRandomSlot() { void DispenserTileEntity::setItem(unsigned int slot, std::shared_ptr item) { - items->data[slot] = item; + items[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); - this->setChanged(); + setChanged(); } int DispenserTileEntity::addItem(std::shared_ptr item) { - for (int i = 0; i < items->length; i++) { - if ((*items)[i] == NULL || (*items)[i]->id == 0) { - (*items)[i] = item; + for (int i = 0; i < items.length; i++) { + if (items[i] == NULL || items[i]->id == 0) { + setItem(i, item); return i; } } @@ -123,34 +121,49 @@ int DispenserTileEntity::addItem(std::shared_ptr item) { return -1; } -int DispenserTileEntity::getName() { return IDS_TILE_DISPENSER; } +std::wstring DispenserTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_TILE_DISPENSER); +} + +std::wstring DispenserTileEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +void DispenserTileEntity::setCustomName(const std::wstring& name) { + this->name = name; +} + +bool DispenserTileEntity::hasCustomName() { return !name.empty(); } void DispenserTileEntity::load(CompoundTag* base) { TileEntity::load(base); ListTag* inventoryList = (ListTag*)base->getList(L"Items"); - items = new ItemInstanceArray(getContainerSize()); + delete[] items.data; + items = ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { CompoundTag* tag = inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot") & 0xff; - if (slot >= 0 && slot < items->length) - (*items)[slot] = ItemInstance::fromTag(tag); + if (slot >= 0 && slot < items.length) + items[slot] = ItemInstance::fromTag(tag); } + if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); } void DispenserTileEntity::save(CompoundTag* base) { TileEntity::save(base); ListTag* listTag = new ListTag; - for (unsigned int i = 0; i < items->length; i++) { - if (items->data[i] != NULL) { + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL) { CompoundTag* tag = new CompoundTag(); tag->putByte(L"Slot", (uint8_t)i); - items->data[i]->save(tag); + items[i]->save(tag); listTag->add(tag); } } base->put(L"Items", listTag); + if (hasCustomName()) base->putString(L"CustomName", name); } int DispenserTileEntity::getMaxStackSize() { @@ -169,15 +182,20 @@ void DispenserTileEntity::startOpen() {} void DispenserTileEntity::stopOpen() {} +bool DispenserTileEntity::canPlaceItem(int slot, + std::shared_ptr item) { + return true; +} + // 4J Added std::shared_ptr DispenserTileEntity::clone() { std::shared_ptr result = std::shared_ptr(new DispenserTileEntity()); TileEntity::clone(result); - for (unsigned int i = 0; i < items->length; i++) { - if (items->data[i] != NULL) { - result->items->data[i] = ItemInstance::clone(items->data[i]); + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL) { + result->items[i] = ItemInstance::clone(items[i]); } } return result; diff --git a/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.h b/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.h index 7ccb69d97..717f808b9 100644 --- a/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/DispenserTileEntity.h @@ -17,9 +17,12 @@ public: using TileEntity::setChanged; private: - ItemInstanceArray* items; + ItemInstanceArray items; Random* random; +protected: + std::wstring name; + public: DispenserTileEntity(); virtual ~DispenserTileEntity(); @@ -28,20 +31,24 @@ public: virtual std::shared_ptr getItem(unsigned int slot); virtual std::shared_ptr removeItem(unsigned int slot, int count); - std::shared_ptr removeItemNoUpdate(int slot); - bool removeProjectile(int itemId); - int getRandomSlot(); + virtual std::shared_ptr removeItemNoUpdate(int slot); + virtual bool removeProjectile(int itemId); + virtual int getRandomSlot(); virtual void setItem(unsigned int slot, std::shared_ptr item); virtual int addItem(std::shared_ptr item); - virtual int getName(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual void setCustomName(const std::wstring& name); + virtual bool hasCustomName(); virtual void load(CompoundTag* base); virtual void save(CompoundTag* base); virtual int getMaxStackSize(); virtual bool stillValid(std::shared_ptr player); virtual void setChanged(); - void startOpen(); - void stopOpen(); + virtual void startOpen(); + virtual void stopOpen(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); // 4J Added virtual std::shared_ptr clone(); diff --git a/Minecraft.World/Blocks/TileEntities/DropperTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/DropperTileEntity.cpp new file mode 100644 index 000000000..89e6c04dc --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/DropperTileEntity.cpp @@ -0,0 +1,18 @@ +#include "../../Platform/stdafx.h" + +#include "DropperTileEntity.h" + +std::wstring DropperTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_CONTAINER_DROPPER); +} + +// 4J Added +std::shared_ptr DropperTileEntity::clone() { + std::shared_ptr result = + std::shared_ptr(new DropperTileEntity()); + TileEntity::clone(result); + + result->name = name; + + return result; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/DropperTileEntity.h b/Minecraft.World/Blocks/TileEntities/DropperTileEntity.h new file mode 100644 index 000000000..a06c8af12 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/DropperTileEntity.h @@ -0,0 +1,14 @@ +#pragma once + +#include "DispenserTileEntity.h" + +class DropperTileEntity : public DispenserTileEntity { +public: + eINSTANCEOF GetType() { return eTYPE_DROPPERTILEENTITY; } + static TileEntity* create() { return new DropperTileEntity(); } + // 4J Added + virtual std::shared_ptr clone(); + +public: + std::wstring getName(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.cpp index f5fd2bba9..08def292b 100644 --- a/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.cpp @@ -16,10 +16,21 @@ EnchantmentTableEntity::EnchantmentTableEntity() { rot = 0.0f; oRot = 0.0f; tRot = 0.0f; + name = L""; } EnchantmentTableEntity::~EnchantmentTableEntity() { delete random; } +void EnchantmentTableEntity::save(CompoundTag* base) { + TileEntity::save(base); + if (hasCustomName()) base->putString(L"CustomName", name); +} + +void EnchantmentTableEntity::load(CompoundTag* base) { + TileEntity::load(base); + if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); +} + void EnchantmentTableEntity::tick() { TileEntity::tick(); oOpen = open; @@ -72,6 +83,20 @@ void EnchantmentTableEntity::tick() { flip = flip + flipA; } +std::wstring EnchantmentTableEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_ENCHANT); +} + +std::wstring EnchantmentTableEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +bool EnchantmentTableEntity::hasCustomName() { return !name.empty(); } + +void EnchantmentTableEntity::setCustomName(const std::wstring& name) { + this->name = name; +} + std::shared_ptr EnchantmentTableEntity::clone() { std::shared_ptr result = std::shared_ptr(new EnchantmentTableEntity()); diff --git a/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.h b/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.h index baefffca1..6ff6d5a56 100644 --- a/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/EnchantmentTableTileEntity.h @@ -15,11 +15,19 @@ public: private: Random* random; + std::wstring name; public: EnchantmentTableEntity(); ~EnchantmentTableEntity(); + + virtual void save(CompoundTag* base); + virtual void load(CompoundTag* base); virtual void tick(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual void setCustomName(const std::wstring& name); // 4J Added virtual std::shared_ptr clone(); diff --git a/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.cpp index 260875bb8..5a775d823 100644 --- a/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.cpp @@ -54,10 +54,12 @@ void EnderChestTileEntity::tick() { } } -void EnderChestTileEntity::triggerEvent(int b0, int b1) { +bool EnderChestTileEntity::triggerEvent(int b0, int b1) { if (b0 == ChestTile::EVENT_SET_OPEN_COUNT) { openCount = b1; + return true; } + return TileEntity::triggerEvent(b0, b1); } void EnderChestTileEntity::setRemoved() { diff --git a/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.h b/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.h index 59dbefbdb..7f2c987fd 100644 --- a/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/EnderChestTileEntity.h @@ -18,7 +18,7 @@ public: EnderChestTileEntity(); void tick(); - void triggerEvent(int b0, int b1); + bool triggerEvent(int b0, int b1); void setRemoved(); void startOpen(); void stopOpen(); diff --git a/Minecraft.World/Blocks/TileEntities/EntityTile.cpp b/Minecraft.World/Blocks/TileEntities/EntityTile.cpp deleted file mode 100644 index 302749035..000000000 --- a/Minecraft.World/Blocks/TileEntities/EntityTile.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "../../Platform/stdafx.h" -#include "../../Headers/net.minecraft.world.level.h" -#include "../../Headers/net.minecraft.world.entity.h" -#include "TileEntity.h" -#include "EntityTile.h" - -EntityTile::EntityTile(int id, Material* material, - bool isSolidRender /*= true*/) - : Tile(id, material, isSolidRender) { - _isEntityTile = true; -} - -void EntityTile::onPlace(Level* level, int x, int y, int z) { - Tile::onPlace(level, x, y, z); - level->setTileEntity(x, y, z, newTileEntity(level)); -} - -void EntityTile::onRemove(Level* level, int x, int y, int z, int id, int data) { - Tile::onRemove(level, x, y, z, id, data); - level->removeTileEntity(x, y, z); -} - -void EntityTile::triggerEvent(Level* level, int x, int y, int z, int b0, - int b1) { - Tile::triggerEvent(level, x, y, z, b0, b1); - std::shared_ptr te = level->getTileEntity(x, y, z); - if (te != NULL) { - te->triggerEvent(b0, b1); - } -} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/EntityTile.h b/Minecraft.World/Blocks/TileEntities/EntityTile.h index cf8d28b22..b92471121 100644 --- a/Minecraft.World/Blocks/TileEntities/EntityTile.h +++ b/Minecraft.World/Blocks/TileEntities/EntityTile.h @@ -1,16 +1,6 @@ #pragma once -#include "../Tile.h" - -class TileEntity; - -class EntityTile : public Tile { -protected: - EntityTile(int id, Material* material, bool isSolidRender = true); +class EntityTile { public: - virtual void onPlace(Level* level, int x, int y, int z); - virtual void onRemove(Level* level, int x, int y, int z, int id, int data); virtual std::shared_ptr newTileEntity(Level* level) = 0; - virtual void triggerEvent(Level* level, int x, int y, int z, int b0, - int b1); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp index 4d5d4ac00..6961fa0eb 100644 --- a/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp @@ -1,5 +1,6 @@ #include "../../Platform/stdafx.h" #include "../../Headers/com.mojang.nbt.h" +#include "../../Headers/net.minecraft.h" #include "../../Headers/net.minecraft.world.entity.player.h" #include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.crafting.h" @@ -8,46 +9,52 @@ #include "../Material.h" #include "FurnaceTileEntity.h" +int furnaceSlotsForUp[] = {FurnaceTileEntity::SLOT_INPUT}; +int furnaceSlotsForDown[] = {FurnaceTileEntity::SLOT_RESULT, + FurnaceTileEntity::SLOT_FUEL}; +int furnaceSlotsForSides[] = {FurnaceTileEntity::SLOT_FUEL}; + +const intArray FurnaceTileEntity::SLOTS_FOR_UP = intArray(furnaceSlotsForUp, 1); +const intArray FurnaceTileEntity::SLOTS_FOR_DOWN = + intArray(furnaceSlotsForDown, 2); +const intArray FurnaceTileEntity::SLOTS_FOR_SIDES = + intArray(furnaceSlotsForSides, 1); + const int FurnaceTileEntity::BURN_INTERVAL = 10 * 20; // 4J Stu - Need a ctor to initialise member variables FurnaceTileEntity::FurnaceTileEntity() : TileEntity() { - items = new ItemInstanceArray(3); + items = ItemInstanceArray(3); litTime = 0; - litDuration = 0; - tickCount = 0; - m_charcoalUsed = false; + name = L""; } -FurnaceTileEntity::~FurnaceTileEntity() { - delete[] items->data; - delete items; -} +FurnaceTileEntity::~FurnaceTileEntity() { delete[] items.data; } -unsigned int FurnaceTileEntity::getContainerSize() { return items->length; } +unsigned int FurnaceTileEntity::getContainerSize() { return items.length; } std::shared_ptr FurnaceTileEntity::getItem(unsigned int slot) { - return (*items)[slot]; + return items[slot]; } std::shared_ptr FurnaceTileEntity::removeItem(unsigned int slot, int count) { m_charcoalUsed = false; - if ((*items)[slot] != NULL) { - if ((*items)[slot]->count <= count) { - std::shared_ptr item = (*items)[slot]; - (*items)[slot] = nullptr; + if (items[slot] != NULL) { + if (items[slot]->count <= count) { + std::shared_ptr item = items[slot]; + items[slot] = nullptr; // 4J Stu - Fix for duplication glitch if (item->count <= 0) return nullptr; return item; } else { - std::shared_ptr i = (*items)[slot]->remove(count); - if ((*items)[slot]->count == 0) (*items)[slot] = nullptr; + std::shared_ptr i = items[slot]->remove(count); + if (items[slot]->count == 0) items[slot] = nullptr; // 4J Stu - Fix for duplication glitch if (i->count <= 0) return nullptr; return i; @@ -59,9 +66,9 @@ std::shared_ptr FurnaceTileEntity::removeItem(unsigned int slot, std::shared_ptr FurnaceTileEntity::removeItemNoUpdate(int slot) { m_charcoalUsed = false; - if (items->data[slot] != NULL) { - std::shared_ptr item = items->data[slot]; - items->data[slot] = nullptr; + if (items[slot] != NULL) { + std::shared_ptr item = items[slot]; + items[slot] = nullptr; return item; } return nullptr; @@ -69,31 +76,42 @@ std::shared_ptr FurnaceTileEntity::removeItemNoUpdate(int slot) { void FurnaceTileEntity::setItem(unsigned int slot, std::shared_ptr item) { - (*items)[slot] = item; + items[slot] = item; if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); } -int FurnaceTileEntity::getName() { return IDS_TILE_FURNACE; } +std::wstring FurnaceTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_TILE_FURNACE); +} + +std::wstring FurnaceTileEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +bool FurnaceTileEntity::hasCustomName() { return !name.empty(); } + +void FurnaceTileEntity::setCustomName(const std::wstring& name) { + this->name = name; +} void FurnaceTileEntity::load(CompoundTag* base) { TileEntity::load(base); - // 4jcraft, fixed cast of templated List to get the tag list - // and cast it to CompoundTag inside the loop - ListTag* inventoryList = base->getList(L"Items"); - - items = new ItemInstanceArray(getContainerSize()); + ListTag* inventoryList = + (ListTag*)base->getList(L"Items"); + delete[] items.data; + items = ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { - CompoundTag* tag = (CompoundTag*)inventoryList->get(i); + CompoundTag* tag = inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot"); - if (slot >= 0 && slot < items->length) - (*items)[slot] = ItemInstance::fromTag(tag); + if (slot >= 0 && slot < items.length) + items[slot] = ItemInstance::fromTag(tag); } litTime = base->getShort(L"BurnTime"); tickCount = base->getShort(L"CookTime"); - litDuration = getBurnDuration((*items)[FUEL_SLOT]); - + litDuration = getBurnDuration(items[SLOT_FUEL]); + if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); m_charcoalUsed = base->getBoolean(L"CharcoalUsed"); } @@ -103,16 +121,16 @@ void FurnaceTileEntity::save(CompoundTag* base) { base->putShort(L"CookTime", (short)(tickCount)); ListTag* listTag = new ListTag(); - for (unsigned int i = 0; i < items->length; i++) { - if ((*items)[i] != NULL) { + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL) { CompoundTag* tag = new CompoundTag(); tag->putByte(L"Slot", (uint8_t)i); - (*items)[i]->save(tag); + items[i]->save(tag); listTag->add(tag); } } base->put(L"Items", listTag); - + if (hasCustomName()) base->putString(L"CustomName", name); base->putBoolean(L"CharcoalUsed", m_charcoalUsed); } @@ -140,24 +158,24 @@ void FurnaceTileEntity::tick() { if (level != NULL && !level->isClientSide) { if (litTime == 0 && canBurn()) { - litDuration = litTime = getBurnDuration((*items)[FUEL_SLOT]); + litDuration = litTime = getBurnDuration(items[SLOT_FUEL]); if (litTime > 0) { changed = true; - if ((*items)[FUEL_SLOT] != NULL) { + if (items[SLOT_FUEL] != NULL) { // 4J Added: Keep track of whether charcoal was used in // production of current stack. - if ((*items)[FUEL_SLOT]->getItem()->id == Item::coal_Id && - (*items)[FUEL_SLOT]->getAuxValue() == + if (items[SLOT_FUEL]->getItem()->id == Item::coal_Id && + items[SLOT_FUEL]->getAuxValue() == CoalItem::CHAR_COAL) { m_charcoalUsed = true; } - (*items)[FUEL_SLOT]->count--; - if ((*items)[FUEL_SLOT]->count == 0) { - Item* remaining = (*items)[FUEL_SLOT] + items[SLOT_FUEL]->count--; + if (items[SLOT_FUEL]->count == 0) { + Item* remaining = items[SLOT_FUEL] ->getItem() ->getCraftingRemainingItem(); - (*items)[FUEL_SLOT] = + items[SLOT_FUEL] = remaining != NULL ? std::shared_ptr( new ItemInstance(remaining)) : nullptr; @@ -187,32 +205,31 @@ void FurnaceTileEntity::tick() { } bool FurnaceTileEntity::canBurn() { - if ((*items)[INPUT_SLOT] == NULL) return false; - ItemInstance* burnResult = - FurnaceRecipes::getInstance()->getResult((*items)[0]->getItem()->id); + if (items[SLOT_INPUT] == NULL) return false; + ItemInstance* burnResult = FurnaceRecipes::getInstance()->getResult( + items[SLOT_INPUT]->getItem()->id); if (burnResult == NULL) return false; - if ((*items)[RESULT_SLOT] == NULL) return true; - if (!(*items)[RESULT_SLOT]->sameItem_not_shared(burnResult)) return false; - if ((*items)[RESULT_SLOT]->count < getMaxStackSize() && - (*items)[RESULT_SLOT]->count < (*items)[RESULT_SLOT]->getMaxStackSize()) - return true; - if ((*items)[RESULT_SLOT]->count < burnResult->getMaxStackSize()) + if (items[SLOT_RESULT] == NULL) return true; + if (!items[SLOT_RESULT]->sameItem_not_shared(burnResult)) return false; + if (items[SLOT_RESULT]->count < getMaxStackSize() && + items[SLOT_RESULT]->count < items[SLOT_RESULT]->getMaxStackSize()) return true; + if (items[SLOT_RESULT]->count < burnResult->getMaxStackSize()) return true; return false; } void FurnaceTileEntity::burn() { if (!canBurn()) return; - ItemInstance* result = - FurnaceRecipes::getInstance()->getResult((*items)[0]->getItem()->id); - if ((*items)[RESULT_SLOT] == NULL) - (*items)[RESULT_SLOT] = result->copy(); - else if ((*items)[RESULT_SLOT]->id == result->id) - (*items)[RESULT_SLOT]->count++; + ItemInstance* result = FurnaceRecipes::getInstance()->getResult( + items[SLOT_INPUT]->getItem()->id); + if (items[SLOT_RESULT] == NULL) + items[SLOT_RESULT] = result->copy(); + else if (items[SLOT_RESULT]->id == result->id) + items[SLOT_RESULT]->count++; - (*items)[INPUT_SLOT]->count--; - if ((*items)[INPUT_SLOT]->count <= 0) (*items)[INPUT_SLOT] = nullptr; + items[SLOT_INPUT]->count--; + if (items[SLOT_INPUT]->count <= 0) items[SLOT_INPUT] = nullptr; } int FurnaceTileEntity::getBurnDuration( @@ -232,6 +249,10 @@ int FurnaceTileEntity::getBurnDuration( if (tile->material == Material::wood) { return BURN_INTERVAL * 3 / 2; } + + if (tile == Tile::coalBlock) { + return BURN_INTERVAL * 8 * 10; + } } if (dynamic_cast(item) && @@ -276,6 +297,37 @@ void FurnaceTileEntity::startOpen() {} void FurnaceTileEntity::stopOpen() {} +bool FurnaceTileEntity::canPlaceItem(int slot, + std::shared_ptr item) { + if (slot == SLOT_RESULT) return false; + if (slot == SLOT_FUEL) return isFuel(item); + return true; +} + +intArray FurnaceTileEntity::getSlotsForFace(int face) { + if (face == Facing::DOWN) { + return SLOTS_FOR_DOWN; + } else if (face == Facing::UP) { + return SLOTS_FOR_UP; + } else { + return SLOTS_FOR_SIDES; + } +} + +bool FurnaceTileEntity::canPlaceItemThroughFace( + int slot, std::shared_ptr item, int face) { + return canPlaceItem(slot, item); +} + +bool FurnaceTileEntity::canTakeItemThroughFace( + int slot, std::shared_ptr item, int face) { + if (face == Facing::DOWN && slot == SLOT_FUEL) { + if (item->id != Item::bucket_empty_Id) return false; + } + + return true; +} + // 4J Added std::shared_ptr FurnaceTileEntity::clone() { std::shared_ptr result = @@ -286,10 +338,10 @@ std::shared_ptr FurnaceTileEntity::clone() { result->tickCount = tickCount; result->litDuration = litDuration; - for (unsigned int i = 0; i < items->length; i++) { - if ((*items)[i] != NULL) { - (*result->items)[i] = ItemInstance::clone((*items)[i]); + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL) { + result->items[i] = ItemInstance::clone(items[i]); } } return result; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.h b/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.h index 82b875f7c..519357f07 100644 --- a/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.h @@ -2,27 +2,29 @@ #include "../FurnaceTile.h" #include "TileEntity.h" -#include "../../Containers/Container.h" +#include "../../Containers/WorldlyContainer.h" class Player; class Level; -class FurnaceTileEntity : public TileEntity, public Container { +class FurnaceTileEntity : public TileEntity, public WorldlyContainer { public: eINSTANCEOF GetType() { return eTYPE_FURNACETILEENTITY; } static TileEntity* create() { return new FurnaceTileEntity(); } using TileEntity::setChanged; -private: - static const int BURN_INTERVAL; - ItemInstanceArray* items; + static const int SLOT_INPUT = 0; + static const int SLOT_FUEL = 1; + static const int SLOT_RESULT = 2; - enum { - INPUT_SLOT = 0, - FUEL_SLOT, - RESULT_SLOT, - }; +private: + static const intArray SLOTS_FOR_UP; + static const intArray SLOTS_FOR_DOWN; + static const intArray SLOTS_FOR_SIDES; + + static const int BURN_INTERVAL; + ItemInstanceArray items; // 4J-JEV: Added for 'Renewable Energy' achievement. // Should be true iff characoal was consumed whilst cooking the current @@ -34,6 +36,9 @@ public: int litDuration; int tickCount; +private: + std::wstring name; + public: // 4J Stu - Need a ctor to initialise member variables FurnaceTileEntity(); @@ -45,7 +50,10 @@ public: int count); virtual std::shared_ptr removeItemNoUpdate(int slot); virtual void setItem(unsigned int slot, std::shared_ptr item); - virtual int getName(); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual void setCustomName(const std::wstring& name); virtual void load(CompoundTag* base); virtual void save(CompoundTag* base); virtual int getMaxStackSize(); @@ -70,6 +78,15 @@ public: void startOpen(); void stopOpen(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); + virtual intArray getSlotsForFace(int face); + virtual bool canPlaceItemThroughFace(int slot, + std::shared_ptr item, + int face); + virtual bool canTakeItemThroughFace(int slot, + std::shared_ptr item, + int face); + // 4J Added virtual std::shared_ptr clone(); diff --git a/Minecraft.World/Blocks/TileEntities/Hopper.h b/Minecraft.World/Blocks/TileEntities/Hopper.h new file mode 100644 index 000000000..0318a2d4f --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/Hopper.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../../Containers/Container.h" + +class Level; + +class Hopper : public virtual Container { +public: + virtual Level* getLevel() = 0; + virtual double getLevelX() = 0; + virtual double getLevelY() = 0; + virtual double getLevelZ() = 0; +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp new file mode 100644 index 000000000..36da69010 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp @@ -0,0 +1,435 @@ +#include "../../Platform/stdafx.h" +#include "../../Headers/net.minecraft.h" +#include "../../Headers/net.minecraft.world.entity.h" +#include "../../Headers/net.minecraft.world.entity.item.h" +#include "../../Headers/net.minecraft.world.entity.player.h" +#include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.tile.h" +#include "../../Headers/net.minecraft.world.level.tile.entity.h" +#include "../../Headers/net.minecraft.world.phys.h" +#include "../../Headers/net.minecraft.world.h" +#include "HopperTileEntity.h" + +HopperTileEntity::HopperTileEntity() { + items = ItemInstanceArray(5); + name = L""; + cooldownTime = -1; +} + +HopperTileEntity::~HopperTileEntity() { delete[] items.data; } + +void HopperTileEntity::load(CompoundTag* base) { + TileEntity::load(base); + + ListTag* inventoryList = + (ListTag*)base->getList(L"Items"); + delete[] items.data; + items = ItemInstanceArray(getContainerSize()); + if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); + cooldownTime = base->getInt(L"TransferCooldown"); + for (int i = 0; i < inventoryList->size(); i++) { + CompoundTag* tag = inventoryList->get(i); + int slot = tag->getByte(L"Slot"); + if (slot >= 0 && slot < items.length) + items[slot] = ItemInstance::fromTag(tag); + } +} + +void HopperTileEntity::save(CompoundTag* base) { + TileEntity::save(base); + ListTag* listTag = new ListTag(); + + for (int i = 0; i < items.length; i++) { + if (items[i] != NULL) { + CompoundTag* tag = new CompoundTag(); + tag->putByte(L"Slot", (uint8_t)i); + items[i]->save(tag); + listTag->add(tag); + } + } + base->put(L"Items", listTag); + base->putInt(L"TransferCooldown", cooldownTime); + if (hasCustomName()) base->putString(L"CustomName", name); +} + +void HopperTileEntity::setChanged() { TileEntity::setChanged(); } + +unsigned int HopperTileEntity::getContainerSize() { return items.length; } + +std::shared_ptr HopperTileEntity::getItem(unsigned int slot) { + return items[slot]; +} + +std::shared_ptr HopperTileEntity::removeItem(unsigned int slot, + int count) { + if (items[slot] != NULL) { + if (items[slot]->count <= count) { + std::shared_ptr item = items[slot]; + items[slot] = nullptr; + return item; + } else { + std::shared_ptr i = items[slot]->remove(count); + if (items[slot]->count == 0) items[slot] = nullptr; + return i; + } + } + return nullptr; +} + +std::shared_ptr HopperTileEntity::removeItemNoUpdate(int slot) { + if (items[slot] != NULL) { + std::shared_ptr item = items[slot]; + items[slot] = nullptr; + return item; + } + return nullptr; +} + +void HopperTileEntity::setItem(unsigned int slot, + std::shared_ptr item) { + items[slot] = item; + if (item != NULL && item->count > getMaxStackSize()) + item->count = getMaxStackSize(); +} + +std::wstring HopperTileEntity::getName() { + return hasCustomName() ? name : app.GetString(IDS_CONTAINER_HOPPER); +} + +std::wstring HopperTileEntity::getCustomName() { + return hasCustomName() ? name : L""; +} + +bool HopperTileEntity::hasCustomName() { return !name.empty(); } + +void HopperTileEntity::setCustomName(const std::wstring& name) { + this->name = name; +} + +int HopperTileEntity::getMaxStackSize() { + return Container::LARGE_MAX_STACK_SIZE; +} + +bool HopperTileEntity::stillValid(std::shared_ptr player) { + if (level->getTileEntity(x, y, z) != shared_from_this()) return false; + if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; + return true; +} + +void HopperTileEntity::startOpen() {} + +void HopperTileEntity::stopOpen() {} + +bool HopperTileEntity::canPlaceItem(int slot, + std::shared_ptr item) { + return true; +} + +void HopperTileEntity::tick() { + if (level == NULL || level->isClientSide) return; + + cooldownTime--; + + if (!isOnCooldown()) { + setCooldown(0); + tryMoveItems(); + } +} + +bool HopperTileEntity::tryMoveItems() { + if (level == NULL || level->isClientSide) return false; + + if (!isOnCooldown() && HopperTile::isTurnedOn(getData())) { + bool changed = ejectItems(); + changed = suckInItems(this) || changed; + + if (changed) { + setCooldown(MOVE_ITEM_SPEED); + setChanged(); + return true; + } + } + + return false; +} + +bool HopperTileEntity::ejectItems() { + std::shared_ptr container = getAttachedContainer(); + if (container == NULL) { + return false; + } + + for (int slot = 0; slot < getContainerSize(); slot++) { + if (getItem(slot) == NULL) continue; + + std::shared_ptr original = getItem(slot)->copy(); + std::shared_ptr result = addItem( + container.get(), removeItem(slot, 1), + Facing::OPPOSITE_FACING[HopperTile::getAttachedFace(getData())]); + + if (result == NULL || result->count == 0) { + container->setChanged(); + return true; + } else { + setItem(slot, original); + } + } + + return false; +} + +bool HopperTileEntity::suckInItems(Hopper* hopper) { + std::shared_ptr container = getSourceContainer(hopper); + + if (container != NULL) { + int face = Facing::DOWN; + + std::shared_ptr worldly = + std::dynamic_pointer_cast(container); + if ((worldly != NULL) && (face > -1)) { + intArray slots = worldly->getSlotsForFace(face); + + for (int i = 0; i < slots.length; i++) { + if (tryTakeInItemFromSlot(hopper, container.get(), slots[i], + face)) + return true; + } + } else { + int size = container->getContainerSize(); + for (int i = 0; i < size; i++) { + if (tryTakeInItemFromSlot(hopper, container.get(), i, face)) + return true; + } + } + } else { + std::shared_ptr above = + getItemAt(hopper->getLevel(), hopper->getLevelX(), + hopper->getLevelY() + 1, hopper->getLevelZ()); + + if (above != NULL) { + return addItem(hopper, above); + } + } + + return false; +} + +bool HopperTileEntity::tryTakeInItemFromSlot(Hopper* hopper, + Container* container, int slot, + int face) { + std::shared_ptr item = container->getItem(slot); + + if (item != NULL && canTakeItemFromContainer(container, item, slot, face)) { + std::shared_ptr original = item->copy(); + std::shared_ptr result = + addItem(hopper, container->removeItem(slot, 1), -1); + + if (result == NULL || result->count == 0) { + container->setChanged(); + return true; + } else { + container->setItem(slot, original); + } + } + + return false; +} + +bool HopperTileEntity::addItem(Container* container, + std::shared_ptr item) { + bool changed = false; + if (item == NULL) return false; + + std::shared_ptr copy = item->getItem()->copy(); + std::shared_ptr result = addItem(container, copy, -1); + + if (result == NULL || result->count == 0) { + changed = true; + + item->remove(); + } else { + item->setItem(result); + } + + return changed; +} + +std::shared_ptr HopperTileEntity::addItem( + Container* container, std::shared_ptr item, int face) { + if (dynamic_cast(container) != NULL && face > -1) { + WorldlyContainer* worldly = (WorldlyContainer*)container; + intArray slots = worldly->getSlotsForFace(face); + + for (int i = 0; i < slots.length && item != NULL && item->count > 0; + i++) { + item = tryMoveInItem(container, item, slots[i], face); + } + } else { + int size = container->getContainerSize(); + for (int i = 0; i < size && item != NULL && item->count > 0; i++) { + item = tryMoveInItem(container, item, i, face); + } + } + + if (item != NULL && item->count == 0) { + item = nullptr; + } + + return item; +} + +bool HopperTileEntity::canPlaceItemInContainer( + Container* container, std::shared_ptr item, int slot, + int face) { + if (!container->canPlaceItem(slot, item)) return false; + if (dynamic_cast(container) != NULL && + !dynamic_cast(container)->canPlaceItemThroughFace( + slot, item, face)) + return false; + return true; +} + +bool HopperTileEntity::canTakeItemFromContainer( + Container* container, std::shared_ptr item, int slot, + int face) { + if (dynamic_cast(container) != NULL && + !dynamic_cast(container)->canTakeItemThroughFace( + slot, item, face)) + return false; + return true; +} + +std::shared_ptr HopperTileEntity::tryMoveInItem( + Container* container, std::shared_ptr item, int slot, + int face) { + std::shared_ptr current = container->getItem(slot); + + if (canPlaceItemInContainer(container, item, slot, face)) { + bool success = false; + if (current == NULL) { + container->setItem(slot, item); + item = nullptr; + success = true; + } else if (canMergeItems(current, item)) { + int space = item->getMaxStackSize() - current->count; + int count = std::min(item->count, space); + + item->count -= count; + current->count += count; + success = count > 0; + } + if (success) { + HopperTileEntity* hopper = + dynamic_cast(container); + if (hopper != NULL) { + hopper->setCooldown(MOVE_ITEM_SPEED); + container->setChanged(); + } + container->setChanged(); + } + } + return item; +} + +std::shared_ptr HopperTileEntity::getAttachedContainer() { + int face = HopperTile::getAttachedFace(getData()); + return getContainerAt(getLevel(), x + Facing::STEP_X[face], + y + Facing::STEP_Y[face], z + Facing::STEP_Z[face]); +} + +std::shared_ptr HopperTileEntity::getSourceContainer( + Hopper* hopper) { + return getContainerAt(hopper->getLevel(), hopper->getLevelX(), + hopper->getLevelY() + 1, hopper->getLevelZ()); +} + +std::shared_ptr HopperTileEntity::getItemAt(Level* level, double xt, + double yt, double zt) { + std::vector >* entities = level->getEntitiesOfClass( + typeid(ItemEntity), AABB::newTemp(xt, yt, zt, xt + 1, yt + 1, zt + 1), + EntitySelector::ENTITY_STILL_ALIVE); + + if (entities->size() > 0) { + std::shared_ptr out = + std::dynamic_pointer_cast(entities->at(0)); + delete entities; + return out; + } else { + delete entities; + return nullptr; + } +} + +std::shared_ptr HopperTileEntity::getContainerAt(Level* level, + double x, double y, + double z) { + std::shared_ptr result = nullptr; + + int xt = Mth::floor(x); + int yt = Mth::floor(y); + int zt = Mth::floor(z); + + std::shared_ptr entity = level->getTileEntity(xt, yt, zt); + + result = std::dynamic_pointer_cast(entity); + if (result != NULL) { + if (std::dynamic_pointer_cast(result) != NULL) { + int id = level->getTile(xt, yt, zt); + Tile* tile = Tile::tiles[id]; + + if (dynamic_cast(tile) != NULL) { + result = ((ChestTile*)tile)->getContainer(level, xt, yt, zt); + } + } + } + + if (result == NULL) { + std::vector >* entities = level->getEntities( + nullptr, AABB::newTemp(x, y, z, x + 1, y + 1, z + 1), + EntitySelector::CONTAINER_ENTITY_SELECTOR); + + if ((entities != NULL) && (entities->size() > 0)) { + result = std::dynamic_pointer_cast( + entities->at(level->random->nextInt(entities->size()))); + } + } + + return result; +} + +bool HopperTileEntity::canMergeItems(std::shared_ptr a, + std::shared_ptr b) { + if (a->id != b->id) return false; + if (a->getAuxValue() != b->getAuxValue()) return false; + if (a->count > a->getMaxStackSize()) return false; + if (!ItemInstance::tagMatches(a, b)) return false; + return true; +} + +Level* HopperTileEntity::getLevel() { return TileEntity::getLevel(); } + +double HopperTileEntity::getLevelX() { return x; } + +double HopperTileEntity::getLevelY() { return y; } + +double HopperTileEntity::getLevelZ() { return z; } + +void HopperTileEntity::setCooldown(int time) { cooldownTime = time; } + +bool HopperTileEntity::isOnCooldown() { return cooldownTime > 0; } + +// 4J Added +std::shared_ptr HopperTileEntity::clone() { + std::shared_ptr result = + std::shared_ptr(new HopperTileEntity()); + TileEntity::clone(result); + + result->name = name; + result->cooldownTime = cooldownTime; + for (unsigned int i = 0; i < items.length; i++) { + if (items[i] != NULL) { + result->items[i] = ItemInstance::clone(items[i]); + } + } + return result; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/HopperTileEntity.h b/Minecraft.World/Blocks/TileEntities/HopperTileEntity.h new file mode 100644 index 000000000..c1dc92c88 --- /dev/null +++ b/Minecraft.World/Blocks/TileEntities/HopperTileEntity.h @@ -0,0 +1,91 @@ +#pragma once + +#include "TileEntity.h" +#include "Hopper.h" + +class HopperTileEntity : public TileEntity, public Hopper { +public: + eINSTANCEOF GetType() { return eTYPE_HOPPERTILEENTITY; } + static TileEntity* create() { return new HopperTileEntity(); } + // 4J Added + virtual std::shared_ptr clone(); + +public: + static const int MOVE_ITEM_SPEED = 8; + +private: + ItemInstanceArray items; + std::wstring name; + int cooldownTime; + +public: + HopperTileEntity(); + ~HopperTileEntity(); + + virtual void load(CompoundTag* base); + virtual void save(CompoundTag* base); + virtual void setChanged(); + virtual unsigned int getContainerSize(); + virtual std::shared_ptr getItem(unsigned int slot); + virtual std::shared_ptr removeItem(unsigned int slot, + int count); + virtual std::shared_ptr removeItemNoUpdate(int slot); + virtual void setItem(unsigned int slot, std::shared_ptr item); + virtual std::wstring getName(); + virtual std::wstring getCustomName(); + virtual bool hasCustomName(); + virtual void setCustomName(const std::wstring& name); + virtual int getMaxStackSize(); + virtual bool stillValid(std::shared_ptr player); + virtual void startOpen(); + virtual void stopOpen(); + virtual bool canPlaceItem(int slot, std::shared_ptr item); + virtual void tick(); + virtual bool tryMoveItems(); + +private: + virtual bool ejectItems(); + +public: + static bool suckInItems(Hopper* hopper); + +private: + static bool tryTakeInItemFromSlot(Hopper* hopper, Container* container, + int slot, int face); + +public: + static bool addItem(Container* container, std::shared_ptr item); + static std::shared_ptr addItem( + Container* container, std::shared_ptr item, int face); + +private: + static bool canPlaceItemInContainer(Container* container, + std::shared_ptr item, + int slot, int face); + static bool canTakeItemFromContainer(Container* container, + std::shared_ptr item, + int slot, int face); + static std::shared_ptr tryMoveInItem( + Container* container, std::shared_ptr item, int slot, + int face); + virtual std::shared_ptr getAttachedContainer(); + +public: + static std::shared_ptr getSourceContainer(Hopper* hopper); + static std::shared_ptr getItemAt(Level* level, double xt, + double yt, double zt); + static std::shared_ptr getContainerAt(Level* level, double x, + double y, double z); + +private: + static bool canMergeItems(std::shared_ptr a, + std::shared_ptr b); + +public: + virtual Level* getLevel(); + virtual double getLevelX(); + virtual double getLevelY(); + virtual double getLevelZ(); + virtual void setCooldown(int time); + virtual bool isOnCooldown(); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.cpp index 14c326749..0cc85500d 100644 --- a/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.cpp @@ -1,214 +1,81 @@ #include "../../Platform/stdafx.h" -#include "../../Headers/com.mojang.nbt.h" -#include "TileEntity.h" -#include "../../Level/Events/LevelEvent.h" -#include "../../Headers/net.minecraft.world.level.h" -#include "../../Headers/net.minecraft.world.entity.item.h" -#include "../../Headers/net.minecraft.world.entity.player.h" -#include "../../Headers/net.minecraft.world.item.h" -#include "../../Headers/net.minecraft.world.entity.h" -#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.network.packet.h" -#include "../../Util/SharedConstants.h" +#include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.tile.h" #include "MobSpawnerTileEntity.h" -const int MobSpawnerTileEntity::MAX_DIST = 16; - -MobSpawnerTileEntity::MobSpawnerTileEntity() : TileEntity() { - spin = 0; - oSpin = 0; - - // entityId = "Skeleton"; - entityId = L"Pig"; - m_bEntityIdUpdated = false; - - spawnData = NULL; - - spawnDelay = 20; - - minSpawnDelay = SharedConstants::TICKS_PER_SECOND * 10; - maxSpawnDelay = SharedConstants::TICKS_PER_SECOND * 40; - spawnCount = 4; - displayEntity = nullptr; +MobSpawnerTileEntity::TileEntityMobSpawner::TileEntityMobSpawner( + MobSpawnerTileEntity* parent) { + m_parent = parent; } -std::wstring MobSpawnerTileEntity::getEntityId() { return entityId; } - -void MobSpawnerTileEntity::setEntityId(const std::wstring& entityId) { - this->entityId = entityId; +void MobSpawnerTileEntity::TileEntityMobSpawner::broadcastEvent(int id) { + m_parent->level->tileEvent(m_parent->x, m_parent->y, m_parent->z, + Tile::mobSpawner_Id, id, 0); } -bool MobSpawnerTileEntity::isNearPlayer() { - return level->getNearestPlayer(x + 0.5, y + 0.5, z + 0.5, MAX_DIST) != NULL; +Level* MobSpawnerTileEntity::TileEntityMobSpawner::getLevel() { + return m_parent->level; } -void MobSpawnerTileEntity::tick() { - if (!isNearPlayer()) { - return; - } +int MobSpawnerTileEntity::TileEntityMobSpawner::getX() { return m_parent->x; } - if (level->isClientSide) { - double xP = x + level->random->nextFloat(); - double yP = y + level->random->nextFloat(); - double zP = z + level->random->nextFloat(); - level->addParticle(eParticleType_smoke, xP, yP, zP, 0, 0, 0); - level->addParticle(eParticleType_flame, xP, yP, zP, 0, 0, 0); +int MobSpawnerTileEntity::TileEntityMobSpawner::getY() { return m_parent->y; } - oSpin = spin; - spin += 1000 / 220.0f; - while (spin > 360) { - spin -= 360; - } - while (oSpin > 360) { - oSpin -= 360; - } - } else { - if (spawnDelay == -1) delay(); +int MobSpawnerTileEntity::TileEntityMobSpawner::getZ() { return m_parent->z; } - if (spawnDelay > 0) { - spawnDelay--; - return; - } - - for (int c = 0; c < spawnCount; c++) { - std::shared_ptr entity = std::dynamic_pointer_cast( - EntityIO::newEntity(entityId, level)); - if (entity == NULL) return; - - Mob* entityPtr = entity.get(); - std::vector >* vecNearby = - level->getEntitiesOfClass( - typeid(*entityPtr), - AABB::newTemp(x, y, z, x + 1, y + 1, z + 1)->grow(8, 4, 8)); - int nearBy = - (int)vecNearby - ->size(); // 4J - IB, TODO, Mob contains no getClass - delete vecNearby; - - if (nearBy >= 6) { - delay(); - return; - } - - // 4J added - our mobspawner tiles should only be spawning monsters. - // Also respect the global limits we have for those so we don't go - // creating silly numbers of them. Have set this limit slightly - // higher than the main spawner has so that this tile entity is more - // likely to actually make something (60 rather than 50) - if (level->countInstanceOf(eTYPE_MONSTER, false) >= 60) { - return; - } - - if (entity != NULL) { - double xp = x + (level->random->nextDouble() - - level->random->nextDouble()) * - 4; - double yp = y + level->random->nextInt(3) - 1; - double zp = z + (level->random->nextDouble() - - level->random->nextDouble()) * - 4; - std::shared_ptr mob = - std::dynamic_pointer_cast(entity); - - entity->moveTo(xp, yp, zp, level->random->nextFloat() * 360, 0); - - if (mob == NULL || mob->canSpawn()) { - fillExtraData(entity); - - level->addEntity(entity); - - level->levelEvent(LevelEvent::PARTICLES_MOBTILE_SPAWN, x, y, - z, 0); - - if (mob != NULL) mob->spawnAnim(); - delay(); - } - } - } - } - - TileEntity::tick(); +void MobSpawnerTileEntity::TileEntityMobSpawner::setNextSpawnData( + BaseMobSpawner::SpawnData* nextSpawnData) { + BaseMobSpawner::setNextSpawnData(nextSpawnData); + if (getLevel() != NULL) + getLevel()->sendTileUpdated(m_parent->x, m_parent->y, m_parent->z); } -void MobSpawnerTileEntity::fillExtraData(std::shared_ptr entity) { - if (spawnData != NULL) { - CompoundTag* data = new CompoundTag(); - entity->save(data); - - std::vector* allTags = spawnData->getAllTags(); - for (AUTO_VAR(it, allTags->begin()); it != allTags->end(); ++it) { - Tag* tag = *it; - data->put((wchar_t*)tag->getName().c_str(), tag->copy()); - } - if (allTags != NULL) delete allTags; - - entity->load(data); - } +MobSpawnerTileEntity::MobSpawnerTileEntity() { + spawner = new TileEntityMobSpawner(this); } -void MobSpawnerTileEntity::delay() { - spawnDelay = - minSpawnDelay + level->random->nextInt(maxSpawnDelay - minSpawnDelay); -} +MobSpawnerTileEntity::~MobSpawnerTileEntity() { delete spawner; } void MobSpawnerTileEntity::load(CompoundTag* tag) { TileEntity::load(tag); - entityId = tag->getString(L"EntityId"); - m_bEntityIdUpdated = true; - - spawnDelay = tag->getShort(L"Delay"); - - if (tag->contains(L"SpawnData")) { - spawnData = tag->getCompound(L"SpawnData"); - } else { - spawnData = NULL; - } - - if (tag->contains(L"MinSpawnDelay")) { - minSpawnDelay = tag->getShort(L"MinSpawnDelay"); - maxSpawnDelay = tag->getShort(L"MaxSpawnDelay"); - spawnCount = tag->getShort(L"SpawnCount"); - } + spawner->load(tag); } void MobSpawnerTileEntity::save(CompoundTag* tag) { TileEntity::save(tag); - tag->putString(L"EntityId", entityId); - tag->putShort(L"Delay", (short)spawnDelay); - tag->putShort(L"MinSpawnDelay", (short)minSpawnDelay); - tag->putShort(L"MaxSpawnDelay", (short)maxSpawnDelay); - tag->putShort(L"SpawnCount", (short)spawnCount); - - if (spawnData != NULL) { - tag->putCompound(L"SpawnData", spawnData); - } + spawner->save(tag); } -std::shared_ptr MobSpawnerTileEntity::getDisplayEntity() { - if (displayEntity == NULL || m_bEntityIdUpdated) { - std::shared_ptr e = EntityIO::newEntity(getEntityId(), NULL); - fillExtraData(e); - displayEntity = e; - m_bEntityIdUpdated = false; - } - - return displayEntity; +void MobSpawnerTileEntity::tick() { + spawner->tick(); + TileEntity::tick(); } std::shared_ptr MobSpawnerTileEntity::getUpdatePacket() { CompoundTag* tag = new CompoundTag(); save(tag); + tag->remove(L"SpawnPotentials"); return std::shared_ptr(new TileEntityDataPacket( x, y, z, TileEntityDataPacket::TYPE_MOB_SPAWNER, tag)); } +bool MobSpawnerTileEntity::triggerEvent(int b0, int b1) { + if (spawner->onEventTriggered(b0)) return true; + return TileEntity::triggerEvent(b0, b1); +} + +BaseMobSpawner* MobSpawnerTileEntity::getSpawner() { return spawner; } + // 4J Added std::shared_ptr MobSpawnerTileEntity::clone() { std::shared_ptr result = std::shared_ptr(new MobSpawnerTileEntity()); TileEntity::clone(result); - result->entityId = entityId; - result->spawnDelay = spawnDelay; return result; } + +void MobSpawnerTileEntity::setEntityId(const std::wstring& id) { + spawner->setEntityId(id); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.h b/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.h index c3315f3a3..0847c1a3a 100644 --- a/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/MobSpawnerTileEntity.h @@ -1,6 +1,7 @@ #pragma once #include "TileEntity.h" +#include "../../Level/BaseMobSpawner.h" class Packet; class Entity; @@ -10,48 +11,36 @@ public: eINSTANCEOF GetType() { return eTYPE_MOBSPAWNERTILEENTITY; } static TileEntity* create() { return new MobSpawnerTileEntity(); } - using TileEntity::setChanged; - private: - static const int MAX_DIST; + class TileEntityMobSpawner : public BaseMobSpawner { + private: + MobSpawnerTileEntity* m_parent; -public: - int spawnDelay; + public: + TileEntityMobSpawner(MobSpawnerTileEntity* parent); -private: - std::wstring entityId; - CompoundTag* spawnData; + void broadcastEvent(int id); + Level* getLevel(); + int getX(); + int getY(); + int getZ(); + void setNextSpawnData(BaseMobSpawner::SpawnData* nextSpawnData); + }; - bool m_bEntityIdUpdated; // 4J Added - -public: - double spin, oSpin; - -private: - int minSpawnDelay; - int maxSpawnDelay; - int spawnCount; - std::shared_ptr displayEntity; + BaseMobSpawner* spawner; public: MobSpawnerTileEntity(); + ~MobSpawnerTileEntity(); - std::wstring getEntityId(); - void setEntityId(const std::wstring& entityId); - bool isNearPlayer(); - virtual void tick(); - void fillExtraData(std::shared_ptr entity); - -private: - void delay(); - -public: virtual void load(CompoundTag* tag); virtual void save(CompoundTag* tag); - - std::shared_ptr getDisplayEntity(); + virtual void tick(); virtual std::shared_ptr getUpdatePacket(); + virtual bool triggerEvent(int b0, int b1); + virtual BaseMobSpawner* getSpawner(); // 4J Added virtual std::shared_ptr clone(); + void setEntityId(const std::wstring& id); }; diff --git a/Minecraft.World/Blocks/TileEntities/MusicTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/MusicTileEntity.cpp index 4ff1f847f..c5fa02784 100644 --- a/Minecraft.World/Blocks/TileEntities/MusicTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/MusicTileEntity.cpp @@ -42,7 +42,7 @@ void MusicTileEntity::playNote(Level* level, int x, int y, int z) { if (m == Material::glass) i = 3; if (m == Material::wood) i = 4; - level->tileEvent(x, y, z, Tile::musicBlock_Id, i, note); + level->tileEvent(x, y, z, Tile::noteblock_Id, i, note); } // 4J Added diff --git a/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp index b5b6b656d..fb49032ca 100644 --- a/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp @@ -107,8 +107,10 @@ void PistonPieceEntity::finalTick() { progressO = progress = 1; level->removeTileEntity(x, y, z); setRemoved(); - if (level->getTile(x, y, z) == Tile::pistonMovingPiece_Id) - level->setTileAndData(x, y, z, id, data); + if (level->getTile(x, y, z) == Tile::pistonMovingPiece_Id) { + level->setTileAndData(x, y, z, id, data, Tile::UPDATE_ALL); + level->neighborChanged(x, y, z, id); + } } } @@ -119,8 +121,10 @@ void PistonPieceEntity::tick() { moveCollidedEntities(1, 4 / 16.f); level->removeTileEntity(x, y, z); setRemoved(); - if (level->getTile(x, y, z) == Tile::pistonMovingPiece_Id) - level->setTileAndData(x, y, z, id, data); + if (level->getTile(x, y, z) == Tile::pistonMovingPiece_Id) { + level->setTileAndData(x, y, z, id, data, Tile::UPDATE_ALL); + level->neighborChanged(x, y, z, id); + } return; } diff --git a/Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp b/Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp index 19b936d26..b27268452 100644 --- a/Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp +++ b/Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp @@ -69,7 +69,7 @@ const std::wstring PotionBrewing::MOD_GLOWSTONE = // with water bottle and gunpowder const std::wstring PotionBrewing::MOD_GUNPOWDER = L"+14"; //&13-13"; // gunpowder makes them throwable! // gunpowder requires - //13 and sets 14 + // 13 and sets 14 #else const std::wstring PotionBrewing::MOD_WATER = L"-1-3-5-7-9-11-13"; const std::wstring PotionBrewing::MOD_SUGAR = L"+0"; @@ -225,6 +225,16 @@ int PotionBrewing::getColorValue(std::vector* effects) { return ((int)red) << 16 | ((int)green) << 8 | ((int)blue); } +bool PotionBrewing::areAllEffectsAmbient( + std::vector* effects) { + for (AUTO_VAR(it, effects->begin()); it != effects->end(); ++it) { + MobEffectInstance* effect = *it; + if (!effect->isAmbient()) return false; + } + + return true; +} + int PotionBrewing::getColorValue(int brew, bool includeDisabledEffects) { if (!includeDisabledEffects) { AUTO_VAR(colIt, cachedColors.find(brew)); @@ -517,8 +527,7 @@ std::vector* PotionBrewing::getEffects( (effect->isDisabled() && !includeDisabledEffects)) { continue; } - // std::wstring durationString = - // potionEffectDuration.get(effect->getId()); + // wstring durationString = potionEffectDuration.get(effect->getId()); AUTO_VAR(effIt, potionEffectDuration.find(effect->getId())); if (effIt == potionEffectDuration.end()) { continue; @@ -557,8 +566,10 @@ std::vector* PotionBrewing::getEffects( if (list == NULL) { list = new std::vector(); } - list->push_back( - new MobEffectInstance(effect->getId(), duration, amplifier)); + MobEffectInstance* instance = + new MobEffectInstance(effect->getId(), duration, amplifier); + if ((brew & THROWABLE_MASK) != 0) instance->setSplash(true); + list->push_back(instance); } } @@ -747,29 +758,29 @@ int PotionBrewing::valueOf(int brew, int p1, int p2, int p3, int p4, int p5) { } std::wstring PotionBrewing::toString(int brew) { - std::wstring string; + std::wstring std::string; int bit = NUM_BITS - 1; while (bit >= 0) { if ((brew & (1 << bit)) != 0) { - string.append(L"O"); + std::string.append(L"O"); } else { - string.append(L"x"); + std::string.append(L"x"); } bit--; } - return string; + return std::string; } // void main(String[] args) //{ // HashMap existingCombinations = new HashMap(); HashMap distinctCombinations = new -//HashMap(); int noEffects = 0; for (int brew = 0; brew <= -//BREW_MASK; brew++) { List effects = -//PotionBrewing.getEffects(brew, true); if (effects != null) { +// Integer>(); HashMap distinctCombinations = new +// HashMap(); int noEffects = 0; for (int brew = 0; brew +// <= BREW_MASK; brew++) { List effects = +// PotionBrewing.getEffects(brew, true); if (effects != null) { // { // StringBuilder builder = new StringBuilder(); @@ -779,8 +790,9 @@ std::wstring PotionBrewing::toString(int brew) { // } // String string = builder.toString(); // Integer count = -//existingCombinations.get(string); if (count != null) { count++; } else { count -//= 1; +// existingCombinations.get(string); if (count != +// null) { count++; +// } else { count = 1; // } // existingCombinations.put(string, count); // } @@ -792,8 +804,9 @@ std::wstring PotionBrewing::toString(int brew) { // } // String string = builder.toString(); // Integer count = -//distinctCombinations.get(string); if (count != null) { count++; } else { count -//= 1; +// distinctCombinations.get(string); if (count != +// null) { count++; +// } else { count = 1; // } // distinctCombinations.put(string, count); // } @@ -810,7 +823,7 @@ std::wstring PotionBrewing::toString(int brew) { // } // System.out.println("Combination with no effects: " + noEffects + " (" + -//((double) noEffects / BREW_MASK * 100.0) + " %)"); System.out.println("Unique -//combinations: " + existingCombinations.size()); System.out.println("Distinct -//combinations: " + distinctCombinations.size()); +//((double) noEffects / BREW_MASK * 100.0) + " %)"); +// System.out.println("Unique combinations: " + existingCombinations.size()); +// System.out.println("Distinct combinations: " + distinctCombinations.size()); //} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/PotionBrewing.h b/Minecraft.World/Blocks/TileEntities/PotionBrewing.h index 04703b822..50e02698c 100644 --- a/Minecraft.World/Blocks/TileEntities/PotionBrewing.h +++ b/Minecraft.World/Blocks/TileEntities/PotionBrewing.h @@ -4,6 +4,14 @@ class MobEffectInstance; class PotionBrewing { public: + static const int POTION_ID_SPLASH_DAMAGE = 32732; + static const int POTION_ID_SPLASH_WEAKNESS = 32696; + static const int POTION_ID_SPLASH_SLOWNESS = 32698; + static const int POTION_ID_SPLASH_POISON = 32660; + static const int POTION_ID_HEAL = 16341; + static const int POTION_ID_SWIFTNESS = 16274; + static const int POTION_ID_FIRE_RESISTANCE = 16307; + static const bool SIMPLIFIED_BREWING = true; // 4J Stu - Made #define so we can use it to select const initialisation #define _SIMPLIFIED_BREWING 1 @@ -27,6 +35,12 @@ public: static const std::wstring MOD_GUNPOWDER; static const std::wstring MOD_GOLDENCARROT; + static const int BITS_FOR_MAX_NORMAL_EFFECT = 0xF; + static const int BITS_FOR_DURATION = (1 << 5); + static const int BITS_FOR_EXTENDED = (1 << 6); + static const int BITS_FOR_NORMAL = (1 << 13); + static const int BITS_FOR_SPLASH = (1 << 14); + private: typedef std::unordered_map intStringMap; static intStringMap potionEffectDuration; @@ -55,6 +69,7 @@ private: public: static int getAppearanceValue(int brew); static int getColorValue(std::vector* effects); + static bool areAllEffectsAmbient(std::vector* effects); private: static std::unordered_map cachedColors; diff --git a/Minecraft.World/Blocks/TileEntities/SignTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/SignTileEntity.cpp index c98fa03d4..26988d536 100644 --- a/Minecraft.World/Blocks/TileEntities/SignTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/SignTileEntity.cpp @@ -27,14 +27,15 @@ SignTileEntity::SignTileEntity() : TileEntity() { m_iSelectedLine = -1; _isEditable = true; + + playerWhoMayEdit = nullptr; } SignTileEntity::~SignTileEntity() { // TODO ORBIS_STUBBED; #ifndef __ORBIS__ // 4J-PB - we don't need to verify strings anymore - - // InputManager.CancelQueuedVerifyStrings(&SignTileEntity::StringVerifyCallback, - // this); + // InputManager.CancelQueuedVerifyStrings(&SignTileEntity::StringVerifyCallback,(LPVOID)this); #endif } @@ -91,6 +92,17 @@ bool SignTileEntity::isEditable() { return _isEditable; } void SignTileEntity::setEditable(bool isEditable) { this->_isEditable = isEditable; + if (!isEditable) { + playerWhoMayEdit = nullptr; + } +} + +void SignTileEntity::setAllowedPlayerEditor(std::shared_ptr player) { + playerWhoMayEdit = player; +} + +std::shared_ptr SignTileEntity::getPlayerWhoMayEdit() { + return playerWhoMayEdit; } void SignTileEntity::setChanged() { @@ -115,8 +127,7 @@ void SignTileEntity::setChanged() { // at this point, we can ask the online string verifier if our sign text is ok #ifdef __ORBIS__ m_bVerified=true; #else - if(!InputManager.VerifyStrings((WCHAR**)&wcMessages,MAX_SIGN_LINES,&SignTileEntity::StringVerifyCallback, -this)) + if(!InputManager.VerifyStrings((WCHAR**)&wcMessages,MAX_SIGN_LINES,&SignTileEntity::StringVerifyCallback,(LPVOID)this)) { // Nothing to verify m_bVerified=true; @@ -178,4 +189,4 @@ std::shared_ptr SignTileEntity::clone() { result->m_bVerified = m_bVerified; result->m_bCensored = m_bCensored; return result; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/SignTileEntity.h b/Minecraft.World/Blocks/TileEntities/SignTileEntity.h index 822770260..38eeb1903 100644 --- a/Minecraft.World/Blocks/TileEntities/SignTileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/SignTileEntity.h @@ -27,6 +27,7 @@ public: public: private: + std::shared_ptr playerWhoMayEdit; bool _isEditable; bool m_bVerified; bool m_bCensored; @@ -40,10 +41,12 @@ public: virtual std::shared_ptr getUpdatePacket(); bool isEditable(); void setEditable(bool isEditable); + void setAllowedPlayerEditor(std::shared_ptr player); + std::shared_ptr getPlayerWhoMayEdit(); virtual void setChanged(); static int StringVerifyCallback(void* lpParam, STRING_VERIFY_RESPONSE* pResults); // 4J Added virtual std::shared_ptr clone(); -}; +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/SkullTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/SkullTileEntity.cpp index 9a481564e..d555b88d8 100644 --- a/Minecraft.World/Blocks/TileEntities/SkullTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/SkullTileEntity.cpp @@ -53,4 +53,4 @@ std::shared_ptr SkullTileEntity::clone() { result->rotation = rotation; result->extraType = extraType; return result; -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TileEntities/TileEntity.cpp b/Minecraft.World/Blocks/TileEntities/TileEntity.cpp index a6a1604fd..24986046f 100644 --- a/Minecraft.World/Blocks/TileEntities/TileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/TileEntity.cpp @@ -18,10 +18,12 @@ void TileEntity::staticCtor() { TileEntity::setId(ChestTileEntity::create, eTYPE_CHESTTILEENTITY, L"Chest"); TileEntity::setId(EnderChestTileEntity::create, eTYPE_ENDERCHESTTILEENTITY, L"EnderChest"); - TileEntity::setId(RecordPlayerTile::Entity::create, eTYPE_RECORDPLAYERTILE, + TileEntity::setId(JukeboxTile::Entity::create, eTYPE_RECORDPLAYERTILE, L"RecordPlayer"); TileEntity::setId(DispenserTileEntity::create, eTYPE_DISPENSERTILEENTITY, L"Trap"); + TileEntity::setId(DropperTileEntity::create, eTYPE_DROPPERTILEENTITY, + L"Dropper"); TileEntity::setId(SignTileEntity::create, eTYPE_SIGNTILEENTITY, L"Sign"); TileEntity::setId(MobSpawnerTileEntity::create, eTYPE_MOBSPAWNERTILEENTITY, L"MobSpawner"); @@ -34,7 +36,17 @@ void TileEntity::staticCtor() { eTYPE_ENCHANTMENTTABLEENTITY, L"EnchantTable"); TileEntity::setId(TheEndPortalTileEntity::create, eTYPE_THEENDPORTALTILEENTITY, L"Airportal"); + TileEntity::setId(CommandBlockEntity::create, eTYPE_COMMANDBLOCKTILEENTITY, + L"Control"); + TileEntity::setId(BeaconTileEntity::create, eTYPE_BEACONTILEENTITY, + L"Beacon"); TileEntity::setId(SkullTileEntity::create, eTYPE_SKULLTILEENTITY, L"Skull"); + TileEntity::setId(DaylightDetectorTileEntity::create, + eTYPE_DAYLIGHTDETECTORTILEENTITY, L"DLDetector"); + TileEntity::setId(HopperTileEntity::create, eTYPE_HOPPERTILEENTITY, + L"Hopper"); + TileEntity::setId(ComparatorTileEntity::create, eTYPE_COMPARATORTILEENTITY, + L"Comparator"); } void TileEntity::setId(tileEntityCreateFn createFn, eINSTANCEOF clas, @@ -117,15 +129,17 @@ int TileEntity::getData() { return data; } -void TileEntity::setData(int data) { +void TileEntity::setData(int data, int updateFlags) { this->data = data; - level->setData(x, y, z, data); + level->setData(x, y, z, data, updateFlags); } void TileEntity::setChanged() { if (level != NULL) { data = level->getData(x, y, z); level->tileEntityChanged(x, y, z, shared_from_this()); + if (getTile() != NULL) + level->updateNeighbourForOutputSignal(x, y, z, getTile()->id); } } @@ -137,6 +151,8 @@ double TileEntity::distanceToSqr(double xPlayer, double yPlayer, return xd * xd + yd * yd + zd * zd; } +double TileEntity::getViewDistance() { return 64 * 64; } + Tile* TileEntity::getTile() { if (tile == NULL) tile = Tile::tiles[level->getTile(x, y, z)]; return tile; @@ -149,7 +165,8 @@ bool TileEntity::isRemoved() { return remove; } void TileEntity::setRemoved() { remove = true; } void TileEntity::clearRemoved() { remove = false; } -void TileEntity::triggerEvent(int b0, int b1) {} + +bool TileEntity::triggerEvent(int b0, int b1) { return false; } void TileEntity::clearCache() { tile = NULL; diff --git a/Minecraft.World/Blocks/TileEntities/TileEntity.h b/Minecraft.World/Blocks/TileEntities/TileEntity.h index ffc49ee65..e640ae2e4 100644 --- a/Minecraft.World/Blocks/TileEntities/TileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/TileEntity.h @@ -51,23 +51,25 @@ public: void upgradeRenderRemoveStage(); // 4J added bool shouldRemoveForRender(); // 4J added - Level* getLevel(); - void setLevel(Level* level); - bool hasLevel(); + virtual Level* getLevel(); + virtual void setLevel(Level* level); + virtual bool hasLevel(); virtual void load(CompoundTag* tag); virtual void save(CompoundTag* tag); virtual void tick(); static std::shared_ptr loadStatic(CompoundTag* tag); - int getData(); - void setData(int data); - void setChanged(); - double distanceToSqr(double xPlayer, double yPlayer, double zPlayer); - Tile* getTile(); + virtual int getData(); + virtual void setData(int data, int updateFlags); + virtual void setChanged(); + virtual double distanceToSqr(double xPlayer, double yPlayer, + double zPlayer); + virtual double getViewDistance(); + virtual Tile* getTile(); virtual std::shared_ptr getUpdatePacket(); virtual bool isRemoved(); virtual void setRemoved(); virtual void clearRemoved(); - virtual void triggerEvent(int b0, int b1); + virtual bool triggerEvent(int b0, int b1); virtual void clearCache(); // 4J Added @@ -75,4 +77,4 @@ public: protected: void clone(std::shared_ptr tileEntity); -}; +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TntTile.cpp b/Minecraft.World/Blocks/TntTile.cpp index 504ea9069..cbcba160b 100644 --- a/Minecraft.World/Blocks/TntTile.cpp +++ b/Minecraft.World/Blocks/TntTile.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.entity.item.h" +#include "../Headers/net.minecraft.world.entity.projectile.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.h" @@ -24,23 +25,22 @@ void TntTile::onPlace(Level* level, int x, int y, int z) { if (level->hasNeighborSignal(x, y, z) && app.GetGameHostOption(eGameHostOption_TNT)) { destroy(level, x, y, z, EXPLODE_BIT); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } void TntTile::neighborChanged(Level* level, int x, int y, int z, int type) { - if (type > 0 && Tile::tiles[type]->isSignalSource()) { - if (level->hasNeighborSignal(x, y, z) && - app.GetGameHostOption(eGameHostOption_TNT)) { - destroy(level, x, y, z, EXPLODE_BIT); - level->setTile(x, y, z, 0); - } + if (level->hasNeighborSignal(x, y, z) && + app.GetGameHostOption(eGameHostOption_TNT)) { + destroy(level, x, y, z, EXPLODE_BIT); + level->removeTile(x, y, z); } } int TntTile::getResourceCount(Random* random) { return 1; } -void TntTile::wasExploded(Level* level, int x, int y, int z) { +void TntTile::wasExploded(Level* level, int x, int y, int z, + Explosion* explosion) { // 4J - added - don't every create on the client, I think this must be the // cause of a bug reported in the java version where white tnts are created // in the network game @@ -53,7 +53,8 @@ void TntTile::wasExploded(Level* level, int x, int y, int z) { if (level->newPrimedTntAllowed() && app.GetGameHostOption(eGameHostOption_TNT)) { std::shared_ptr primed = std::shared_ptr( - new PrimedTnt(level, x + 0.5f, y + 0.5f, z + 0.5f)); + new PrimedTnt(level, x + 0.5f, y + 0.5f, z + 0.5f, + explosion->getSourceMob())); primed->life = level->random->nextInt(primed->life / 4) + primed->life / 8; level->addEntity(primed); @@ -61,6 +62,11 @@ void TntTile::wasExploded(Level* level, int x, int y, int z) { } void TntTile::destroy(Level* level, int x, int y, int z, int data) { + destroy(level, x, y, z, data, nullptr); +} + +void TntTile::destroy(Level* level, int x, int y, int z, int data, + std::shared_ptr source) { if (level->isClientSide) return; if ((data & EXPLODE_BIT) == 1) { @@ -68,9 +74,9 @@ void TntTile::destroy(Level* level, int x, int y, int z, int data) { if (level->newPrimedTntAllowed() && app.GetGameHostOption(eGameHostOption_TNT)) { std::shared_ptr tnt = std::shared_ptr( - new PrimedTnt(level, x + 0.5f, y + 0.5f, z + 0.5f)); + new PrimedTnt(level, x + 0.5f, y + 0.5f, z + 0.5f, source)); level->addEntity(tnt); - level->playSound(tnt, eSoundType_RANDOM_FUSE, 1, 1.0f); + level->playEntitySound(tnt, eSoundType_RANDOM_FUSE, 1, 1.0f); } } } @@ -83,8 +89,9 @@ bool TntTile::use(Level* level, int x, int y, int z, if (soundOnly) return false; if (player->getSelectedItem() != NULL && player->getSelectedItem()->id == Item::flintAndSteel_Id) { - destroy(level, x, y, z, EXPLODE_BIT); - level->setTile(x, y, z, 0); + destroy(level, x, y, z, EXPLODE_BIT, player); + level->removeTile(x, y, z); + player->getSelectedItem()->hurtAndBreak(1, player); return true; } return Tile::use(level, x, y, z, player, clickedFace, clickX, clickY, @@ -94,22 +101,22 @@ bool TntTile::use(Level* level, int x, int y, int z, void TntTile::entityInside(Level* level, int x, int y, int z, std::shared_ptr entity) { if (entity->GetType() == eTYPE_ARROW && !level->isClientSide) { - // 4J Stu - Don't need to cast this - // std::shared_ptr arrow = - // std::dynamic_pointer_cast(entity); if (entity->isOnFire()) { - destroy(level, x, y, z, EXPLODE_BIT); - level->setTile(x, y, z, 0); + std::shared_ptr arrow = + std::dynamic_pointer_cast(entity); + destroy(level, x, y, z, EXPLODE_BIT, + arrow->owner->instanceof(eTYPE_LIVINGENTITY) + ? std::dynamic_pointer_cast(arrow->owner) + : nullptr); + level->removeTile(x, y, z); } } } -std::shared_ptr TntTile::getSilkTouchItemInstance(int data) { - return nullptr; -} - void TntTile::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(L"tnt_side"); iconTop = iconRegister->registerIcon(L"tnt_top"); iconBottom = iconRegister->registerIcon(L"tnt_bottom"); -} \ No newline at end of file +} + +bool TntTile::dropFromExplosion(Explosion* explosion) { return false; } \ No newline at end of file diff --git a/Minecraft.World/Blocks/TntTile.h b/Minecraft.World/Blocks/TntTile.h index cc6fadad9..97afe195f 100644 --- a/Minecraft.World/Blocks/TntTile.h +++ b/Minecraft.World/Blocks/TntTile.h @@ -13,23 +13,21 @@ public: static const int EXPLODE_BIT = 1; TntTile(int id); - Icon* getTexture(int face, int data); + virtual Icon* getTexture(int face, int data); virtual void onPlace(Level* level, int x, int y, int z); - - void neighborChanged(Level* level, int x, int y, int z, int type); - - int getResourceCount(Random* random); - - void wasExploded(Level* level, int x, int y, int z); - - void destroy(Level* level, int x, int y, int z, int data); - - bool use(Level* level, int x, int y, int z, std::shared_ptr player, - int clickedFace, float clickX, float clickY, float clickZ, - bool soundOnly = false); // 4J added soundOnly param - - void entityInside(Level* level, int x, int y, int z, - std::shared_ptr entity); - virtual std::shared_ptr getSilkTouchItemInstance(int data); - void registerIcons(IconRegister* iconRegister); + virtual void neighborChanged(Level* level, int x, int y, int z, int type); + virtual int getResourceCount(Random* random); + virtual void wasExploded(Level* level, int x, int y, int z, + Explosion* explosion); + virtual void destroy(Level* level, int x, int y, int z, int data); + virtual void destroy(Level* level, int x, int y, int z, int data, + std::shared_ptr source); + virtual bool use(Level* level, int x, int y, int z, + std::shared_ptr player, int clickedFace, + float clickX, float clickY, float clickZ, + bool soundOnly = false); // 4J added soundOnly param + virtual void entityInside(Level* level, int x, int y, int z, + std::shared_ptr entity); + virtual bool dropFromExplosion(Explosion* explosion); + virtual void registerIcons(IconRegister* iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Blocks/TopSnowTile.cpp b/Minecraft.World/Blocks/TopSnowTile.cpp index aed8bc72f..198741cc1 100644 --- a/Minecraft.World/Blocks/TopSnowTile.cpp +++ b/Minecraft.World/Blocks/TopSnowTile.cpp @@ -9,12 +9,13 @@ #include "TopSnowTile.h" const int TopSnowTile::MAX_HEIGHT = 6; - const int TopSnowTile::HEIGHT_MASK = 7; // max 8 steps -TopSnowTile::TopSnowTile(int id) : Tile(id, Material::topSnow, false) { +TopSnowTile::TopSnowTile(int id) + : Tile(id, Material::topSnow, false) { setShape(0, 0, 0, 1, 2 / 16.0f, 1); setTicking(true); + updateShape(0); } void TopSnowTile::registerIcons(IconRegister* iconRegister) { @@ -23,12 +24,10 @@ void TopSnowTile::registerIcons(IconRegister* iconRegister) { AABB* TopSnowTile::getAABB(Level* level, int x, int y, int z) { int height = level->getData(x, y, z) & HEIGHT_MASK; - if (height >= (MAX_HEIGHT / 2)) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); - return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, - x + tls->xx1, y + .5f, z + tls->zz1); - } - return NULL; + float offset = 2.0f / SharedConstants::WORLD_RESOLUTION; + ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape); + return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, + y + (height * offset), z + tls->zz1); } float TopSnowTile::getHeight(Level* level, int x, int y, int z) { @@ -60,11 +59,14 @@ void TopSnowTile::updateShape(int data) { bool TopSnowTile::mayPlace(Level* level, int x, int y, int z) { int t = level->getTile(x, y - 1, z); + if (t == 0) return false; + if (t == id && + (level->getData(x, y - 1, z) & HEIGHT_MASK) == MAX_HEIGHT + 1) + return true; // 4J Stu - Assume when placing that this is the server level and we don't // care how it's going to be rendered Fix for #9407 - Gameplay: Destroying a // block of snow on top of trees, removes any adjacent snow. - if (t == 0 || - (t != Tile::leaves_Id && !Tile::tiles[t]->isSolidRender(true))) + if (t != Tile::leaves_Id && !Tile::tiles[t]->isSolidRender(true)) return false; return level->getMaterial(x, y - 1, z)->blocksMotion(); } @@ -75,8 +77,8 @@ void TopSnowTile::neighborChanged(Level* level, int x, int y, int z, int type) { bool TopSnowTile::checkCanSurvive(Level* level, int x, int y, int z) { if (!mayPlace(level, x, y, z)) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); return false; } return true; @@ -85,17 +87,11 @@ bool TopSnowTile::checkCanSurvive(Level* level, int x, int y, int z) { void TopSnowTile::playerDestroy(Level* level, std::shared_ptr player, int x, int y, int z, int data) { int type = Item::snowBall->id; - float s = 0.7f; - double xo = level->random->nextFloat() * s + (1 - s) * 0.5; - double yo = level->random->nextFloat() * s + (1 - s) * 0.5; - double zo = level->random->nextFloat() * s + (1 - s) * 0.5; - std::shared_ptr item = - std::shared_ptr(new ItemEntity( - level, x + xo, y + yo, z + zo, - std::shared_ptr(new ItemInstance(type, 1, 0)))); - item->throwTime = 10; - level->addEntity(item); - level->setTile(x, y, z, 0); + int height = data & HEIGHT_MASK; + popResource( + level, x, y, z, + std::shared_ptr(new ItemInstance(type, height + 1, 0))); + level->removeTile(x, y, z); } int TopSnowTile::getResource(int data, Random* random, int playerBonusLevel) { @@ -106,8 +102,8 @@ int TopSnowTile::getResourceCount(Random* random) { return 0; } void TopSnowTile::tick(Level* level, int x, int y, int z, Random* random) { if (level->getBrightness(LightLayer::Block, x, y, z) > 11) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); } } diff --git a/Minecraft.World/Blocks/TorchTile.cpp b/Minecraft.World/Blocks/TorchTile.cpp index 47c0e49d8..bca94562f 100644 --- a/Minecraft.World/Blocks/TorchTile.cpp +++ b/Minecraft.World/Blocks/TorchTile.cpp @@ -100,21 +100,25 @@ void TorchTile::tick(Level* level, int x, int y, int z, Random* random) { void TorchTile::onPlace(Level* level, int x, int y, int z) { if (level->getData(x, y, z) == 0) { if (level->isSolidBlockingTileInLoadedChunk(x - 1, y, z, true)) { - level->setData(x, y, z, 1); + level->setData(x, y, z, 1, Tile::UPDATE_CLIENTS); } else if (level->isSolidBlockingTileInLoadedChunk(x + 1, y, z, true)) { - level->setData(x, y, z, 2); + level->setData(x, y, z, 2, Tile::UPDATE_CLIENTS); } else if (level->isSolidBlockingTileInLoadedChunk(x, y, z - 1, true)) { - level->setData(x, y, z, 3); + level->setData(x, y, z, 3, Tile::UPDATE_CLIENTS); } else if (level->isSolidBlockingTileInLoadedChunk(x, y, z + 1, true)) { - level->setData(x, y, z, 4); + level->setData(x, y, z, 4, Tile::UPDATE_CLIENTS); } else if (isConnection(level, x, y - 1, z)) { - level->setData(x, y, z, 5); + level->setData(x, y, z, 5, Tile::UPDATE_CLIENTS); } } checkCanSurvive(level, x, y, z); } void TorchTile::neighborChanged(Level* level, int x, int y, int z, int type) { + checkDoPop(level, x, y, z, type); +} + +bool TorchTile::checkDoPop(Level* level, int x, int y, int z, int type) { if (checkCanSurvive(level, x, y, z)) { int dir = level->getData(x, y, z); bool replace = false; @@ -134,17 +138,21 @@ void TorchTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!isConnection(level, x, y - 1, z) && dir == 5) replace = true; if (replace) { - this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, level->getData(x, y, z), 0); + level->removeTile(x, y, z); + return true; } + } else { + return true; } + return false; } bool TorchTile::checkCanSurvive(Level* level, int x, int y, int z) { if (!mayPlace(level, x, y, z)) { if (level->getTile(x, y, z) == id) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } return false; } diff --git a/Minecraft.World/Blocks/TorchTile.h b/Minecraft.World/Blocks/TorchTile.h index 9f258f6a7..0369a3584 100644 --- a/Minecraft.World/Blocks/TorchTile.h +++ b/Minecraft.World/Blocks/TorchTile.h @@ -23,7 +23,7 @@ public: virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); virtual int getRenderShape(); - bool isConnection(Level* level, int x, int y, int z); + virtual bool isConnection(Level* level, int x, int y, int z); virtual bool mayPlace(Level* level, int x, int y, int z); virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, @@ -32,7 +32,8 @@ public: virtual void onPlace(Level* level, int x, int y, int z); virtual void neighborChanged(Level* level, int x, int y, int z, int type); -private: +protected: + virtual bool checkDoPop(Level* level, int x, int y, int z, int type); virtual bool checkCanSurvive(Level* level, int x, int y, int z); public: diff --git a/Minecraft.World/Blocks/TrapDoorTile.cpp b/Minecraft.World/Blocks/TrapDoorTile.cpp index 48610d388..eb685504d 100644 --- a/Minecraft.World/Blocks/TrapDoorTile.cpp +++ b/Minecraft.World/Blocks/TrapDoorTile.cpp @@ -49,7 +49,11 @@ void TrapDoorTile::updateDefaultShape() { void TrapDoorTile::setShape(int data) { float r = 3 / 16.0f; - Tile::setShape(0, 0, 0, 1, r, 1); + if ((data & TOP_MASK) != 0) { + setShape(0, 1 - r, 0, 1, 1, 1); + } else { + setShape(0, 0, 0, 1, r, 1); + } if (isOpen(data)) { if ((data & 3) == 0) setShape(0, 0, 1 - r, 1, 1, 1); if ((data & 3) == 1) setShape(0, 0, 0, 1, 1, r); @@ -60,7 +64,7 @@ void TrapDoorTile::setShape(int data) { void TrapDoorTile::attack(Level* level, int x, int y, int z, std::shared_ptr player) { - use(level, x, y, z, player, 0, 0, 0, 0); + // use(level, x, y, z, player, 0, 0, 0, 0); } // 4J-PB - Adding a TestUse for tooltip display @@ -80,7 +84,7 @@ bool TrapDoorTile::use(Level* level, int x, int y, int z, } int dir = level->getData(x, y, z); - level->setData(x, y, z, dir ^ 4); + level->setData(x, y, z, dir ^ 4, Tile::UPDATE_CLIENTS); level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0); return true; @@ -92,7 +96,7 @@ void TrapDoorTile::setOpen(Level* level, int x, int y, int z, bool shouldOpen) { bool wasOpen = (dir & 4) > 0; if (wasOpen == shouldOpen) return; - level->setData(x, y, z, dir ^ 4); + level->setData(x, y, z, dir ^ 4, Tile::UPDATE_CLIENTS); level->levelEvent(nullptr, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0); } @@ -110,7 +114,7 @@ void TrapDoorTile::neighborChanged(Level* level, int x, int y, int z, if ((data & 3) == 3) xt--; if (!attachesTo(level->getTile(xt, y, zt))) { - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); spawnResources(level, x, y, z, data, 0); } @@ -168,7 +172,7 @@ bool TrapDoorTile::attachesTo(int id) { return tile != NULL && (tile->material->isSolidBlocking() && tile->isCubeShaped()) || - tile == Tile::lightGem || + tile == Tile::glowstone || (dynamic_cast(tile) != NULL) || (dynamic_cast(tile) != NULL); -} +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/TreeTile.cpp b/Minecraft.World/Blocks/TreeTile.cpp index 37cb956e1..8bf398d18 100644 --- a/Minecraft.World/Blocks/TreeTile.cpp +++ b/Minecraft.World/Blocks/TreeTile.cpp @@ -7,19 +7,17 @@ #include "TreeTile.h" -const unsigned int TreeTile::TREE_NAMES[TREE_NAMES_LENGTH] = { +const unsigned int TreeTile::TREE_NAMES[TreeTile::TREE_NAMES_LENGTH] = { IDS_TILE_LOG_OAK, IDS_TILE_LOG_SPRUCE, IDS_TILE_LOG_BIRCH, IDS_TILE_LOG_JUNGLE}; +const std::wstring TreeTile::TREE_STRING_NAMES[TreeTile::TREE_NAMES_LENGTH] = { + L"oak", L"spruce", L"birch", L"jungle"}; + const std::wstring TreeTile::TREE_TEXTURES[] = {L"tree_side", L"tree_spruce", L"tree_birch", L"tree_jungle"}; -TreeTile::TreeTile(int id) : Tile(id, Material::wood) { - icons = NULL; - iconTop = NULL; -} - -int TreeTile::getRenderShape() { return Tile::SHAPE_TREE; } +TreeTile::TreeTile(int id) : RotatedPillarTile(id, Material::wood) {} int TreeTile::getResourceCount(Random* random) { return 1; } @@ -40,64 +38,25 @@ void TreeTile::onRemove(Level* level, int x, int y, int z, int id, int data) { int currentData = level->getData(x + xo, y + yo, z + zo); if ((currentData & LeafTile::UPDATE_LEAF_BIT) == 0) { - level->setDataNoUpdate( + level->setData( x + xo, y + yo, z + zo, - currentData | LeafTile::UPDATE_LEAF_BIT); + currentData | LeafTile::UPDATE_LEAF_BIT, + Tile::UPDATE_NONE); } } } } } -void TreeTile::setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by) { - int type = level->getData(x, y, z) & MASK_TYPE; - int dir = PistonBaseTile::getNewFacing( - level, x, y, z, std::dynamic_pointer_cast(by)); - int facing = 0; - - switch (dir) { - case Facing::NORTH: - case Facing::SOUTH: - facing = FACING_Z; - break; - case Facing::EAST: - case Facing::WEST: - facing = FACING_X; - break; - case Facing::UP: - case Facing::DOWN: - facing = FACING_Y; - break; - } - - level->setData(x, y, z, type | facing); -} - -Icon* TreeTile::getTexture(int face, int data) { - int dir = data & MASK_FACING; - int type = data & MASK_TYPE; - - if (dir == FACING_Y && (face == Facing::UP || face == Facing::DOWN)) { - return iconTop; - } else if (dir == FACING_X && - (face == Facing::EAST || face == Facing::WEST)) { - return iconTop; - } else if (dir == FACING_Z && - (face == Facing::NORTH || face == Facing::SOUTH)) { - return iconTop; - } - - return icons[type]; -} - unsigned int TreeTile::getDescriptionId(int iData /*= -1*/) { int type = iData & MASK_TYPE; if (type < 0) type = 0; return TreeTile::TREE_NAMES[type]; } -int TreeTile::getSpawnResourcesAuxValue(int data) { return data & MASK_TYPE; } +Icon* TreeTile::getTypeTexture(int type) { return icons_side[type]; } + +Icon* TreeTile::getTopTexture(int type) { return icons_top[type]; } int TreeTile::getWoodType(int data) { return data & MASK_TYPE; } @@ -108,10 +67,10 @@ std::shared_ptr TreeTile::getSilkTouchItemInstance(int data) { } void TreeTile::registerIcons(IconRegister* iconRegister) { - iconTop = iconRegister->registerIcon(L"tree_top"); - icons = new Icon*[TREE_NAMES_LENGTH]; - for (int i = 0; i < TREE_NAMES_LENGTH; i++) { - icons[i] = iconRegister->registerIcon(TREE_TEXTURES[i]); + icons_side[i] = iconRegister->registerIcon(getIconName() + L"_" + + TREE_STRING_NAMES[i]); + icons_top[i] = iconRegister->registerIcon( + getIconName() + L"_" + TREE_STRING_NAMES[i] + L"_top"); } } \ No newline at end of file diff --git a/Minecraft.World/Blocks/TreeTile.h b/Minecraft.World/Blocks/TreeTile.h index 62783f917..455a3adc3 100644 --- a/Minecraft.World/Blocks/TreeTile.h +++ b/Minecraft.World/Blocks/TreeTile.h @@ -1,11 +1,11 @@ #pragma once -#include "Tile.h" +#include "RotatedPillarTile.h" class ChunkRebuildData; class Player; -class TreeTile : public Tile { +class TreeTile : public RotatedPillarTile { friend class Tile; friend class ChunkRebuildData; @@ -24,27 +24,26 @@ public: static const unsigned int TREE_NAMES[TREE_NAMES_LENGTH]; + static const std::wstring TREE_STRING_NAMES[TREE_NAMES_LENGTH]; + static const std::wstring TREE_TEXTURES[]; private: - Icon** icons; - Icon* iconTop; + Icon* icons_side[TREE_NAMES_LENGTH]; + Icon* icons_top[TREE_NAMES_LENGTH]; protected: TreeTile(int id); public: - virtual int getRenderShape(); virtual int getResourceCount(Random* random); virtual int getResource(int data, Random* random, int playerBonusLevel); virtual void onRemove(Level* level, int x, int y, int z, int id, int data); - virtual void setPlacedBy(Level* level, int x, int y, int z, - std::shared_ptr by); - virtual Icon* getTexture(int face, int data); virtual unsigned int getDescriptionId(int iData = -1); protected: - int getSpawnResourcesAuxValue(int data); + virtual Icon* getTypeTexture(int type); + virtual Icon* getTopTexture(int type); public: static int getWoodType(int data); diff --git a/Minecraft.World/Blocks/TripWireSourceTile.cpp b/Minecraft.World/Blocks/TripWireSourceTile.cpp index 12c5bb6bf..14fc620b9 100644 --- a/Minecraft.World/Blocks/TripWireSourceTile.cpp +++ b/Minecraft.World/Blocks/TripWireSourceTile.cpp @@ -2,6 +2,7 @@ #include "../Headers/net.minecraft.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.level.redstone.h" #include "TripWireSourceTile.h" TripWireSourceTile::TripWireSourceTile(int id) @@ -93,8 +94,8 @@ void TripWireSourceTile::neighborChanged(Level* level, int x, int y, int z, replace = true; if (replace) { - this->spawnResources(level, x, y, z, data, 0); - level->setTile(x, y, z, 0); + spawnResources(level, x, y, z, data, 0); + level->removeTile(x, y, z); } } } @@ -170,7 +171,7 @@ void TripWireSourceTile::calculateState( int xx = x + stepX * receiverPos; int zz = z + stepZ * receiverPos; int opposite = Direction::DIRECTION_OPPOSITE[dir]; - level->setData(xx, y, zz, opposite | state); + level->setData(xx, y, zz, opposite | state, Tile::UPDATE_ALL); notifyNeighbors(level, xx, y, zz, opposite); playSound(level, xx, y, zz, attached, powered, wasAttached, wasPowered); @@ -180,7 +181,7 @@ void TripWireSourceTile::calculateState( if (id > 0) // ie. it isn't being removed. { - level->setData(x, y, z, data); + level->setData(x, y, z, data, Tile::UPDATE_ALL); if (canUpdate) notifyNeighbors(level, x, y, z, dir); } @@ -197,7 +198,7 @@ void TripWireSourceTile::calculateState( wireData &= ~TripWireTile::MASK_ATTACHED; } - level->setData(xx, y, zz, wireData); + level->setData(xx, y, zz, wireData, Tile::UPDATE_ALL); } } } @@ -228,23 +229,23 @@ void TripWireSourceTile::playSound(Level* level, int x, int y, int z, void TripWireSourceTile::notifyNeighbors(Level* level, int x, int y, int z, int dir) { - level->updateNeighborsAt(x, y, z, this->id); + level->updateNeighborsAt(x, y, z, id); if (dir == Direction::EAST) { - level->updateNeighborsAt(x - 1, y, z, this->id); + level->updateNeighborsAt(x - 1, y, z, id); } else if (dir == Direction::WEST) { - level->updateNeighborsAt(x + 1, y, z, this->id); + level->updateNeighborsAt(x + 1, y, z, id); } else if (dir == Direction::SOUTH) { - level->updateNeighborsAt(x, y, z - 1, this->id); + level->updateNeighborsAt(x, y, z - 1, id); } else if (dir == Direction::NORTH) { - level->updateNeighborsAt(x, y, z + 1, this->id); + level->updateNeighborsAt(x, y, z + 1, id); } } bool TripWireSourceTile::checkCanSurvive(Level* level, int x, int y, int z) { if (!mayPlace(level, x, y, z)) { this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return false; } @@ -296,23 +297,29 @@ void TripWireSourceTile::onRemove(Level* level, int x, int y, int z, int id, Tile::onRemove(level, x, y, z, id, data); } -bool TripWireSourceTile::getSignal(LevelSource* level, int x, int y, int z, - int dir) { - return (level->getData(x, y, z) & MASK_POWERED) == MASK_POWERED; +int TripWireSourceTile::getSignal(LevelSource* level, int x, int y, int z, + int dir) { + return (level->getData(x, y, z) & MASK_POWERED) == MASK_POWERED + ? Redstone::SIGNAL_MAX + : Redstone::SIGNAL_NONE; } -bool TripWireSourceTile::getDirectSignal(Level* level, int x, int y, int z, - int dir) { +int TripWireSourceTile::getDirectSignal(LevelSource* level, int x, int y, int z, + int dir) { int data = level->getData(x, y, z); - if ((data & MASK_POWERED) != MASK_POWERED) return false; + if ((data & MASK_POWERED) != MASK_POWERED) return Redstone::SIGNAL_NONE; int myDir = data & MASK_DIR; - if (myDir == Direction::NORTH && dir == Facing::NORTH) return true; - if (myDir == Direction::SOUTH && dir == Facing::SOUTH) return true; - if (myDir == Direction::WEST && dir == Facing::WEST) return true; - if (myDir == Direction::EAST && dir == Facing::EAST) return true; + if (myDir == Direction::NORTH && dir == Facing::NORTH) + return Redstone::SIGNAL_MAX; + if (myDir == Direction::SOUTH && dir == Facing::SOUTH) + return Redstone::SIGNAL_MAX; + if (myDir == Direction::WEST && dir == Facing::WEST) + return Redstone::SIGNAL_MAX; + if (myDir == Direction::EAST && dir == Facing::EAST) + return Redstone::SIGNAL_MAX; - return false; + return Redstone::SIGNAL_NONE; } bool TripWireSourceTile::isSignalSource() { return true; } diff --git a/Minecraft.World/Blocks/TripWireSourceTile.h b/Minecraft.World/Blocks/TripWireSourceTile.h index 81dc1d571..9cce09eb6 100644 --- a/Minecraft.World/Blocks/TripWireSourceTile.h +++ b/Minecraft.World/Blocks/TripWireSourceTile.h @@ -43,7 +43,8 @@ public: std::shared_ptr forceEntity = std::shared_ptr()); void onRemove(Level* level, int x, int y, int z, int id, int data); - virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir); - virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir); + virtual int getSignal(LevelSource* level, int x, int y, int z, int dir); + virtual int getDirectSignal(LevelSource* level, int x, int y, int z, + int dir); bool isSignalSource(); }; diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index 51477fed7..d33c3ea72 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -5,7 +5,8 @@ #include "../Headers/net.minecraft.world.phys.h" #include "TripWireTile.h" -TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, false) { +TripWireTile::TripWireTile(int id) + : Tile(id, Material::decoration, false) { setShape(0, 0, 0, 1, 2.5f / 16.0f, 1); this->setTicking(true); } @@ -43,7 +44,7 @@ void TripWireTile::neighborChanged(Level* level, int x, int y, int z, bool isSuspended = !level->isTopSolidBlocking(x, y - 1, z); if (wasSuspended != isSuspended) { spawnResources(level, x, y, z, data, 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } @@ -65,7 +66,7 @@ void TripWireTile::updateShape(LevelSource* level, int x, int y, int z, void TripWireTile::onPlace(Level* level, int x, int y, int z) { int data = level->isTopSolidBlocking(x, y - 1, z) ? 0 : MASK_SUSPENDED; - level->setData(x, y, z, data); + level->setData(x, y, z, data, Tile::UPDATE_ALL); updateSource(level, x, y, z, data); } @@ -80,7 +81,7 @@ void TripWireTile::playerWillDestroy(Level* level, int x, int y, int z, if (player->getSelectedItem() != NULL && player->getSelectedItem()->id == Item::shears_Id) { - level->setData(x, y, z, data | MASK_DISARMED); + level->setData(x, y, z, data | MASK_DISARMED, Tile::UPDATE_NONE); } } @@ -136,7 +137,13 @@ void TripWireTile::checkPressed(Level* level, int x, int y, int z) { nullptr, AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1)); if (!entities->empty()) { - shouldBePressed = true; + for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { + std::shared_ptr e = *it; + if (!e->isIgnoringTileTriggers()) { + shouldBePressed = true; + break; + } + } } if (shouldBePressed && !wasPressed) { @@ -148,7 +155,7 @@ void TripWireTile::checkPressed(Level* level, int x, int y, int z) { } if (shouldBePressed != wasPressed) { - level->setData(x, y, z, data); + level->setData(x, y, z, data, Tile::UPDATE_ALL); updateSource(level, x, y, z, data); } diff --git a/Minecraft.World/Blocks/VineTile.cpp b/Minecraft.World/Blocks/VineTile.cpp index 542504125..d2febbaa9 100644 --- a/Minecraft.World/Blocks/VineTile.cpp +++ b/Minecraft.World/Blocks/VineTile.cpp @@ -8,7 +8,8 @@ #include "../Headers/net.minecraft.stats.h" #include "../Headers/net.minecraft.world.level.biome.h" -VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, false) { +VineTile::VineTile(int id) + : Tile(id, Material::replaceable_plant, false) { setTicking(true); } @@ -139,7 +140,7 @@ bool VineTile::updateSurvival(Level* level, int x, int y, int z) { } } if (newFacings != facings) { - level->setData(x, y, z, newFacings); + level->setData(x, y, z, newFacings, Tile::UPDATE_CLIENTS); } return true; } @@ -159,7 +160,7 @@ int VineTile::getColor(LevelSource* level, int x, int y, int z) { void VineTile::neighborChanged(Level* level, int x, int y, int z, int type) { if (!level->isClientSide && !updateSurvival(level, x, y, z)) { spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); } } @@ -202,7 +203,8 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { } } if (spawnFacings > 0) { - level->setTileAndData(x, y + 1, z, id, spawnFacings); + level->setTileAndData(x, y + 1, z, id, spawnFacings, + Tile::UPDATE_CLIENTS); } } } else if (testFacing >= Facing::NORTH && @@ -231,8 +233,8 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { Direction::STEP_Z[left]))) { level->setTileAndData( x + Direction::STEP_X[testDirection], y, - z + Direction::STEP_Z[testDirection], id, - 1 << left); + z + Direction::STEP_Z[testDirection], id, 1 << left, + Tile::UPDATE_CLIENTS); } else if ((currentFacings & (1 << right)) != 0 && isAcceptableNeighbor(level->getTile( x + Direction::STEP_X[testDirection] + @@ -243,7 +245,7 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { level->setTileAndData( x + Direction::STEP_X[testDirection], y, z + Direction::STEP_Z[testDirection], id, - 1 << right); + 1 << right, Tile::UPDATE_CLIENTS); } // attempt to grow around corners, but only if the // base tile is solid @@ -263,7 +265,8 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[left], - id, 1 << ((testDirection + 2) & 3)); + id, 1 << ((testDirection + 2) & 3), + Tile::UPDATE_CLIENTS); } else if ((currentFacings & (1 << right)) != 0 && level->isEmptyTile( x + Direction::STEP_X[testDirection] + @@ -280,7 +283,8 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[right], - id, 1 << ((testDirection + 2) & 3)); + id, 1 << ((testDirection + 2) & 3), + Tile::UPDATE_CLIENTS); } // attempt to grow onto the ceiling else if (isAcceptableNeighbor(level->getTile( @@ -288,14 +292,16 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { z + Direction::STEP_Z[testDirection]))) { level->setTileAndData( x + Direction::STEP_X[testDirection], y, - z + Direction::STEP_Z[testDirection], id, 0); + z + Direction::STEP_Z[testDirection], id, 0, + Tile::UPDATE_CLIENTS); } } else if (Tile::tiles[edgeTile]->material->isSolidBlocking() && Tile::tiles[edgeTile]->isCubeShaped()) { // we have a wall that we can cling to level->setData(x, y, z, - currentFacings | (1 << testDirection)); + currentFacings | (1 << testDirection), + Tile::UPDATE_CLIENTS); } } // growing downwards happens more often than the other @@ -307,14 +313,16 @@ void VineTile::tick(Level* level, int x, int y, int z, Random* random) { int spawnFacings = level->random->nextInt(16) & currentFacings; if (spawnFacings > 0) { - level->setTileAndData(x, y - 1, z, id, spawnFacings); + level->setTileAndData(x, y - 1, z, id, spawnFacings, + Tile::UPDATE_CLIENTS); } } else if (belowTile == id) { int spawnFacings = level->random->nextInt(16) & currentFacings; int belowData = level->getData(x, y - 1, z); if (belowData != (belowData | spawnFacings)) { - level->setData(x, y - 1, z, belowData | spawnFacings); + level->setData(x, y - 1, z, belowData | spawnFacings, + Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/Blocks/WallTile.cpp b/Minecraft.World/Blocks/WallTile.cpp index 861744c09..67d3c0bae 100644 --- a/Minecraft.World/Blocks/WallTile.cpp +++ b/Minecraft.World/Blocks/WallTile.cpp @@ -25,9 +25,9 @@ WallTile::WallTile(int id, Tile* baseTile) Icon* WallTile::getTexture(int face, int data) { if (data == TYPE_MOSSY) { - return Tile::mossStone->getTexture(face); + return Tile::mossyCobblestone->getTexture(face); } - return Tile::stoneBrick->getTexture(face); + return Tile::cobblestone->getTexture(face); } int WallTile::getRenderShape() { return SHAPE_WALL; } diff --git a/Minecraft.World/Blocks/WaterLilyTile.cpp b/Minecraft.World/Blocks/WaterLilyTile.cpp index a4f23ce23..6ba33ba73 100644 --- a/Minecraft.World/Blocks/WaterLilyTile.cpp +++ b/Minecraft.World/Blocks/WaterLilyTile.cpp @@ -11,14 +11,14 @@ WaterlilyTile::WaterlilyTile(int id) : Bush(id) { this->updateDefaultShape(); } void WaterlilyTile::updateDefaultShape() { float ss = 0.5f; float hh = 0.25f / 16.0f; - this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, hh, 0.5f + ss); + setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, hh, 0.5f + ss); } int WaterlilyTile::getRenderShape() { return Tile::SHAPE_LILYPAD; } void WaterlilyTile::addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source) { - if (source == NULL || !(std::dynamic_pointer_cast(source))) { + if (source == NULL || !source->instanceof(eTYPE_BOAT)) { Bush::addAABBs(level, x, y, z, box, boxes, source); } } diff --git a/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp b/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp new file mode 100644 index 000000000..55e1b5a15 --- /dev/null +++ b/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp @@ -0,0 +1,41 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.entity.item.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.level.redstone.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Entities/Entity.h" +#include "WeightedPressurePlateTile.h" + +WeightedPressurePlateTile::WeightedPressurePlateTile(int id, + const std::wstring& tex, + Material* material, + int maxWeight) + : BasePressurePlateTile(id, tex, material) { + this->maxWeight = maxWeight; + + // 4J Stu - Move this from base class to use virtual function + updateShape(getDataForSignal(Redstone::SIGNAL_MAX)); +} + +int WeightedPressurePlateTile::getSignalStrength(Level* level, int x, int y, + int z) { + int weightOfEntities = + level->getEntitiesOfClass(typeid(Entity), getSensitiveAABB(x, y, z)) + ->size(); + int count = std::min(weightOfEntities, maxWeight); + + if (count <= 0) { + return 0; + } else { + float pct = std::min(maxWeight, count) / (float)maxWeight; + return Mth::ceil(pct * Redstone::SIGNAL_MAX); + } +} + +int WeightedPressurePlateTile::getSignalForData(int data) { return data; } + +int WeightedPressurePlateTile::getDataForSignal(int signal) { return signal; } + +int WeightedPressurePlateTile::getTickDelay(Level* level) { + return SharedConstants::TICKS_PER_SECOND / 2; +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/WeightedPressurePlateTile.h b/Minecraft.World/Blocks/WeightedPressurePlateTile.h new file mode 100644 index 000000000..12009d7fa --- /dev/null +++ b/Minecraft.World/Blocks/WeightedPressurePlateTile.h @@ -0,0 +1,18 @@ +#pragma once + +#include "BasePressurePlateTile.h" + +class WeightedPressurePlateTile : public BasePressurePlateTile { +private: + int maxWeight; + +public: + WeightedPressurePlateTile(int id, const std::wstring& tex, + Material* material, int maxWeight); + +protected: + virtual int getSignalStrength(Level* level, int x, int y, int z); + virtual int getSignalForData(int data); + virtual int getDataForSignal(int signal); + virtual int getTickDelay(Level* level); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/WoodButtonTile.cpp b/Minecraft.World/Blocks/WoodButtonTile.cpp new file mode 100644 index 000000000..3129003de --- /dev/null +++ b/Minecraft.World/Blocks/WoodButtonTile.cpp @@ -0,0 +1,9 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.h" +#include "WoodButtonTile.h" + +WoodButtonTile::WoodButtonTile(int id) : ButtonTile(id, true) {} + +Icon* WoodButtonTile::getTexture(int face, int data) { + return Tile::wood->getTexture(Facing::UP); +} \ No newline at end of file diff --git a/Minecraft.World/Blocks/WoodButtonTile.h b/Minecraft.World/Blocks/WoodButtonTile.h new file mode 100644 index 000000000..30df3da9e --- /dev/null +++ b/Minecraft.World/Blocks/WoodButtonTile.h @@ -0,0 +1,10 @@ +#pragma once + +#include "ButtonTile.h" + +class WoodButtonTile : public ButtonTile { +public: + WoodButtonTile(int id); + + Icon* getTexture(int face, int data); +}; \ No newline at end of file diff --git a/Minecraft.World/Blocks/WoodTile.cpp b/Minecraft.World/Blocks/WoodTile.cpp index 3b6d9699f..59142c2de 100644 --- a/Minecraft.World/Blocks/WoodTile.cpp +++ b/Minecraft.World/Blocks/WoodTile.cpp @@ -14,8 +14,8 @@ const unsigned int WoodTile::WOOD_NAMES[WOOD_NAMES_LENGTH] = { IDS_TILE_JUNGLE_PLANKS, }; -const std::wstring WoodTile::TEXTURE_NAMES[] = {L"wood", L"wood_spruce", - L"wood_birch", L"wood_jungle"}; +const std::wstring WoodTile::TEXTURE_NAMES[] = {L"oak", L"spruce", L"birch", + L"jungle"}; // public static final String[] WOOD_NAMES = { // "oak", "spruce", "birch", "jungle" @@ -42,6 +42,7 @@ void WoodTile::registerIcons(IconRegister* iconRegister) { icons = new Icon*[WOOD_NAMES_LENGTH]; for (int i = 0; i < WOOD_NAMES_LENGTH; i++) { - icons[i] = iconRegister->registerIcon(TEXTURE_NAMES[i]); + icons[i] = + iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_NAMES[i]); } } \ No newline at end of file diff --git a/Minecraft.World/Blocks/WoolCarpetTile.cpp b/Minecraft.World/Blocks/WoolCarpetTile.cpp index 79d3ba931..0b1ead42c 100644 --- a/Minecraft.World/Blocks/WoolCarpetTile.cpp +++ b/Minecraft.World/Blocks/WoolCarpetTile.cpp @@ -12,7 +12,7 @@ WoolCarpetTile::WoolCarpetTile(int id) } Icon* WoolCarpetTile::getTexture(int face, int data) { - return Tile::cloth->getTexture(face, data); + return Tile::wool->getTexture(face, data); } AABB* WoolCarpetTile::getAABB(Level* level, int x, int y, int z) { @@ -57,7 +57,7 @@ void WoolCarpetTile::neighborChanged(Level* level, int x, int y, int z, bool WoolCarpetTile::checkCanSurvive(Level* level, int x, int y, int z) { if (!canSurvive(level, x, y, z)) { spawnResources(level, x, y, z, level->getData(x, y, z), 0); - level->setTile(x, y, z, 0); + level->removeTile(x, y, z); return false; } return true; diff --git a/Minecraft.World/Blocks/WorkbenchTile.cpp b/Minecraft.World/Blocks/WorkbenchTile.cpp index 916fe8ee1..f266f7ed2 100644 --- a/Minecraft.World/Blocks/WorkbenchTile.cpp +++ b/Minecraft.World/Blocks/WorkbenchTile.cpp @@ -36,5 +36,6 @@ bool WorkbenchTile::use(Level* level, int x, int y, int z, return true; } player->startCrafting(x, y, z); + // player->openFireworks(x, y, z); return true; } \ No newline at end of file