use of WayofTime.bloodmagic.ritual.AreaDescriptor in project BloodMagic by WayofTime.
the class Dungeon method placeStructureAtPosition.
public static boolean placeStructureAtPosition(Random rand, WorldServer world, BlockPos pos) {
long startTime = System.nanoTime();
// Map of doors. The EnumFacing indicates what way this door faces.
Map<EnumFacing, List<BlockPos>> availableDoorMap = new HashMap<>();
List<AreaDescriptor> descriptorList = new ArrayList<>();
// Placement positions in terms of actual positions
Map<BlockPos, Pair<DungeonRoom, PlacementSettings>> roomMap = new HashMap<>();
PlacementSettings settings = new PlacementSettings();
Mirror mir = Mirror.NONE;
settings.setMirror(mir);
Rotation rot = Rotation.NONE;
settings.setRotation(rot);
settings.setIgnoreEntities(true);
settings.setChunk(null);
settings.setReplacedBlock(null);
settings.setIgnoreStructureBlock(false);
DungeonRoom room = getRandomRoom(rand);
roomMap.put(pos, Pair.of(room, settings.copy()));
descriptorList.addAll(room.getAreaDescriptors(settings, pos));
for (EnumFacing facing : EnumFacing.VALUES) {
if (availableDoorMap.containsKey(facing)) {
List<BlockPos> doorList = availableDoorMap.get(facing);
doorList.addAll(room.getDoorOffsetsForFacing(settings, facing, pos));
} else {
List<BlockPos> doorList = room.getDoorOffsetsForFacing(settings, facing, pos);
availableDoorMap.put(facing, doorList);
}
}
// Initial AreaDescriptors and door positions are initialized. Time for fun!
for (int i = 0; i < 100; i++) {
List<EnumFacing> facingList = new ArrayList<>();
for (Entry<EnumFacing, List<BlockPos>> entry : availableDoorMap.entrySet()) {
if (entry.getValue() != null && !entry.getValue().isEmpty()) {
facingList.add(entry.getKey());
}
}
// Shuffle the list so that it is random what is chosen
Collections.shuffle(facingList);
Pair<EnumFacing, BlockPos> removedDoor1 = null;
Pair<EnumFacing, BlockPos> removedDoor2 = null;
BlockPos roomLocation = null;
for (EnumFacing doorFacing : facingList) {
EnumFacing oppositeDoorFacing = doorFacing.getOpposite();
// May need to copy here
List<BlockPos> availableDoorList = availableDoorMap.get(doorFacing);
Collections.shuffle(availableDoorList);
// Same for the Mirror
settings.setRotation(Rotation.values()[rand.nextInt(Rotation.values().length)]);
DungeonRoom testingRoom = getRandomRoom(rand);
List<BlockPos> otherDoorList = testingRoom.getDoorOffsetsForFacing(settings, oppositeDoorFacing, BlockPos.ORIGIN);
if (otherDoorList != null && !otherDoorList.isEmpty()) {
// See if one of these doors works.
Collections.shuffle(otherDoorList);
BlockPos testDoor = otherDoorList.get(0);
testDoor: for (BlockPos availableDoor : availableDoorList) {
// TODO: Test if it fits, then add the doors to the list.
roomLocation = availableDoor.subtract(testDoor).add(doorFacing.getDirectionVec());
List<AreaDescriptor> descriptors = testingRoom.getAreaDescriptors(settings, roomLocation);
for (AreaDescriptor testDesc : descriptors) {
for (AreaDescriptor currentDesc : descriptorList) {
if (testDesc.intersects(currentDesc)) {
break testDoor;
}
}
}
roomMap.put(roomLocation, Pair.of(testingRoom, settings.copy()));
descriptorList.addAll(descriptors);
removedDoor1 = Pair.of(doorFacing, availableDoor);
removedDoor2 = Pair.of(oppositeDoorFacing, testDoor.add(roomLocation));
room = testingRoom;
}
break;
}
// Collections.shuffle(otherDoorList);
}
if (removedDoor1 != null) {
for (EnumFacing facing : EnumFacing.VALUES) {
if (availableDoorMap.containsKey(facing)) {
List<BlockPos> doorList = availableDoorMap.get(facing);
doorList.addAll(room.getDoorOffsetsForFacing(settings, facing, roomLocation));
} else {
List<BlockPos> doorList = room.getDoorOffsetsForFacing(settings, facing, roomLocation);
availableDoorMap.put(facing, doorList);
}
}
EnumFacing face = removedDoor1.getKey();
if (availableDoorMap.containsKey(face)) {
availableDoorMap.get(face).remove(removedDoor1.getRight());
}
}
if (removedDoor2 != null) {
EnumFacing face = removedDoor2.getKey();
if (availableDoorMap.containsKey(face)) {
availableDoorMap.get(face).remove(removedDoor2.getRight());
}
}
}
long endTime = System.nanoTime();
// divide by 1000000 to get milliseconds.
long duration = (endTime - startTime);
BMLog.DEBUG.info("Duration: " + duration + "(ns), " + duration / 1000000 + "(ms)");
// Building what I've got
for (Entry<BlockPos, Pair<DungeonRoom, PlacementSettings>> entry : roomMap.entrySet()) {
BlockPos placementPos = entry.getKey();
DungeonRoom placedRoom = entry.getValue().getKey();
PlacementSettings placementSettings = entry.getValue().getValue();
placedRoom.placeStructureAtPosition(rand, placementSettings, world, placementPos);
}
return false;
}
use of WayofTime.bloodmagic.ritual.AreaDescriptor in project BloodMagic by WayofTime.
the class RitualEllipsoid method performRitual.
@Override
public void performRitual(IMasterRitualStone masterRitualStone) {
World world = masterRitualStone.getWorldObj();
int currentEssence = masterRitualStone.getOwnerNetwork().getCurrentEssence();
BlockPos masterPos = masterRitualStone.getBlockPos();
AreaDescriptor chestRange = getBlockRange(CHEST_RANGE);
TileEntity tileInventory = world.getTileEntity(chestRange.getContainedPositions(masterPos).get(0));
if (currentEssence < getRefreshCost()) {
masterRitualStone.getOwnerNetwork().causeNausea();
return;
}
AreaDescriptor sphereRange = getBlockRange(SPHEROID_RANGE);
AxisAlignedBB sphereBB = sphereRange.getAABB(masterPos);
int minX = (int) (masterPos.getX() - sphereBB.minX);
int maxX = (int) (sphereBB.maxX - masterPos.getX()) - 1;
int minY = (int) (masterPos.getY() - sphereBB.minY);
int maxY = (int) (sphereBB.maxY - masterPos.getY()) - 1;
int minZ = (int) (masterPos.getZ() - sphereBB.minZ);
int maxZ = (int) (sphereBB.maxZ - masterPos.getZ()) - 1;
if (tileInventory != null) {
if (tileInventory.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN)) {
IItemHandler itemHandler = tileInventory.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);
if (itemHandler.getSlots() <= 0) {
return;
}
int blockSlot = -1;
for (int invSlot = 0; invSlot < itemHandler.getSlots(); invSlot++) {
ItemStack stack = itemHandler.extractItem(invSlot, 1, true);
if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock))
continue;
blockSlot = invSlot;
break;
}
if (blockSlot == -1) {
return;
}
int xR = Math.max(maxX, minX);
int yR = Math.max(maxY, minY);
int zR = Math.max(maxZ, minZ);
int j = -minX;
int i = -minY;
int k = -minZ;
if (currentPos != null) {
j = currentPos.getY();
i = Math.min(xR, Math.max(-minX, currentPos.getX()));
k = Math.min(zR, Math.max(-minZ, currentPos.getZ()));
}
int checks = 0;
int maxChecks = 100;
while (j <= maxY) {
while (i <= maxX) {
while (k <= maxZ) {
checks++;
if (checks >= maxChecks) {
this.currentPos = new BlockPos(i, j, k);
return;
}
if (checkIfEllipsoidShell(xR, yR, zR, i, j, k)) {
BlockPos newPos = masterPos.add(i, j, k);
//
if (!world.getBlockState(newPos).getBlock().isReplaceable(world, newPos)) {
k++;
continue;
}
IBlockState placeState = Block.getBlockFromItem(itemHandler.getStackInSlot(blockSlot).getItem()).getStateFromMeta(itemHandler.getStackInSlot(blockSlot).getItemDamage());
world.setBlockState(newPos, placeState);
itemHandler.extractItem(blockSlot, 1, false);
tileInventory.markDirty();
// TODO:
masterRitualStone.getOwnerNetwork().syphon(getRefreshCost());
k++;
this.currentPos = new BlockPos(i, j, k);
return;
}
k++;
}
i++;
k = -minZ;
}
j++;
i = -minX;
this.currentPos = new BlockPos(i, j, k);
return;
}
j = -minY;
this.currentPos = new BlockPos(i, j, k);
return;
}
}
}
Aggregations