bool BlockChest::findConnectedChest(int32_t x, int16_t y, int32_t z, int map, chestDataPtr& chest) { int32_t connectedX, connectedZ; if(findConnectedChest(x, y, z, map, &connectedX, &connectedZ)) { return getChestByCoordinates(connectedX, y, connectedZ, map, chest); } else { return false; } }
bool BlockChest::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta)) { revertBlock(user, x, y, z, map); return true; } /* Check block below allows blocks placed on top */ if (!this->isBlockStackable(oldblock)) { revertBlock(user, x, y, z, map); return true; } /* move the x,y,z coords dependent upon placement direction */ if (!this->translateDirection(&x, &y, &z, map, direction)) { revertBlock(user, x, y, z, map); return true; } if (this->isUserOnBlock(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } if (!this->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } // if there is a large chest around --> block { chestDataPtr _connectedChest; if(findConnectedChest(x, y, z, map, _connectedChest)) { if(_connectedChest->large()) { revertBlock(user, x, y, z, map); return true; } } } direction = user->relativeToBlock(x, y, z); //// Fix orientation switch (direction) { case BLOCK_EAST: //direction = BLOCK_SOUTH; break; case BLOCK_BOTTOM: direction = BLOCK_WEST; break; case BLOCK_NORTH: direction = BLOCK_TOP; break; case BLOCK_SOUTH: //direction = BLOCK_NORTH; break; } int32_t connectedChestX, connectedChestZ; if(findConnectedChest(x, y, z, map, &connectedChestX, &connectedChestZ)) { if(connectedChestX != x) { if(!(direction == 3 || direction == 2)) { direction = 3; } } if(connectedChestZ != z) { if(!(direction == 4 || direction == 5)) { direction = 4; } } ServerInstance->map(map)->setBlock(connectedChestX, y, connectedChestZ, (char)newblock, direction); ServerInstance->map(map)->sendBlockChange(connectedChestX, y, connectedChestZ, (char)newblock, direction); // create a new chest and connect it to another chest --> large chest chestDataPtr connectedChest; if(getChestByCoordinates(connectedChestX, y, connectedChestZ, map, connectedChest)) { chestDataPtr newchest; if(!getChestByCoordinates(x, y, z, map, newchest)) { sChunk* chunk = ServerInstance->map(map)->getChunk(blockToChunk(x), blockToChunk(z)); if(chunk != NULL) { newchest = chestDataPtr(new chestData); newchest->items(connectedChest->items()); newchest->x(x); newchest->y(y); newchest->z(z); chunk->chests.push_back(newchest); } } else { newchest->large(true); } connectedChest->large(true); } } else { // create a new (small) chest chestDataPtr newchest(new chestData); sChunk* chunk = ServerInstance->map(map)->getChunk(blockToChunk(x), blockToChunk(z)); if(chunk != NULL) { newchest->x(x); newchest->y(y); newchest->z(z); chunk->chests.push_back(newchest); } } ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, direction); ServerInstance->map(map)->sendBlockChange(x, y, z, (char)newblock, direction); return false; }