/*
* Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
* Copyright (C) 2021 cyoung06
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package kr.syeyoung.dungeonsguide.roomprocessor;
import com.google.common.base.Predicate;
import kr.syeyoung.dungeonsguide.config.Config;
import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom;
import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
import kr.syeyoung.dungeonsguide.utils.RenderUtils;
import net.minecraft.block.Block;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.init.Blocks;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class RoomProcessorCreeperSolver extends GeneralRoomProcessor {
private final List poses = new ArrayList();
private final boolean bugged = false;
public RoomProcessorCreeperSolver(DungeonRoom dungeonRoom) {
super(dungeonRoom);
findCreeperAndDoPoses();
}
private boolean check(AxisAlignedBB axis, Vec3 vec) {
if (vec == null) return false;
return axis.isVecInside(vec);
}
private void findCreeperAndDoPoses() {
World w = getDungeonRoom().getContext().getWorld();
List prismarines = new ArrayList();
final BlockPos low = getDungeonRoom().getMin().add(0,-2,0);
final BlockPos high = getDungeonRoom().getMax().add(0,20,0);
final AxisAlignedBB axis = AxisAlignedBB.fromBounds(
low.getX() + 17, low.getY() + 7, low.getZ() + 17,
low.getX() + 16, low.getY() + 10.5, low.getZ() + 16
);
for (BlockPos pos : BlockPos.getAllInBox(low, high)) {
Block b = w.getBlockState(pos).getBlock();
if (b == Blocks.prismarine || b == Blocks.sea_lantern) {
for (EnumFacing face:EnumFacing.VALUES) {
if (w.getBlockState(pos.offset(face)).getBlock() == Blocks.air) {
prismarines.add(pos);
break;
}
}
}
}
double offset = 0.1;
while (prismarines.size() > 1) {
BlockPos first = prismarines.get(0);
BlockPos highestMatch = null;
int highestDist = 0;
label: for (int i = 1; i < prismarines.size(); i++) {
BlockPos second = prismarines.get(i);
if (second.distanceSq(first) < highestDist) continue;
Vec3 startLoc = new Vec3(first).addVector(0.5,0.5,0.5);
Vec3 dest = new Vec3(second).addVector(0.5,0.5,0.5);
if (check(axis, startLoc.getIntermediateWithYValue(dest, axis.minY+offset)) ||
check(axis, startLoc.getIntermediateWithYValue(dest, axis.maxY-offset)) ||
check(axis, startLoc.getIntermediateWithXValue(dest, axis.minX+offset)) ||
check(axis, startLoc.getIntermediateWithXValue(dest, axis.maxX-offset)) ||
check(axis, startLoc.getIntermediateWithZValue(dest, axis.minZ+offset)) ||
check(axis, startLoc.getIntermediateWithZValue(dest, axis.maxZ-offset))) {
highestDist = (int) second.distanceSq(first);
highestMatch = second;
}
}
if (highestMatch == null) {
prismarines.remove(first);
} else {
prismarines.remove(first);
prismarines.remove(highestMatch);
poses.add(new BlockPos[] {first, highestMatch});
}
}
}
@Override
public void tick() {
super.tick();
if (bugged) {
findCreeperAndDoPoses();
}
}
private static final Color[] colors = new Color[] {Color.red, Color.orange, Color.green, Color.cyan, Color.blue, Color.pink, Color.yellow, Color.darkGray, Color.lightGray};
@Override
public void drawWorld(float partialTicks) {
super.drawWorld(partialTicks);
if (!FeatureRegistry.SOLVER_CREEPER.isEnabled()) return;
World w = getDungeonRoom().getContext().getWorld();
for (int i = 0; i < poses.size(); i++) {
BlockPos[] poset = poses.get(i);
Color color = colors[i % colors.length];
boolean oneIsConnected = w.getChunkFromBlockCoords(poset[0]).getBlock(poset[0]) != Blocks.sea_lantern &&
w.getChunkFromBlockCoords(poset[1]).getBlock(poset[1]) != Blocks.sea_lantern;
RenderUtils.drawLine(new Vec3(poset[0].getX() +0.5, poset[0].getY() +0.5, poset[0].getZ()+0.5),
new Vec3(poset[1].getX() +0.5, poset[1].getY() +0.5, poset[1].getZ()+0.5), oneIsConnected ? new Color(0,0,0,50) : color, partialTicks, true);
}
final BlockPos low = getDungeonRoom().getMin();
final AxisAlignedBB axis = AxisAlignedBB.fromBounds(
low.getX() + 17, low.getY() + 5, low.getZ() + 17,
low.getX() + 16, low.getY() + 8.5, low.getZ() + 16
);
RenderUtils.highlightBox(axis, new Color(0x4400FF00, true), partialTicks, false);
}
public static class Generator implements RoomProcessorGenerator {
@Override
public RoomProcessorCreeperSolver createNew(DungeonRoom dungeonRoom) {
RoomProcessorCreeperSolver defaultRoomProcessor = new RoomProcessorCreeperSolver(dungeonRoom);
return defaultRoomProcessor;
}
}
}