bool BlockSnow::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->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->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, direction); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, direction); return false; }
bool BlockPumpkin::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->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; } direction = user->relativeToBlock(x, y, z); switch (direction) { case BLOCK_EAST: direction = BLOCK_SOUTH; break; case BLOCK_BOTTOM: direction = BLOCK_EAST; break; case BLOCK_NORTH: direction = BLOCK_NORTH; break; case BLOCK_SOUTH: direction = BLOCK_BOTTOM; break; } Mineserver::get()->map(map)->setBlock(x, y, z, newblock, direction); Mineserver::get()->map(map)->sendBlockChange(x, y, z, newblock, direction); return false; }
bool BlockNote::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; } ServerInstance->map(map)->setBlock(x, y, z, BLOCK_NOTE_BLOCK, 0); ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_NOTE_BLOCK, 0); return false; }
bool BlockLiquid::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta)) 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->isBlockEmpty(x,y,z,map)) revertBlock(user,x,y,z,map); return true; direction = user->relativeToBlock(x, y, z); int block = newblock; if (block == ITEM_WATER_BUCKET) newblock = BLOCK_STATIONARY_WATER; if (block == ITEM_LAVA_BUCKET) newblock = BLOCK_STATIONARY_LAVA; Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, 0); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, 0); physics(x,y,z,map); return false; }
bool BlockStair::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction, int8_t posx, int8_t posy, int8_t posz) { 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; } int8_t relative_direction = user->relativeToBlock(x, y, z); switch(relative_direction) { case RELATIVE_SOUTH: relative_direction = 2; break; case RELATIVE_WEST: relative_direction = 1; break; case RELATIVE_NORTH: relative_direction = 3; break; case RELATIVE_EAST: relative_direction = 0; } //set upside down stair if( (direction != BLOCK_TOP && posy >= (int8_t)8) || direction == BLOCK_BOTTOM ) relative_direction ^= 4; ServerInstance->map(map)->setBlock(x, y, z, char(newblock), char(relative_direction)); ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), char(relative_direction)); return false; }
bool BlockDefault::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 (newblock > 255) { return true; } 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; } 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; } //direction = user->relativeToBlock(x, y, z); if (newblock < 256) { ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, 0); ServerInstance->map(map)->sendBlockChange(x, y, z, newblock, 0); } return false; }
bool BlockDyed::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta)) { revertBlock(user,x,y,z,map); return true; } //Combine two steps if(newblock == BLOCK_STEP && oldblock == BLOCK_STEP && direction == BLOCK_TOP) { Item item = user->inv[user->curItem+36]; if(item.getHealth() == oldmeta){ Mineserver::get()->map(map)->setBlock(x, y, z, (char)BLOCK_DOUBLE_STEP, oldmeta); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)BLOCK_DOUBLE_STEP, oldmeta); revertBlock(user,x,y,z,map); return true; }else{ 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; } 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; } Item item = user->inv[user->curItem+36]; Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, item.getHealth()); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, item.getHealth()); return false; }
bool BlockWood::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->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; } 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; } Item item = user->inv[user->curItem + 36]; Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, item.getHealth()); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, item.getHealth()); return false; }
bool BlockRedstone::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction, int8_t posx, int8_t posy, int8_t posz) { uint8_t block; uint8_t meta; if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta)) { revertBlock(user, x, y, z, map); return true; } /* Check block below allows blocks placed on top */ if (!isBlockStackable(block)) { revertBlock(user, x, y, z, map); return true; } /* move the x,y,z coords dependent upon placement direction */ if (!translateDirection(&x, &y, &z, map, direction)) { revertBlock(user, x, y, z, map); return true; } if (!isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } newblock = 55; meta = 0; ServerInstance->map(map)->setBlock(x, y, z, char(newblock), meta); ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), meta); ServerInstance->redstone(map)->addSimulation(vec(x,y,z)); return false; }
bool BlockFire::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction, int8_t posx, int8_t posy, int8_t posz) { 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; } /* burning block regardless of direction */ y++; /* FIXME: Need this or should be just let em burn? */ if (this->isUserOnBlock(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } /* if the block isn't empty then you can't burn it */ if (!this->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } direction = user->relativeToBlock(x, y, z); ServerInstance->map(map)->setBlock(x, y, z, (char)BLOCK_FIRE, 0); ServerInstance->map(map)->sendBlockChange(x, y, z, (char)BLOCK_FIRE, 0); return false; }
bool BlockSnow::onBroken(User* user, int8_t status, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t block; uint8_t meta; if (!Mineserver::get()->map(map)->getBlock(x, y, z, &block, &meta)) { revertBlock(user, x, y, z, map); return true; } Mineserver::get()->map(map)->sendBlockChange(x, y, z, BLOCK_AIR, 0); Mineserver::get()->map(map)->setBlock(x, y, z, BLOCK_AIR, 0); this->spawnBlockItem(x, y, z, map, block, meta); return false; }
bool BlockLeaves::onBroken(User* user, int8_t status, int32_t x, int16_t y, int32_t z, int map, int8_t direction) { std::set<Decay>::iterator it = std::find_if(decaying.begin(), decaying.end(), DecayFinder(x,y,z,map)); if (it != decaying.end()) decaying.erase(it); uint8_t block; uint8_t meta; if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta)) { revertBlock(user, x, y, z, map); return true; } ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_AIR, 0); ServerInstance->map(map)->setBlock(x, y, z, BLOCK_AIR, 0); this->spawnBlockItem(x, y, z, map, block, meta); return true; }
bool BlockDefault::onBroken(User* user, int8_t status, int32_t x, int16_t y, int32_t z, int map, int8_t direction) { uint8_t block; uint8_t meta; if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta)) { revertBlock(user, x, y, z, map); return true; } if (block != BLOCK_WOOL && block != BLOCK_LOG && block != BLOCK_STEP) { // Only Cloth, Wood and Step have colour metadata meta = 0; } ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_AIR, 0); ServerInstance->map(map)->setBlock(x, y, z, BLOCK_AIR, 0); this->spawnBlockItem(x, y, z, map, block, meta); 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; }
bool BlockTorch::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->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } if (direction == 0) { if (ServerInstance->map(map)->getBlock(x+1, y, z, &oldblock, &oldmeta) && oldblock != BLOCK_AIR) { direction = 2; } else if (ServerInstance->map(map)->getBlock(x, y, z+1, &oldblock, &oldmeta) && oldblock != BLOCK_AIR) { direction = 4; } else if (ServerInstance->map(map)->getBlock(x-1, y, z, &oldblock, &oldmeta) && oldblock != BLOCK_AIR) { direction = 1; } else if (ServerInstance->map(map)->getBlock(x, y, z-1, &oldblock, &oldmeta) && oldblock != BLOCK_AIR) { direction = 3; } else { direction = 5; } } ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, direction); ServerInstance->map(map)->sendBlockChange(x, y, z, (char)newblock, direction); if(newblock == BLOCK_REDSTONE_TORCH_OFF || newblock == BLOCK_REDSTONE_TORCH_ON) { ServerInstance->redstone(map)->addSimulation(vec(x,y,z)); } return false; }
bool BlockFurnace::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->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; } direction = user->relativeToBlock(x, y, z); // Fix orientation //switch (direction) //{ //case BLOCK_EAST: // direction = BLOCK_SOUTH; // break; //case BLOCK_BOTTOM: // direction = BLOCK_EAST; // break; //case BLOCK_NORTH: // direction = BLOCK_NORTH; // break; //case BLOCK_SOUTH: // direction = BLOCK_BOTTOM; // break; //} Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, direction); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, direction); int chunk_x = blockToChunk(x); int chunk_z = blockToChunk(z); sChunk* chunk = Mineserver::get()->map(map)->loadMap(chunk_x, chunk_z); if (chunk == NULL) { revertBlock(user, x, y, z, map); } return true; for (uint32_t i = 0; i < chunk->furnaces.size(); i++) { if (chunk->furnaces[i]->x == x && chunk->furnaces[i]->y == y && chunk->furnaces[i]->z == z) { chunk->furnaces.erase(chunk->furnaces.begin() + i); break; } } return false; }
bool BlockPlant::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; /* 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 (!ServerInstance->map(map)->getBlock(x, y - 1, z, &oldblock, &oldmeta)) { revertBlock(user, x, y, z, map); return true; } if (newblock != BLOCK_DIRT && newblock != BLOCK_SOIL && newblock != BLOCK_GRASS) { if (this->isBlockEmpty(x, y - 1, z, map) || !this->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } if (!this->isBlockStackable(oldblock)) { revertBlock(user, x, y, z, map); return true; } } else { if (this->isUserOnBlock(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } } if ((newblock == BLOCK_REED || newblock == ITEM_REED) && (oldblock == BLOCK_GRASS || oldblock == BLOCK_DIRT)) { // TODO : Check for water ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_REED, 0); ServerInstance->map(map)->setBlock(x, y, z, BLOCK_REED, 0); addBlock(x, y, z, map); return false; } if (newblock == BLOCK_CACTUS && oldblock != BLOCK_SAND) { revertBlock(user, x, y, z, map); return true; } if ((newblock == BLOCK_YELLOW_FLOWER || newblock == BLOCK_RED_ROSE) && (oldblock != BLOCK_DIRT && oldblock != BLOCK_GRASS)) { revertBlock(user, x, y, z, map); return true; } if ((newblock == ITEM_SEEDS || newblock == BLOCK_CROPS) && (oldblock == BLOCK_SOIL)) { ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_CROPS, 0); ServerInstance->map(map)->setBlock(x, y, z, BLOCK_CROPS, 0); addBlock(x, y, z, map); return false; } if ((newblock == ITEM_SEEDS || newblock == BLOCK_CROPS)) { revertBlock(user, x, y, z, map); return true; } if (newblock > 255 && (oldblock == BLOCK_DIRT || oldblock == BLOCK_GRASS)) { // Hoe on dirt = Soil ServerInstance->map(map)->sendBlockChange(x, y - 1, z, BLOCK_SOIL, 0); ServerInstance->map(map)->setBlock(x, y - 1, z, BLOCK_SOIL, 0); if (SEEDS_CHANCE >= rand() % 10000) { ServerInstance->map(map)->createPickupSpawn(x, y + 1, z, ITEM_SEEDS, 1, 0, nullptr); } return true; } if (newblock > 255) { revertBlock(user, x, y, z, map); return true; } if ((newblock == BLOCK_BROWN_MUSHROOM || newblock == BLOCK_RED_MUSHROOM) && oldblock != BLOCK_DIRT) { revertBlock(user, x, y, z, map); return true; } if (newblock == BLOCK_SAPLING) { ServerInstance->map(map)->addSapling(user, x, y, z); } else { ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), 0); ServerInstance->map(map)->setBlock(x, y, z, char(newblock), 0); addBlocks(x, y, z, map); } return false; }
bool BlockTracks::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction) { uint8_t block; uint8_t meta; if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta)) { revertBlock(user, x, y, z, map); return true; } /* Check block below allows blocks placed on top */ if (!this->isBlockStackable(block)) { 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->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } uint8_t metadata = FLAT_NS; uint8_t elevoftrack = 2; // WEST of placed track if (searchTrack(x + 1, y, z, map, meta) != 2 && isStartPiece(x + 1, y, z, map)) { LOG(INFO, "Tracks", "WEST"); metadata = FLAT_EW; elevoftrack = searchTrack(x + 1, y, z, map, meta); if (meta == FLAT_NS && elevoftrack == 0) { ServerInstance->map(map)->setBlock(x + 1, y, z, (char)newblock, FLAT_EW); ServerInstance->map(map)->sendBlockChange(x + 1, y, z, (char)newblock, FLAT_EW); } // Rising & falling tracks if (isTrack(x + 1, y + 1, z, map, meta) && isStartPiece(x + 1, y + 1, z, map)) // Rising & falling tracks { metadata = ASCEND_W; } else if (isTrack(x + 1, y - 1, z, map, meta) && isStartPiece(x + 1, y - 1, z, map)) // Rising & falling tracks { ServerInstance->map(map)->setBlock(x + 1, y - 1, z, (char)newblock, ASCEND_E); ServerInstance->map(map)->sendBlockChange(x + 1, y - 1, z, (char)newblock, ASCEND_E); } // Change previous track, Turns if (searchTrack(x + 1, y, z - 1, map, meta) != 2 && isStartPiece(x + 1, y, z, map) && meta != FLAT_EW) // Left { ServerInstance->map(map)->setBlock(x + 1, y + elevoftrack, z, (char)newblock, CORNER_NW); ServerInstance->map(map)->sendBlockChange(x + 1, y + elevoftrack, z, (char)newblock, CORNER_NW); } if (searchTrack(x + 1, y, z + 1, map, meta) != 2 && isStartPiece(x + 1, y, z, map) && meta != FLAT_EW) // Right { ServerInstance->map(map)->setBlock(x + 1, y + elevoftrack, z, (char)newblock, CORNER_SW); ServerInstance->map(map)->sendBlockChange(x + 1, y + elevoftrack, z, (char)newblock, CORNER_SW); } // Make track you just placed a corner if (isTrack(x, y, z - 1, map, meta) && isStartPiece(x, y, z - 1, map)) { metadata = CORNER_NE; } if (isTrack(x, y, z + 1, map, meta) && isStartPiece(x, y, z + 1, map)) { metadata = CORNER_SE; } } // EAST of placed track else if (searchTrack(x - 1, y, z, map, meta) != 2 && isStartPiece(x - 1, y, z, map)) { LOG(INFO, "Tracks", "EAST"); metadata = FLAT_EW; elevoftrack = searchTrack(x - 1, y, z, map, meta); if (meta == FLAT_NS && elevoftrack == 0) { ServerInstance->map(map)->setBlock(x - 1, y, z, (char)newblock, FLAT_EW); ServerInstance->map(map)->sendBlockChange(x - 1, y, z, (char)newblock, FLAT_EW); } // Rising & falling tracks if (isTrack(x - 1, y + 1, z, map, meta) && isStartPiece(x - 1, y + 1, z, map)) { metadata = ASCEND_E; if (meta != ASCEND_E || meta != CORNER_NW || meta != CORNER_SW) { ServerInstance->map(map)->setBlock(x - 1, y + 1, z, (char)newblock, FLAT_EW); ServerInstance->map(map)->sendBlockChange(x - 1, y + 1, z, (char)newblock, FLAT_EW); } } else if (isTrack(x - 1, y - 1, z, map, meta) && isStartPiece(x - 1, y - 1, z, map)) { ServerInstance->map(map)->setBlock(x - 1, y - 1, z, (char)newblock, ASCEND_W); ServerInstance->map(map)->sendBlockChange(x - 1, y - 1, z, (char)newblock, ASCEND_W); } // Change previous track, Turns if (searchTrack(x - 1, y, z - 1, map, meta) != 2 && isStartPiece(x - 1, y, z, map) && meta != FLAT_EW) // Right { ServerInstance->map(map)->setBlock(x - 1, y + elevoftrack, z, (char)newblock, CORNER_NE); ServerInstance->map(map)->sendBlockChange(x - 1, y + elevoftrack, z, (char)newblock, CORNER_NE); } if (searchTrack(x - 1, y, z + 1, map, meta) != 2 && isStartPiece(x - 1, y, z, map) && meta != FLAT_EW) // Left { ServerInstance->map(map)->setBlock(x - 1, y + elevoftrack, z, (char)newblock, CORNER_SE); ServerInstance->map(map)->sendBlockChange(x - 1, y + elevoftrack, z, (char)newblock, CORNER_SE); } // Make track you just placed a corner if (isTrack(x, y, z - 1, map, meta) && isStartPiece(x, y, z - 1, map)) { metadata = CORNER_NW; } if (isTrack(x, y, z + 1, map, meta) && isStartPiece(x, y, z + 1, map)) { metadata = CORNER_SW; } } // SOUTH of placed track else if (searchTrack(x, y, z - 1, map, meta) != 2 && isStartPiece(x, y, z - 1, map)) { LOG(INFO, "Tracks", "SOUTH"); metadata = FLAT_NS; elevoftrack = searchTrack(x, y, z - 1, map, meta); // Elevation of found track if (meta == FLAT_EW && elevoftrack == 0) { ServerInstance->map(map)->setBlock(x, y, z - 1, (char)newblock, FLAT_NS); ServerInstance->map(map)->sendBlockChange(x, y, z - 1, (char)newblock, FLAT_NS); } // Rising & falling tracks if (isTrack(x, y + 1, z - 1, map, meta) && isStartPiece(x, y + 1, z - 1, map)) // Rising & falling tracks { metadata = ASCEND_S; } else if (isTrack(x, y - 1, z - 1, map, meta) && isStartPiece(x, y - 1, z - 1, map)) // Rising & falling tracks { ServerInstance->map(map)->setBlock(x, y - 1, z - 1, (char)newblock, ASCEND_N); ServerInstance->map(map)->sendBlockChange(x, y - 1, z - 1, (char)newblock, ASCEND_N); } // Change previous track, Turns if (searchTrack(x - 1, y, z - 1, map, meta) != 2 && isStartPiece(x, y, z - 1, map) && meta != FLAT_NS) // Left { ServerInstance->map(map)->setBlock(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SW); ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SW); } if (searchTrack(x + 1, y, z - 1, map, meta) != 2 && isStartPiece(x, y, z - 1, map) && meta != FLAT_NS) // Right { ServerInstance->map(map)->setBlock(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SE); ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SE); } // Make track you just placed a corner if (isTrack(x + 1, y, z, map, meta) && isStartPiece(x + 1, y, z, map)) { metadata = CORNER_NE; } if (isTrack(x - 1, y, z, map, meta) && isStartPiece(x - 1, y, z, map)) { metadata = CORNER_NW; } } // NORTH of placed track else if (searchTrack(x, y, z + 1, map, meta) != 2 && isStartPiece(x, y, z + 1, map)) { LOG(INFO, "Tracks", "NORTH"); metadata = FLAT_NS; elevoftrack = searchTrack(x, y, z + 1, map, meta); if (meta == FLAT_EW && elevoftrack == 0) { ServerInstance->map(map)->setBlock(x, y, z + 1, (char)newblock, FLAT_NS); ServerInstance->map(map)->sendBlockChange(x, y, z + 1, (char)newblock, FLAT_NS); } // Rising & falling tracks if (isTrack(x, y - 1, z + 1, map, meta) && isStartPiece(x, y - 1, z + 1, map)) // Rising & falling tracks { ServerInstance->map(map)->setBlock(x, y - 1, z + 1, (char)newblock, ASCEND_S); ServerInstance->map(map)->sendBlockChange(x, y - 1, z + 1, (char)newblock, ASCEND_S); } else if (isTrack(x, y + 1, z + 1, map, meta) && isStartPiece(x, y + 1, z + 1, map)) // Rising & falling tracks { metadata = ASCEND_N; } // Change previous track, Turns if (searchTrack(x + 1, y, z + 1, map, meta) != 2 && isStartPiece(x, y, z + 1, map) && meta != FLAT_NS) // Left { ServerInstance->map(map)->setBlock(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NE); ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NE); } if (searchTrack(x - 1, y, z + 1, map, meta) != 2 && isStartPiece(x, y, z + 1, map) && meta != FLAT_NS) // Right { ServerInstance->map(map)->setBlock(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NW); ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NW); } // Make track you just placed a corner if (isTrack(x + 1, y, z, map, meta) && isStartPiece(x + 1, y, z, map)) { metadata = CORNER_SE; } if (isTrack(x - 1, y, z, map, meta) && isStartPiece(x - 1, y, z, map)) { metadata = CORNER_SW; } } ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, metadata); ServerInstance->map(map)->sendBlockChange(x, y, z, (char)newblock, metadata); return false; }
bool BlockSign::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; if (!Mineserver::get()->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; } // 0x0 -> West West West West // 0x1 -> West West West North // 0x2 -> West West North North // 0x3 -> West North North North // 0x4 -> North North North North // 0x5 -> North North North East // 0x6 -> North North East East // 0x7 -> North East East East // 0x8 -> East East East East // 0x9 -> East East East South // 0xA -> East East South South // 0xB -> East South South South // 0xC -> South South South South // 0xD -> South South South West // 0xE -> South South West West // 0xF -> South West West West // The values were the signs are facing // // North // // -X | 4 // | 3 5 // | 2 6 // | 1 [=] 7 // West | 0 | 8 East // | F 9 // | E A // | D B // +X | C // ---------------------------------- // +Z -Z // // South // Were it should be placed depending on the user's position // // North // // -X | C // | B D // | A o E // | 9 [ ] F // West | 8 | | 0 East // | 7 1 // | 6 2 // | 5 3 // +X | 4 // ---------------------------------- // +Z -Z // // South // We place according to the player's position double diffX = (x + 0.5) - user->pos.x; // + 0.5 to get the middle of the square double diffZ = (z + 0.5) - user->pos.z; // + 0.5 to get the middle of the square double angleDegree = ((atan2(diffZ, diffX) * 180 / M_PI + 90) / 22.5); uint8_t metadata; if (angleDegree < 0) { angleDegree += 16; } newblock = BLOCK_WALL_SIGN; metadata = 6 - direction; switch (direction) { case BLOCK_SOUTH: x--; break; case BLOCK_NORTH: x++; break; case BLOCK_EAST: z++; break; case BLOCK_WEST: z--; break; case BLOCK_TOP: y++; newblock = BLOCK_SIGN_POST; metadata = (uint8_t)(angleDegree + 0.5); break; case BLOCK_BOTTOM: default: revertBlock(user, x, y, z, map); return true; break; } if (!this->isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, metadata); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, metadata); return false; }
bool BlockRedstoneUtil::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction) { uint8_t block; uint8_t meta = 0; if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta)) { revertBlock(user, x, y, z, map); return true; } /* Check block below allows blocks placed on top */ if (!isBlockStackable(block)) { revertBlock(user, x, y, z, map); return true; } /* move the x,y,z coords dependent upon placement direction */ if (!translateDirection(&x, &y, &z, map, direction)) { revertBlock(user, x, y, z, map); return true; } if (!isBlockEmpty(x, y, z, map)) { revertBlock(user, x, y, z, map); return true; } // Check that switch is placed on legal direction if ((newblock == BLOCK_STONE_BUTTON && (direction == BLOCK_TOP || direction == BLOCK_BOTTOM)) || ((newblock == BLOCK_STONE_PRESSURE_PLATE || newblock == BLOCK_WOODEN_PRESSURE_PLATE) && direction != BLOCK_TOP)) { revertBlock(user, x, y, z, map); return true; } // Set metadata for the position if (newblock == BLOCK_STONE_BUTTON || newblock == BLOCK_LEVER) { // Wall switch if (direction != BLOCK_TOP && direction != BLOCK_BOTTOM) { meta = direction; } // Ceiling lever else if (direction == BLOCK_BOTTOM) { int yaw = abs(int(user->pos.yaw)) % 360; if ((yaw > 45 && yaw <= 135) || (yaw > 225 && yaw <= 315)) { meta = 0x00; } else { meta = 0x07; } } // Floor lever else { int yaw = abs(int(user->pos.yaw)) % 360; if ((yaw > 45 && yaw <= 135) || (yaw > 225 && yaw <= 315)) { meta = 0x06; } else { meta = 0x05; } } } ServerInstance->map(map)->setBlock(x, y, z, char(newblock), meta); ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), meta); return false; }
bool BlockBed::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction) { uint8_t oldblock; uint8_t oldmeta; int zMod = 0, xMod = 0; if (!Mineserver::get()->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; } // checking for an item rather then a block if (newblock == ITEM_BED) { newblock = BLOCK_BED; } direction = user->relativeToBlock(x, y, z); switch (direction) { case BLOCK_EAST: direction = BLOCK_SOUTH; zMod = -1; xMod = 0; break; case BLOCK_BOTTOM: direction = BLOCK_EAST; zMod = 0; xMod = +1; break; case BLOCK_NORTH: direction = BLOCK_NORTH; zMod = 0; xMod = -1; break; case BLOCK_SOUTH: direction = BLOCK_BOTTOM; zMod = +1; xMod = 0; break; } Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, direction); Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, direction); // set head of the bed direction ^= 8; Mineserver::get()->map(map)->setBlock(x + xMod, y, z + zMod, (char)newblock, direction); Mineserver::get()->map(map)->sendBlockChange(x + xMod, y, z + zMod, (char)newblock, direction); return false; }