the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 253 lines 7.2 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.world.entity.item.h" 3#include "net.minecraft.world.entity.player.h" 4#include "net.minecraft.world.entity.projectile.h" 5#include "net.minecraft.world.item.h" 6#include "net.minecraft.world.inventory.h" 7#include "net.minecraft.world.level.h" 8#include "net.minecraft.world.level.tile.h" 9#include "net.minecraft.world.level.tile.entity.h" 10#include "net.minecraft.world.h" 11#include "DispenserTile.h" 12#include "net.minecraft.h" 13#include "Mob.h" 14 15BehaviorRegistry DispenserTile::REGISTRY = BehaviorRegistry(new DefaultDispenseItemBehavior()); 16 17DispenserTile::DispenserTile(int id) : BaseEntityTile(id, Material::stone) 18{ 19 random = new Random(); 20 21 iconTop = NULL; 22 iconFront = NULL; 23 iconFrontVertical = NULL; 24} 25 26int DispenserTile::getTickDelay(Level *level) 27{ 28 return 4; 29} 30 31void DispenserTile::onPlace(Level *level, int x, int y, int z) 32{ 33 BaseEntityTile::onPlace(level, x, y, z); 34 recalcLockDir(level, x, y, z); 35} 36 37void DispenserTile::recalcLockDir(Level *level, int x, int y, int z) 38{ 39 if (level->isClientSide) 40 { 41 return; 42 } 43 44 int n = level->getTile(x, y, z - 1); // face = 2 45 int s = level->getTile(x, y, z + 1); // face = 3 46 int w = level->getTile(x - 1, y, z); // face = 4 47 int e = level->getTile(x + 1, y, z); // face = 5 48 49 int lockDir = 3; 50 if (Tile::solid[n] && !Tile::solid[s]) lockDir = 3; 51 if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2; 52 if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5; 53 if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4; 54 level->setData(x, y, z, lockDir, Tile::UPDATE_CLIENTS); 55} 56 57Icon *DispenserTile::getTexture(int face, int data) 58{ 59 int dir = data & FACING_MASK; 60 61 if (face == dir) 62 { 63 if (dir == Facing::UP || dir == Facing::DOWN) 64 { 65 return iconFrontVertical; 66 } 67 else 68 { 69 return iconFront; 70 } 71 } 72 73 if (dir == Facing::UP || dir == Facing::DOWN) 74 { 75 return iconTop; 76 } 77 else if (face == Facing::UP || face == Facing::DOWN) 78 { 79 return iconTop; 80 } 81 82 return icon; 83} 84 85void DispenserTile::registerIcons(IconRegister *iconRegister) 86{ 87 icon = iconRegister->registerIcon(L"furnace_side"); 88 iconTop = iconRegister->registerIcon(L"furnace_top"); 89 iconFront = iconRegister->registerIcon(L"dispenser_front"); 90 iconFrontVertical = iconRegister->registerIcon(L"dispenser_front_vertical"); 91} 92 93// 4J-PB - Adding a TestUse for tooltip display 94bool DispenserTile::TestUse() 95{ 96 return true; 97} 98 99bool DispenserTile::use(Level *level, int x, int y, int z, shared_ptr<Player> player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param 100{ 101 if( soundOnly) return false; 102 103 if (level->isClientSide) 104 { 105 return true; 106 } 107 108 shared_ptr<DispenserTileEntity> trap = dynamic_pointer_cast<DispenserTileEntity>( level->getTileEntity(x, y, z) ); 109 player->openTrap(trap); 110 111 return true; 112} 113 114void DispenserTile::dispenseFrom(Level *level, int x, int y, int z) 115{ 116 BlockSourceImpl source(level, x, y, z); 117 shared_ptr<DispenserTileEntity> trap = dynamic_pointer_cast<DispenserTileEntity>( source.getEntity() ); 118 if (trap == NULL) return; 119 120 int slot = trap->getRandomSlot(); 121 if (slot < 0) 122 { 123 level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); 124 } 125 else 126 { 127 shared_ptr<ItemInstance> item = trap->getItem(slot); 128 DispenseItemBehavior *behavior = getDispenseMethod(item); 129 130 if (behavior != DispenseItemBehavior::NOOP) 131 { 132 shared_ptr<ItemInstance> leftOver = behavior->dispense(&source, item); 133 134 trap->setItem(slot, leftOver->count == 0 ? nullptr : leftOver); 135 } 136 } 137} 138 139DispenseItemBehavior *DispenserTile::getDispenseMethod(shared_ptr<ItemInstance> item) 140{ 141 return REGISTRY.get(item->getItem()); 142} 143 144void DispenserTile::neighborChanged(Level *level, int x, int y, int z, int type) 145{ 146 bool signal = level->hasNeighborSignal(x, y, z) || level->hasNeighborSignal(x, y + 1, z); 147 int data = level->getData(x, y, z); 148 bool isTriggered = (data & TRIGGER_BIT) != 0; 149 150 if (signal && !isTriggered) 151 { 152 level->addToTickNextTick(x, y, z, id, getTickDelay(level)); 153 level->setData(x, y, z, data | TRIGGER_BIT, UPDATE_NONE); 154 } 155 else if (!signal && isTriggered) 156 { 157 level->setData(x, y, z, data & ~TRIGGER_BIT, UPDATE_NONE); 158 } 159} 160 161void DispenserTile::tick(Level *level, int x, int y, int z, Random *random) 162{ 163 if (!level->isClientSide) // && (level.hasNeighborSignal(x, y, z) || level.hasNeighborSignal(x, y + 1, z))) 164 { 165 dispenseFrom(level, x, y, z); 166 } 167} 168 169shared_ptr<TileEntity> DispenserTile::newTileEntity(Level *level) 170{ 171 return shared_ptr<DispenserTileEntity>( new DispenserTileEntity() ); 172} 173 174void DispenserTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<LivingEntity> by, shared_ptr<ItemInstance> itemInstance) 175{ 176 int dir = PistonBaseTile::getNewFacing(level, x, y, z, by); 177 178 level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS); 179 180 if (itemInstance->hasCustomHoverName()) 181 { 182 dynamic_pointer_cast<DispenserTileEntity>( level->getTileEntity(x, y, z))->setCustomName(itemInstance->getHoverName()); 183 } 184} 185 186void DispenserTile::onRemove(Level *level, int x, int y, int z, int id, int data) 187{ 188 shared_ptr<Container> container = dynamic_pointer_cast<DispenserTileEntity>( level->getTileEntity(x, y, z) ); 189 if (container != NULL ) 190 { 191 for (unsigned int i = 0; i < container->getContainerSize(); i++) 192 { 193 shared_ptr<ItemInstance> item = container->getItem(i); 194 if (item != NULL) 195 { 196 float xo = random->nextFloat() * 0.8f + 0.1f; 197 float yo = random->nextFloat() * 0.8f + 0.1f; 198 float zo = random->nextFloat() * 0.8f + 0.1f; 199 200 while (item->count > 0) 201 { 202 int count = random->nextInt(21) + 10; 203 if (count > item->count) count = item->count; 204 item->count -= count; 205 206 shared_ptr<ItemInstance> newItem = shared_ptr<ItemInstance>( new ItemInstance(item->id, count, item->getAuxValue()) ); 207 newItem->set4JData( item->get4JData() ); 208 shared_ptr<ItemEntity> itemEntity = shared_ptr<ItemEntity>( new ItemEntity(level, x + xo, y + yo, z + zo, newItem ) ); 209 float pow = 0.05f; 210 itemEntity->xd = (float) random->nextGaussian() * pow; 211 itemEntity->yd = (float) random->nextGaussian() * pow + 0.2f; 212 itemEntity->zd = (float) random->nextGaussian() * pow; 213 if (item->hasTag()) 214 { 215 itemEntity->getItem()->setTag((CompoundTag *) item->getTag()->copy()); 216 } 217 level->addEntity(itemEntity); 218 } 219 220 // 4J Stu - Fix for duplication glitch 221 container->setItem(i,nullptr); 222 } 223 } 224 level->updateNeighbourForOutputSignal(x, y, z, id); 225 } 226 BaseEntityTile::onRemove(level, x, y, z, id, data); 227} 228 229Position *DispenserTile::getDispensePosition(BlockSource *source) 230{ 231 FacingEnum *facing = getFacing(source->getData()); 232 233 double originX = source->getX() + 0.7 * facing->getStepX(); 234 double originY = source->getY() + 0.7 * facing->getStepY(); 235 double originZ = source->getZ() + 0.7 * facing->getStepZ(); 236 237 return new PositionImpl(originX, originY, originZ); 238} 239 240FacingEnum *DispenserTile::getFacing(int data) 241{ 242 return FacingEnum::fromData(data & FACING_MASK); 243} 244 245bool DispenserTile::hasAnalogOutputSignal() 246{ 247 return true; 248} 249 250int DispenserTile::getAnalogOutputSignal(Level *level, int x, int y, int z, int dir) 251{ 252 return AbstractContainerMenu::getRedstoneSignalFromContainer(dynamic_pointer_cast<Container>( level->getTileEntity(x, y, z)) ); 253}