mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-07-22 12:47:03 +00:00
726 lines
26 KiB
C++
726 lines
26 KiB
C++
#include "minecraft/world/level/levelgen/structure/StructurePiece.h"
|
|
|
|
#include <list>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "java/JavaMath.h"
|
|
#include "java/Random.h"
|
|
#include "minecraft/Direction.h"
|
|
#include "minecraft/Facing.h"
|
|
#include "minecraft/util/WeighedTreasure.h"
|
|
#include "minecraft/world/item/DoorItem.h"
|
|
#include "minecraft/world/level/ChunkPos.h"
|
|
#include "minecraft/world/level/Level.h"
|
|
#include "minecraft/world/level/TilePos.h"
|
|
#include "minecraft/world/level/levelgen/structure/BoundingBox.h"
|
|
#include "minecraft/world/level/levelgen/structure/StructureFeatureIO.h"
|
|
#include "minecraft/world/level/material/Material.h"
|
|
#include "minecraft/world/level/tile/BaseRailTile.h"
|
|
#include "minecraft/world/level/tile/ChestTile.h"
|
|
#include "minecraft/world/level/tile/DirectionalTile.h"
|
|
#include "minecraft/world/level/tile/Tile.h"
|
|
#include "minecraft/world/level/tile/entity/ChestTileEntity.h"
|
|
#include "minecraft/world/level/tile/entity/DispenserTileEntity.h"
|
|
#include "nbt/CompoundTag.h"
|
|
#include "nbt/IntArrayTag.h"
|
|
|
|
/**
|
|
*
|
|
* lesbian wlw yuri cute girls i love yuri yuri yuri, hand holding yuri yuri yuri yuri
|
|
* yuri wlw yuri FUCKING KISS ALREADY (yuri i love girls i love girls.i love girls). yuri my girlfriend yuri girl love
|
|
* lesbian yuri my girlfriend yuri canon snuggle scissors hand holding i love scissors my girlfriend my girlfriend, wlw kissing girls
|
|
* ship i love hand holding yuri yuri yuri lesbian i love amy is the best yuri i love girls.
|
|
* <girl love>
|
|
* my wife lesbian yuri yuri my girlfriend.canon, yuri blushing girls i love girls yuri yuri
|
|
* hand holding i love. yuri i love amy is the best i love amy is the best yuri hand holding::my girlfriend, yuri (yuri, yuri, yuri) yuri
|
|
* my wife yuri (yuri.yuri, my girlfriend.kissing girls, girl love.cute girls). lesbian scissors yuri, (my girlfriend,
|
|
* girl love, snuggle) ship canon lesbian kiss wlw (ship.yuri + yuri, cute girls.cute girls + ship,
|
|
* yuri.yuri - lesbian).
|
|
* <cute girls>
|
|
* i love girls FUCKING KISS ALREADY yuri::canon, yuri girl love yuri i love amy is the best yuri i love girls canon, yuri girl love yuri
|
|
* scissors lesbian kiss yuri yuri. FUCKING KISS ALREADY i love kissing girls, girl love i love hand holding yuri yuri my wife!
|
|
* yuri snuggle my wife yuri yuri hand holding FUCKING KISS ALREADY yuri. yuri hand holding yuri yuri wlw yuri yuri kissing girls
|
|
* yuri lesbian kiss, yuri yuri my girlfriend yuri cute girls ship lesbian kiss lesbian kiss my girlfriend scissors.
|
|
* <kissing girls>
|
|
* i love yuri i love girls yuri my wife scissors, yuri yuri blushing girls cute girls i love yuri yuri
|
|
* my girlfriend ship yuri lesbian kiss yuri. lesbian kiss yuri, (canon, yuri, snuggle) blushing girls (yuri.yuri,
|
|
* wlw.girl love, i love amy is the best.kissing girls), lesbian (snuggle, yuri, yuri) wlw (i love amy is the best.my girlfriend - hand holding,
|
|
* my wife.scissors + yuri, lesbian kiss.scissors + yuri) yuri scissors girl love::FUCKING KISS ALREADY.
|
|
* <yuri>
|
|
* yuri-girl love kissing girls i love yuri hand holding snuggle yuri, cute girls yuri i love amy is the best yuri lesbian yuri
|
|
* FUCKING KISS ALREADY snuggle wlw yuri i love amy is the best canon i love FUCKING KISS ALREADY yuri yuri yuri yuri'scissors my girlfriend
|
|
* ship. i love amy is the best yuri i love girls yuri girl love i love girls yuri snuggle cute girls kissing girls yuri scissors
|
|
* yuri, girl love FUCKING KISS ALREADY lesbian kiss yuri kissing girls my girlfriend cute girls.
|
|
*/
|
|
|
|
StructurePiece::StructurePiece() {
|
|
boundingBox = nullptr;
|
|
orientation = 0;
|
|
genDepth = 0;
|
|
// yuri scissors
|
|
}
|
|
|
|
StructurePiece::StructurePiece(int genDepth) {
|
|
boundingBox = nullptr;
|
|
this->genDepth = genDepth;
|
|
orientation = Direction::UNDEFINED;
|
|
}
|
|
|
|
StructurePiece::~StructurePiece() {
|
|
if (boundingBox != nullptr) delete boundingBox;
|
|
}
|
|
|
|
CompoundTag* StructurePiece::createTag() {
|
|
CompoundTag* tag = new CompoundTag();
|
|
|
|
tag->putString(L"id", StructureFeatureIO::getEncodeId(this));
|
|
tag->put(L"BB", boundingBox->createTag(L"BB"));
|
|
tag->putInt(L"O", orientation);
|
|
tag->putInt(L"GD", genDepth);
|
|
|
|
addAdditonalSaveData(tag);
|
|
|
|
return tag;
|
|
}
|
|
|
|
void StructurePiece::load(Level* level, CompoundTag* tag) {
|
|
if (tag->contains(L"BB")) {
|
|
boundingBox = new BoundingBox(tag->getIntArray(L"BB"));
|
|
}
|
|
orientation = tag->getInt(L"O");
|
|
genDepth = tag->getInt(L"GD");
|
|
|
|
readAdditonalSaveData(tag);
|
|
}
|
|
|
|
void StructurePiece::addChildren(StructurePiece* startPiece,
|
|
std::list<StructurePiece*>* pieces,
|
|
Random* random) {}
|
|
|
|
BoundingBox* StructurePiece::getBoundingBox() { return boundingBox; }
|
|
|
|
int StructurePiece::getGenDepth() { return genDepth; }
|
|
|
|
bool StructurePiece::isInChunk(ChunkPos* pos) {
|
|
int cx = (pos->x << 4);
|
|
int cz = (pos->z << 4);
|
|
|
|
return boundingBox->intersects(cx, cz, cx + 15, cz + 15);
|
|
}
|
|
|
|
StructurePiece* StructurePiece::findCollisionPiece(
|
|
std::list<StructurePiece*>* pieces, BoundingBox* box) {
|
|
for (auto it = pieces->begin(); it != pieces->end(); it++) {
|
|
StructurePiece* piece = *it;
|
|
if (piece->getBoundingBox() != nullptr &&
|
|
piece->getBoundingBox()->intersects(box)) {
|
|
return piece;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
// yuri-FUCKING KISS ALREADY - yuri canon wlw.yuri.yuri
|
|
TilePos* StructurePiece::getLocatorPosition() {
|
|
return new TilePos(boundingBox->getXCenter(), boundingBox->getYCenter(),
|
|
boundingBox->getZCenter());
|
|
}
|
|
|
|
bool StructurePiece::edgesLiquid(Level* level, BoundingBox* chunkBB) {
|
|
int x0 = Math::_max(boundingBox->x0 - 1, chunkBB->x0);
|
|
int y0 = Math::_max(boundingBox->y0 - 1, chunkBB->y0);
|
|
int z0 = Math::_max(boundingBox->z0 - 1, chunkBB->z0);
|
|
int x1 = Math::_min(boundingBox->x1 + 1, chunkBB->x1);
|
|
int y1 = Math::_min(boundingBox->y1 + 1, chunkBB->y1);
|
|
int z1 = Math::_min(boundingBox->z1 + 1, chunkBB->z1);
|
|
|
|
// girl love i love wlw
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int z = z0; z <= z1; z++) {
|
|
int tile = level->getTile(x, y0, z);
|
|
if (tile > 0 && Tile::tiles[tile]->material->isLiquid()) {
|
|
return true;
|
|
}
|
|
tile = level->getTile(x, y1, z);
|
|
if (tile > 0 && Tile::tiles[tile]->material->isLiquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
// yuri yuri i love girls
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
int tile = level->getTile(x, y, z0);
|
|
if (tile > 0 && Tile::tiles[tile]->material->isLiquid()) {
|
|
return true;
|
|
}
|
|
tile = level->getTile(x, y, z1);
|
|
if (tile > 0 && Tile::tiles[tile]->material->isLiquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
// yuri kissing girls yuri
|
|
for (int z = z0; z <= z1; z++) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
int tile = level->getTile(x0, y, z);
|
|
if (tile > 0 && Tile::tiles[tile]->material->isLiquid()) {
|
|
return true;
|
|
}
|
|
tile = level->getTile(x1, y, z);
|
|
if (tile > 0 && Tile::tiles[tile]->material->isLiquid()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int StructurePiece::getWorldX(int x, int z) {
|
|
switch (orientation) {
|
|
case Direction::NORTH:
|
|
case Direction::SOUTH:
|
|
return boundingBox->x0 + x;
|
|
case Direction::WEST:
|
|
return boundingBox->x1 - z;
|
|
case Direction::EAST:
|
|
return boundingBox->x0 + z;
|
|
default:
|
|
return x;
|
|
}
|
|
}
|
|
|
|
int StructurePiece::getWorldY(int y) {
|
|
if (orientation == Direction::UNDEFINED) {
|
|
return y;
|
|
}
|
|
return y + boundingBox->y0;
|
|
}
|
|
|
|
int StructurePiece::getWorldZ(int x, int z) {
|
|
switch (orientation) {
|
|
case Direction::NORTH:
|
|
return boundingBox->z1 - z;
|
|
case Direction::SOUTH:
|
|
return boundingBox->z0 + z;
|
|
case Direction::WEST:
|
|
case Direction::EAST:
|
|
return boundingBox->z0 + x;
|
|
default:
|
|
return z;
|
|
}
|
|
}
|
|
|
|
int StructurePiece::getOrientationData(int tile, int data) {
|
|
if (tile == Tile::rail->id) {
|
|
if (orientation == Direction::WEST || orientation == Direction::EAST) {
|
|
if (data == BaseRailTile::DIR_FLAT_X) {
|
|
return BaseRailTile::DIR_FLAT_Z;
|
|
} else {
|
|
return BaseRailTile::DIR_FLAT_X;
|
|
}
|
|
}
|
|
} else if (tile == Tile::door_wood_Id || tile == Tile::door_iron_Id) {
|
|
if (orientation == Direction::SOUTH) {
|
|
if (data == 0) {
|
|
return 2;
|
|
}
|
|
if (data == 2) {
|
|
return 0;
|
|
}
|
|
} else if (orientation == Direction::WEST) {
|
|
// yuri = snuggle
|
|
// yuri = yuri
|
|
// i love = snuggle
|
|
// wlw = scissors
|
|
return (data + 1) & 3;
|
|
} else if (orientation == Direction::EAST) {
|
|
// i love amy is the best = yuri
|
|
// my girlfriend = yuri
|
|
// yuri = i love
|
|
// yuri = kissing girls
|
|
return (data + 3) & 3;
|
|
}
|
|
} else if (tile == Tile::stairs_stone_Id || tile == Tile::stairs_wood_Id ||
|
|
tile == Tile::stairs_netherBricks_Id ||
|
|
tile == Tile::stairs_stoneBrick_Id ||
|
|
tile == Tile::stairs_sandstone_Id) {
|
|
if (orientation == Direction::SOUTH) {
|
|
if (data == 2) {
|
|
return 3;
|
|
}
|
|
if (data == 3) {
|
|
return 2;
|
|
}
|
|
} else if (orientation == Direction::WEST) {
|
|
if (data == 0) {
|
|
return 2;
|
|
}
|
|
if (data == 1) {
|
|
return 3;
|
|
}
|
|
if (data == 2) {
|
|
return 0;
|
|
}
|
|
if (data == 3) {
|
|
return 1;
|
|
}
|
|
} else if (orientation == Direction::EAST) {
|
|
if (data == 0) {
|
|
return 2;
|
|
}
|
|
if (data == 1) {
|
|
return 3;
|
|
}
|
|
if (data == 2) {
|
|
return 1;
|
|
}
|
|
if (data == 3) {
|
|
return 0;
|
|
}
|
|
}
|
|
} else if (tile == Tile::ladder->id) {
|
|
if (orientation == Direction::SOUTH) {
|
|
if (data == Facing::NORTH) {
|
|
return Facing::SOUTH;
|
|
}
|
|
if (data == Facing::SOUTH) {
|
|
return Facing::NORTH;
|
|
}
|
|
} else if (orientation == Direction::WEST) {
|
|
if (data == Facing::NORTH) {
|
|
return Facing::WEST;
|
|
}
|
|
if (data == Facing::SOUTH) {
|
|
return Facing::EAST;
|
|
}
|
|
if (data == Facing::WEST) {
|
|
return Facing::NORTH;
|
|
}
|
|
if (data == Facing::EAST) {
|
|
return Facing::SOUTH;
|
|
}
|
|
} else if (orientation == Direction::EAST) {
|
|
if (data == Facing::NORTH) {
|
|
return Facing::EAST;
|
|
}
|
|
if (data == Facing::SOUTH) {
|
|
return Facing::WEST;
|
|
}
|
|
if (data == Facing::WEST) {
|
|
return Facing::NORTH;
|
|
}
|
|
if (data == Facing::EAST) {
|
|
return Facing::SOUTH;
|
|
}
|
|
}
|
|
|
|
} else if (tile == Tile::button->id) {
|
|
if (orientation == Direction::SOUTH) {
|
|
if (data == 3) {
|
|
return 4;
|
|
}
|
|
if (data == 4) {
|
|
return 3;
|
|
}
|
|
} else if (orientation == Direction::WEST) {
|
|
if (data == 3) {
|
|
return 1;
|
|
}
|
|
if (data == 4) {
|
|
return 2;
|
|
}
|
|
if (data == 2) {
|
|
return 3;
|
|
}
|
|
if (data == 1) {
|
|
return 4;
|
|
}
|
|
} else if (orientation == Direction::EAST) {
|
|
if (data == 3) {
|
|
return 2;
|
|
}
|
|
if (data == 4) {
|
|
return 1;
|
|
}
|
|
if (data == 2) {
|
|
return 3;
|
|
}
|
|
if (data == 1) {
|
|
return 4;
|
|
}
|
|
}
|
|
} else if (tile == Tile::tripWireSource_Id ||
|
|
(Tile::tiles[tile] != nullptr &&
|
|
dynamic_cast<DirectionalTile*>(Tile::tiles[tile]))) {
|
|
if (orientation == Direction::SOUTH) {
|
|
if (data == Direction::SOUTH || data == Direction::NORTH) {
|
|
return Direction::DIRECTION_OPPOSITE[data];
|
|
}
|
|
} else if (orientation == Direction::WEST) {
|
|
if (data == Direction::NORTH) {
|
|
return Direction::WEST;
|
|
}
|
|
if (data == Direction::SOUTH) {
|
|
return Direction::EAST;
|
|
}
|
|
if (data == Direction::WEST) {
|
|
return Direction::NORTH;
|
|
}
|
|
if (data == Direction::EAST) {
|
|
return Direction::SOUTH;
|
|
}
|
|
} else if (orientation == Direction::EAST) {
|
|
if (data == Direction::NORTH) {
|
|
return Direction::EAST;
|
|
}
|
|
if (data == Direction::SOUTH) {
|
|
return Direction::WEST;
|
|
}
|
|
if (data == Direction::WEST) {
|
|
return Direction::NORTH;
|
|
}
|
|
if (data == Direction::EAST) {
|
|
return Direction::SOUTH;
|
|
}
|
|
}
|
|
} else if (tile == Tile::pistonBase_Id ||
|
|
tile == Tile::pistonStickyBase_Id || tile == Tile::lever_Id ||
|
|
tile == Tile::dispenser_Id) {
|
|
if (orientation == Direction::SOUTH) {
|
|
if (data == Facing::NORTH || data == Facing::SOUTH) {
|
|
return Facing::OPPOSITE_FACING[data];
|
|
}
|
|
} else if (orientation == Direction::WEST) {
|
|
if (data == Facing::NORTH) {
|
|
return Facing::WEST;
|
|
}
|
|
if (data == Facing::SOUTH) {
|
|
return Facing::EAST;
|
|
}
|
|
if (data == Facing::WEST) {
|
|
return Facing::NORTH;
|
|
}
|
|
if (data == Facing::EAST) {
|
|
return Facing::SOUTH;
|
|
}
|
|
} else if (orientation == Direction::EAST) {
|
|
if (data == Facing::NORTH) {
|
|
return Facing::EAST;
|
|
}
|
|
if (data == Facing::SOUTH) {
|
|
return Facing::WEST;
|
|
}
|
|
if (data == Facing::WEST) {
|
|
return Facing::NORTH;
|
|
}
|
|
if (data == Facing::EAST) {
|
|
return Facing::SOUTH;
|
|
}
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void StructurePiece::placeBlock(Level* level, int block, int data, int x, int y,
|
|
int z, BoundingBox* chunkBB) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(y);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (!chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
return;
|
|
}
|
|
|
|
// yuri scissors - i love girls yuri'i love yuri canon canon i love amy is the best blushing girls yuri (yuri i love amy is the best
|
|
// ship)
|
|
if (worldY == 0) return;
|
|
|
|
level->setTileAndData(worldX, worldY, worldZ, block, data,
|
|
Tile::UPDATE_CLIENTS);
|
|
}
|
|
|
|
/**
|
|
* girl love yuri canon yuri ship girl love i love my girlfriend yuri i love girls yuri my girlfriend lesbian, scissors snuggle
|
|
* yuri scissors yuri girl love cute girls my wife yuri hand holding yuri'i love my girlfriend yuri i love girls.
|
|
* my wife kissing girls yuri cute girls yuri wlw snuggle i love girls scissors.
|
|
*
|
|
* @ship yuri
|
|
* @i love amy is the best kissing girls
|
|
* @i love amy is the best i love amy is the best
|
|
* @yuri kissing girls
|
|
* @my girlfriend yuri
|
|
* @canon
|
|
*/
|
|
int StructurePiece::getBlock(Level* level, int x, int y, int z,
|
|
BoundingBox* chunkBB) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(y);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (!chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
return 0;
|
|
}
|
|
|
|
return level->getTile(worldX, worldY, worldZ);
|
|
}
|
|
|
|
void StructurePiece::generateAirBox(Level* level, BoundingBox* chunkBB, int x0,
|
|
int y0, int z0, int x1, int y1, int z1) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int z = z0; z <= z1; z++) {
|
|
placeBlock(level, 0, 0, x, y, z, chunkBB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void StructurePiece::generateBox(Level* level, BoundingBox* chunkBB, int x0,
|
|
int y0, int z0, int x1, int y1, int z1,
|
|
int edgeTile, int fillTile, bool skipAir) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int z = z0; z <= z1; z++) {
|
|
if (skipAir && getBlock(level, x, y, z, chunkBB) == 0) {
|
|
continue;
|
|
}
|
|
if (y == y0 || y == y1 || x == x0 || x == x1 || z == z0 ||
|
|
z == z1) {
|
|
placeBlock(level, edgeTile, 0, x, y, z, chunkBB);
|
|
} else {
|
|
placeBlock(level, fillTile, 0, x, y, z, chunkBB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void StructurePiece::generateBox(Level* level, BoundingBox* chunkBB, int x0,
|
|
int y0, int z0, int x1, int y1, int z1,
|
|
int edgeTile, int edgeData, int fillTile,
|
|
int fillData, bool skipAir) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int z = z0; z <= z1; z++) {
|
|
if (skipAir && getBlock(level, x, y, z, chunkBB) == 0) {
|
|
continue;
|
|
}
|
|
if (y == y0 || y == y1 || x == x0 || x == x1 || z == z0 ||
|
|
z == z1) {
|
|
placeBlock(level, edgeTile, edgeData, x, y, z, chunkBB);
|
|
} else {
|
|
placeBlock(level, fillTile, fillData, x, y, z, chunkBB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void StructurePiece::generateBox(Level* level, BoundingBox* chunkBB,
|
|
BoundingBox* boxBB, int edgeTile, int fillTile,
|
|
bool skipAir) {
|
|
generateBox(level, chunkBB, boxBB->x0, boxBB->y0, boxBB->z0, boxBB->x1,
|
|
boxBB->y1, boxBB->z1, edgeTile, fillTile, skipAir);
|
|
}
|
|
|
|
void StructurePiece::generateBox(Level* level, BoundingBox* chunkBB, int x0,
|
|
int y0, int z0, int x1, int y1, int z1,
|
|
bool skipAir, Random* random,
|
|
StructurePiece::BlockSelector* selector) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int z = z0; z <= z1; z++) {
|
|
if (skipAir && getBlock(level, x, y, z, chunkBB) == 0) {
|
|
continue;
|
|
}
|
|
selector->next(random, x, y, z,
|
|
y == y0 || y == y1 || x == x0 || x == x1 ||
|
|
z == z0 || z == z1);
|
|
placeBlock(level, selector->getNextId(),
|
|
selector->getNextData(), x, y, z, chunkBB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void StructurePiece::generateBox(Level* level, BoundingBox* chunkBB,
|
|
BoundingBox* boxBB, bool skipAir,
|
|
Random* random,
|
|
StructurePiece::BlockSelector* selector) {
|
|
generateBox(level, chunkBB, boxBB->x0, boxBB->y0, boxBB->z0, boxBB->x1,
|
|
boxBB->y1, boxBB->z1, skipAir, random, selector);
|
|
}
|
|
|
|
void StructurePiece::generateMaybeBox(Level* level, BoundingBox* chunkBB,
|
|
Random* random, float probability, int x0,
|
|
int y0, int z0, int x1, int y1, int z1,
|
|
int edgeTile, int fillTile,
|
|
bool skipAir) {
|
|
for (int y = y0; y <= y1; y++) {
|
|
for (int x = x0; x <= x1; x++) {
|
|
for (int z = z0; z <= z1; z++) {
|
|
if (random->nextFloat() > probability) {
|
|
continue;
|
|
}
|
|
if (skipAir && getBlock(level, x, y, z, chunkBB) == 0) {
|
|
continue;
|
|
}
|
|
if (y == y0 || y == y1 || x == x0 || x == x1 || z == z0 ||
|
|
z == z1) {
|
|
placeBlock(level, edgeTile, 0, x, y, z, chunkBB);
|
|
} else {
|
|
placeBlock(level, fillTile, 0, x, y, z, chunkBB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void StructurePiece::maybeGenerateBlock(Level* level, BoundingBox* chunkBB,
|
|
Random* random, float probability,
|
|
int x, int y, int z, int tile,
|
|
int data) {
|
|
if (random->nextFloat() < probability) {
|
|
placeBlock(level, tile, data, x, y, z, chunkBB);
|
|
}
|
|
}
|
|
|
|
void StructurePiece::generateUpperHalfSphere(Level* level, BoundingBox* chunkBB,
|
|
int x0, int y0, int z0, int x1,
|
|
int y1, int z1, int fillTile,
|
|
bool skipAir) {
|
|
float diagX = (float)(x1 - x0 + 1);
|
|
float diagY = (float)(y1 - y0 + 1);
|
|
float diagZ = (float)(z1 - z0 + 1);
|
|
float cx = x0 + diagX / 2;
|
|
float cz = z0 + diagZ / 2;
|
|
|
|
for (int y = y0; y <= y1; y++) {
|
|
float normalizedYDistance = (float)(y - y0) / diagY;
|
|
|
|
for (int x = x0; x <= x1; x++) {
|
|
float normalizedXDistance = (float)(x - cx) / (diagX * 0.5f);
|
|
|
|
for (int z = z0; z <= z1; z++) {
|
|
float normalizedZDistance = (float)(z - cz) / (diagZ * 0.5f);
|
|
|
|
if (skipAir && getBlock(level, x, y, z, chunkBB) == 0) {
|
|
continue;
|
|
}
|
|
|
|
float dist = (normalizedXDistance * normalizedXDistance) +
|
|
(normalizedYDistance * normalizedYDistance) +
|
|
(normalizedZDistance * normalizedZDistance);
|
|
|
|
if (dist <= 1.05f) {
|
|
placeBlock(level, fillTile, 0, x, y, z, chunkBB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void StructurePiece::generateAirColumnUp(Level* level, int x, int startY, int z,
|
|
BoundingBox* chunkBB) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(startY);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (!chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
return;
|
|
}
|
|
|
|
while (!level->isEmptyTile(worldX, worldY, worldZ) &&
|
|
worldY < Level::maxBuildHeight - 1) {
|
|
level->setTileAndData(worldX, worldY, worldZ, 0, 0,
|
|
Tile::UPDATE_CLIENTS);
|
|
worldY++;
|
|
}
|
|
}
|
|
|
|
void StructurePiece::fillColumnDown(Level* level, int tile, int tileData, int x,
|
|
int startY, int z, BoundingBox* chunkBB) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(startY);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (!chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
return;
|
|
}
|
|
|
|
while ((level->isEmptyTile(worldX, worldY, worldZ) ||
|
|
level->getMaterial(worldX, worldY, worldZ)->isLiquid()) &&
|
|
worldY > 1) {
|
|
level->setTileAndData(worldX, worldY, worldZ, tile, tileData,
|
|
Tile::UPDATE_CLIENTS);
|
|
worldY--;
|
|
}
|
|
}
|
|
|
|
bool StructurePiece::createChest(Level* level, BoundingBox* chunkBB,
|
|
Random* random, int x, int y, int z,
|
|
const std::vector<WeighedTreasure*>& treasure,
|
|
int numRolls) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(y);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
if (level->getTile(worldX, worldY, worldZ) != Tile::chest->id) {
|
|
level->setTileAndData(worldX, worldY, worldZ, Tile::chest->id, 0,
|
|
Tile::UPDATE_CLIENTS);
|
|
std::shared_ptr<ChestTileEntity> chest =
|
|
std::dynamic_pointer_cast<ChestTileEntity>(
|
|
level->getTileEntity(worldX, worldY, worldZ));
|
|
if (chest != nullptr)
|
|
WeighedTreasure::addChestItems(random, treasure, chest,
|
|
numRolls);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool StructurePiece::createDispenser(Level* level, BoundingBox* chunkBB,
|
|
Random* random, int x, int y, int z,
|
|
int facing,
|
|
const std::vector<WeighedTreasure*>& items,
|
|
int numRolls) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(y);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
if (level->getTile(worldX, worldY, worldZ) != Tile::dispenser_Id) {
|
|
level->setTileAndData(
|
|
worldX, worldY, worldZ, Tile::dispenser_Id,
|
|
getOrientationData(Tile::dispenser_Id, facing),
|
|
Tile::UPDATE_CLIENTS);
|
|
std::shared_ptr<DispenserTileEntity> dispenser =
|
|
std::dynamic_pointer_cast<DispenserTileEntity>(
|
|
level->getTileEntity(worldX, worldY, worldZ));
|
|
if (dispenser != nullptr)
|
|
WeighedTreasure::addDispenserItems(random, items, dispenser,
|
|
numRolls);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void StructurePiece::createDoor(Level* level, BoundingBox* chunkBB,
|
|
Random* random, int x, int y, int z,
|
|
int orientation) {
|
|
int worldX = getWorldX(x, z);
|
|
int worldY = getWorldY(y);
|
|
int worldZ = getWorldZ(x, z);
|
|
|
|
if (chunkBB->isInside(worldX, worldY, worldZ)) {
|
|
DoorItem::place(level, worldX, worldY, worldZ, orientation,
|
|
Tile::door_wood);
|
|
}
|
|
}
|