the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 414 lines 9.6 kB view raw
1#include "stdafx.h" 2#include "com.mojang.nbt.h" 3#include "net.minecraft.h" 4#include "net.minecraft.world.entity.player.h" 5#include "net.minecraft.world.item.h" 6#include "net.minecraft.world.item.crafting.h" 7#include "net.minecraft.world.level.h" 8#include "net.minecraft.world.level.tile.h" 9#include "Material.h" 10#include "FurnaceTileEntity.h" 11 12int furnaceSlotsForUp [] = { FurnaceTileEntity::SLOT_INPUT }; 13int furnaceSlotsForDown [] = { FurnaceTileEntity::SLOT_RESULT, FurnaceTileEntity::SLOT_FUEL }; 14int furnaceSlotsForSides [] = { FurnaceTileEntity::SLOT_FUEL }; 15 16const intArray FurnaceTileEntity::SLOTS_FOR_UP = intArray(furnaceSlotsForUp, 1); 17const intArray FurnaceTileEntity::SLOTS_FOR_DOWN = intArray(furnaceSlotsForDown, 2); 18const intArray FurnaceTileEntity::SLOTS_FOR_SIDES = intArray(furnaceSlotsForSides, 1); 19 20const int FurnaceTileEntity::BURN_INTERVAL = 10 * 20; 21 22// 4J Stu - Need a ctor to initialise member variables 23FurnaceTileEntity::FurnaceTileEntity() : TileEntity() 24{ 25 items = ItemInstanceArray(3); 26 27 litTime = 0; 28 litDuration = 0; 29 tickCount = 0; 30 m_charcoalUsed = false; 31 name = L""; 32} 33 34FurnaceTileEntity::~FurnaceTileEntity() 35{ 36 delete[] items.data; 37} 38 39 40unsigned int FurnaceTileEntity::getContainerSize() 41{ 42 return items.length; 43} 44 45 46shared_ptr<ItemInstance> FurnaceTileEntity::getItem(unsigned int slot) 47{ 48 return items[slot]; 49} 50 51 52shared_ptr<ItemInstance> FurnaceTileEntity::removeItem(unsigned int slot, int count) 53{ 54 m_charcoalUsed = false; 55 56 if (items[slot] != NULL) 57 { 58 if (items[slot]->count <= count) 59 { 60 shared_ptr<ItemInstance> item = items[slot]; 61 items[slot] = nullptr; 62 // 4J Stu - Fix for duplication glitch 63 if(item->count <= 0) return nullptr; 64 return item; 65 } 66 else 67 { 68 shared_ptr<ItemInstance> i = items[slot]->remove(count); 69 if (items[slot]->count == 0) items[slot] = nullptr; 70 // 4J Stu - Fix for duplication glitch 71 if(i->count <= 0) return nullptr; 72 return i; 73 } 74 } 75 return nullptr; 76} 77 78shared_ptr<ItemInstance> FurnaceTileEntity::removeItemNoUpdate(int slot) 79{ 80 m_charcoalUsed = false; 81 82 if (items[slot] != NULL) 83 { 84 shared_ptr<ItemInstance> item = items[slot]; 85 items[slot] = nullptr; 86 return item; 87 } 88 return nullptr; 89} 90 91 92void FurnaceTileEntity::setItem(unsigned int slot, shared_ptr<ItemInstance> item) 93{ 94 items[slot] = item; 95 if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize(); 96} 97 98 99wstring FurnaceTileEntity::getName() 100{ 101 return hasCustomName() ? name : app.GetString(IDS_TILE_FURNACE); 102} 103 104wstring FurnaceTileEntity::getCustomName() 105{ 106 return hasCustomName() ? name : L""; 107} 108 109bool FurnaceTileEntity::hasCustomName() 110{ 111 return !name.empty(); 112} 113 114void FurnaceTileEntity::setCustomName(const wstring &name) 115{ 116 this->name = name; 117} 118 119void FurnaceTileEntity::load(CompoundTag *base) 120{ 121 TileEntity::load(base); 122 ListTag<CompoundTag> *inventoryList = (ListTag<CompoundTag> *) base->getList(L"Items"); 123 delete[] items.data; 124 items = ItemInstanceArray(getContainerSize()); 125 for (int i = 0; i < inventoryList->size(); i++) 126 { 127 CompoundTag *tag = inventoryList->get(i); 128 unsigned int slot = tag->getByte(L"Slot"); 129 if (slot >= 0 && slot < items.length) items[slot] = ItemInstance::fromTag(tag); 130 } 131 132 litTime = base->getShort(L"BurnTime"); 133 tickCount = base->getShort(L"CookTime"); 134 litDuration = getBurnDuration(items[SLOT_FUEL]); 135 if (base->contains(L"CustomName")) name = base->getString(L"CustomName"); 136 m_charcoalUsed = base->getBoolean(L"CharcoalUsed"); 137} 138 139 140void FurnaceTileEntity::save(CompoundTag *base) 141{ 142 TileEntity::save(base); 143 base->putShort(L"BurnTime", (short) (litTime)); 144 base->putShort(L"CookTime", (short) (tickCount)); 145 ListTag<CompoundTag> *listTag = new ListTag<CompoundTag>(); 146 147 for (unsigned int i = 0; i < items.length; i++) 148 { 149 if (items[i] != NULL) 150 { 151 CompoundTag *tag = new CompoundTag(); 152 tag->putByte(L"Slot", (byte) i); 153 items[i]->save(tag); 154 listTag->add(tag); 155 } 156 } 157 base->put(L"Items", listTag); 158 if (hasCustomName()) base->putString(L"CustomName", name); 159 base->putBoolean(L"CharcoalUsed", m_charcoalUsed); 160} 161 162 163int FurnaceTileEntity::getMaxStackSize() const 164{ 165 return Container::LARGE_MAX_STACK_SIZE; 166} 167 168 169int FurnaceTileEntity::getBurnProgress(int max) 170{ 171 return tickCount * max / BURN_INTERVAL; 172} 173 174 175int FurnaceTileEntity::getLitProgress(int max) 176{ 177 if (litDuration == 0) litDuration = BURN_INTERVAL; 178 return litTime * max / litDuration; 179} 180 181 182bool FurnaceTileEntity::isLit() 183{ 184 return litTime > 0; 185} 186 187 188void FurnaceTileEntity::tick() 189{ 190 bool wasLit = litTime > 0; 191 bool changed = false; 192 if (litTime > 0) 193 { 194 litTime--; 195 } 196 197 if ( level != NULL && !level->isClientSide) 198 { 199 if (litTime == 0 && canBurn()) 200 { 201 litDuration = litTime = getBurnDuration(items[SLOT_FUEL]); 202 if (litTime > 0) 203 { 204 changed = true; 205 if (items[SLOT_FUEL] != NULL) 206 { 207 // 4J Added: Keep track of whether charcoal was used in production of current stack. 208 if ( items[SLOT_FUEL]->getItem()->id == Item::coal_Id 209 && items[SLOT_FUEL]->getAuxValue() == CoalItem::CHAR_COAL) 210 { 211 m_charcoalUsed = true; 212 } 213 214 items[SLOT_FUEL]->count--; 215 if (items[SLOT_FUEL]->count == 0) 216 { 217 Item *remaining = items[SLOT_FUEL]->getItem()->getCraftingRemainingItem(); 218 items[SLOT_FUEL] = remaining != NULL ? shared_ptr<ItemInstance>(new ItemInstance(remaining)) : nullptr; 219 } 220 } 221 } 222 } 223 224 if (isLit() && canBurn()) 225 { 226 tickCount++; 227 if (tickCount == BURN_INTERVAL) 228 { 229 tickCount = 0; 230 burn(); 231 changed = true; 232 } 233 } 234 else 235 { 236 tickCount = 0; 237 } 238 239 if (wasLit != litTime > 0) 240 { 241 changed = true; 242 FurnaceTile::setLit(litTime > 0, level, x, y, z); 243 } 244 } 245 246 if (changed) setChanged(); 247} 248 249 250bool FurnaceTileEntity::canBurn() 251{ 252 if (items[SLOT_INPUT] == NULL) return false; 253 const ItemInstance *burnResult = FurnaceRecipes::getInstance()->getResult(items[SLOT_INPUT]->getItem()->id); 254 if (burnResult == NULL) return false; 255 if (items[SLOT_RESULT] == NULL) return true; 256 if (!items[SLOT_RESULT]->sameItem_not_shared(burnResult)) return false; 257 if (items[SLOT_RESULT]->count < getMaxStackSize() && items[SLOT_RESULT]->count < items[SLOT_RESULT]->getMaxStackSize()) return true; 258 if (items[SLOT_RESULT]->count < burnResult->getMaxStackSize()) return true; 259 return false; 260} 261 262 263void FurnaceTileEntity::burn() 264{ 265 if (!canBurn()) return; 266 267 const ItemInstance *result = FurnaceRecipes::getInstance()->getResult(items[SLOT_INPUT]->getItem()->id); 268 if (items[SLOT_RESULT] == NULL) items[SLOT_RESULT] = result->copy(); 269 else if (items[SLOT_RESULT]->id == result->id) items[SLOT_RESULT]->count++; 270 271 items[SLOT_INPUT]->count--; 272 if (items[SLOT_INPUT]->count <= 0) items[SLOT_INPUT] = nullptr; 273} 274 275 276int FurnaceTileEntity::getBurnDuration(shared_ptr<ItemInstance> itemInstance) 277{ 278 if (itemInstance == NULL) return 0; 279 int id = itemInstance->getItem()->id; 280 281 Item *item = itemInstance->getItem(); 282 283 if (id < 256 && Tile::tiles[id] != NULL) 284 { 285 Tile *tile = Tile::tiles[id]; 286 287 if (tile == Tile::woodSlabHalf) 288 { 289 return BURN_INTERVAL * 3 / 4; 290 } 291 292 if (tile->material == Material::wood) 293 { 294 return BURN_INTERVAL * 3 / 2; 295 } 296 297 if (tile == Tile::coalBlock) 298 { 299 return BURN_INTERVAL * 8 * 10; 300 } 301 } 302 303 if (dynamic_cast<DiggerItem *>(item) && ((DiggerItem *) item)->getTier() == Item::Tier::WOOD) 304 { 305 return BURN_INTERVAL; 306 } 307 else if (dynamic_cast<WeaponItem *>(item) && ((WeaponItem *) item)->getTier() == Item::Tier::WOOD) 308 { 309 return BURN_INTERVAL; 310 } 311 else if (dynamic_cast<HoeItem *>(item) && ((HoeItem *) item)->getTier() == Item::Tier::WOOD) 312 { 313 return BURN_INTERVAL; 314 } 315 316 if (id == Item::stick->id) 317 { 318 return BURN_INTERVAL / 2; 319 } 320 321 if (id == Item::coal->id) return BURN_INTERVAL * 8; 322 323 if (id == Item::bucket_lava->id) return BURN_INTERVAL * 100; 324 325 if (id == Tile::sapling_Id) return BURN_INTERVAL / 2; 326 327 if (id == Item::blazeRod_Id) return BURN_INTERVAL * 12; 328 329 return 0; 330} 331 332bool FurnaceTileEntity::isFuel(shared_ptr<ItemInstance> item) 333{ 334 return getBurnDuration(item) > 0; 335} 336 337bool FurnaceTileEntity::stillValid(shared_ptr<Player> player) 338{ 339 if (level->getTileEntity(x, y, z) != shared_from_this() ) return false; 340 if (player->distanceToSqr(x + 0.5, y + 0.5, z + 0.5) > 8 * 8) return false; 341 return true; 342} 343 344void FurnaceTileEntity::setChanged() 345{ 346 return TileEntity::setChanged(); 347} 348 349void FurnaceTileEntity::startOpen() 350{ 351} 352 353void FurnaceTileEntity::stopOpen() 354{ 355} 356 357bool FurnaceTileEntity::canPlaceItem(int slot, shared_ptr<ItemInstance> item) 358{ 359 if (slot == SLOT_RESULT) return false; 360 if (slot == SLOT_FUEL) return isFuel(item); 361 return true; 362} 363 364intArray FurnaceTileEntity::getSlotsForFace(int face) 365{ 366 if (face == Facing::DOWN) 367 { 368 return SLOTS_FOR_DOWN; 369 } 370 else if (face == Facing::UP) 371 { 372 return SLOTS_FOR_UP; 373 } 374 else 375 { 376 return SLOTS_FOR_SIDES; 377 } 378} 379 380bool FurnaceTileEntity::canPlaceItemThroughFace(int slot, shared_ptr<ItemInstance> item, int face) 381{ 382 return canPlaceItem(slot, item); 383 384} 385 386bool FurnaceTileEntity::canTakeItemThroughFace(int slot, shared_ptr<ItemInstance> item, int face) 387{ 388 if (face == Facing::DOWN && slot == SLOT_FUEL) 389 { 390 if (item->id != Item::bucket_empty_Id) return false; 391 } 392 393 return true; 394} 395 396// 4J Added 397shared_ptr<TileEntity> FurnaceTileEntity::clone() 398{ 399 shared_ptr<FurnaceTileEntity> result = shared_ptr<FurnaceTileEntity>( new FurnaceTileEntity() ); 400 TileEntity::clone(result); 401 402 result->litTime = litTime; 403 result->tickCount = tickCount; 404 result->litDuration = litDuration; 405 406 for (unsigned int i = 0; i < items.length; i++) 407 { 408 if (items[i] != NULL) 409 { 410 result->items[i] = ItemInstance::clone(items[i]); 411 } 412 } 413 return result; 414}