Search in sources :

Example 1 with AreaDescriptor

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;
}
Also used : AreaDescriptor(WayofTime.bloodmagic.ritual.AreaDescriptor) EnumFacing(net.minecraft.util.EnumFacing) PlacementSettings(net.minecraft.world.gen.structure.template.PlacementSettings) Rotation(net.minecraft.util.Rotation) BlockPos(net.minecraft.util.math.BlockPos) Mirror(net.minecraft.util.Mirror) Pair(org.apache.commons.lang3.tuple.Pair)

Example 2 with AreaDescriptor

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;
        }
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) AreaDescriptor(WayofTime.bloodmagic.ritual.AreaDescriptor) IBlockState(net.minecraft.block.state.IBlockState) IItemHandler(net.minecraftforge.items.IItemHandler) BlockPos(net.minecraft.util.math.BlockPos) World(net.minecraft.world.World) ItemStack(net.minecraft.item.ItemStack) ItemBlock(net.minecraft.item.ItemBlock)

Aggregations

AreaDescriptor (WayofTime.bloodmagic.ritual.AreaDescriptor)2 BlockPos (net.minecraft.util.math.BlockPos)2 IBlockState (net.minecraft.block.state.IBlockState)1 ItemBlock (net.minecraft.item.ItemBlock)1 ItemStack (net.minecraft.item.ItemStack)1 TileEntity (net.minecraft.tileentity.TileEntity)1 EnumFacing (net.minecraft.util.EnumFacing)1 Mirror (net.minecraft.util.Mirror)1 Rotation (net.minecraft.util.Rotation)1 AxisAlignedBB (net.minecraft.util.math.AxisAlignedBB)1 World (net.minecraft.world.World)1 PlacementSettings (net.minecraft.world.gen.structure.template.PlacementSettings)1 IItemHandler (net.minecraftforge.items.IItemHandler)1 Pair (org.apache.commons.lang3.tuple.Pair)1