aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/AbstractAction.java61
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionBreakWithSuperBoom.java103
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionChangeState.java75
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClick.java82
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClickSet.java90
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionComplete.java41
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionDropItem.java82
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionInteract.java89
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionKill.java90
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMove.java122
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMoveNearestAir.java92
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionRoot.java47
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRoute.java136
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRouteProperties.java16
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTree.java94
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTreeUtil.java83
16 files changed, 1303 insertions, 0 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/AbstractAction.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/AbstractAction.java
new file mode 100644
index 00000000..d465fd47
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/AbstractAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.events.impl.PlayerInteractEntityEvent;
+import net.minecraftforge.event.entity.living.LivingDeathEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+
+import java.util.Set;
+
+public abstract class AbstractAction {
+ public void onPlayerInteract(DungeonRoom dungeonRoom, PlayerInteractEvent event, ActionRouteProperties actionRouteProperties){
+
+ }
+
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+
+ }
+
+ public void onLivingDeath(DungeonRoom dungeonRoom, LivingDeathEvent event, ActionRouteProperties actionRouteProperties) {
+
+ }
+
+ public void onRenderScreen(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties) {
+
+ }
+
+ public void onLivingInteract(DungeonRoom dungeonRoom, PlayerInteractEntityEvent event, ActionRouteProperties actionRouteProperties) {
+
+ }
+
+ public void onTick(DungeonRoom dungeonRoom, ActionRouteProperties actionRouteProperties) {
+
+ }
+
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return null;
+ }
+
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return false;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionBreakWithSuperBoom.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionBreakWithSuperBoom.java
new file mode 100755
index 00000000..baab261f
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionBreakWithSuperBoom.java
@@ -0,0 +1,103 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.BlockRendererDispatcher;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.renderer.texture.TextureMap;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.entity.Entity;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.BlockPos;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionBreakWithSuperBoom extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<AbstractAction>();
+ private OffsetPoint target;
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return false;
+ }
+
+ public ActionBreakWithSuperBoom(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationBlocksTexture);
+
+ BlockPos blockpos = target.getBlockPos(dungeonRoom);
+
+ Entity viewing_from = Minecraft.getMinecraft().getRenderViewEntity();
+
+ double x_fix = viewing_from.lastTickPosX + ((viewing_from.posX - viewing_from.lastTickPosX) * partialTicks);
+ double y_fix = viewing_from.lastTickPosY + ((viewing_from.posY - viewing_from.lastTickPosY) * partialTicks);
+ double z_fix = viewing_from.lastTickPosZ + ((viewing_from.posZ - viewing_from.lastTickPosZ) * partialTicks);
+
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(-x_fix, -y_fix, -z_fix);
+ GlStateManager.disableLighting();
+ GlStateManager.enableAlpha();
+ GlStateManager.disableDepth();
+ GlStateManager.depthMask(false);
+ GlStateManager.enableBlend();
+
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer vertexbuffer = tessellator.getWorldRenderer();
+ vertexbuffer.begin(7, DefaultVertexFormats.BLOCK);
+
+ BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
+ blockrendererdispatcher.getBlockModelRenderer().renderModel(Minecraft.getMinecraft().theWorld,
+ blockrendererdispatcher.getBlockModelShapes().getModelForState(Blocks.tnt.getDefaultState()),
+ Blocks.tnt.getDefaultState(), blockpos, vertexbuffer, false);
+ tessellator.draw();
+
+ GlStateManager.enableLighting();
+ GlStateManager.popMatrix();
+
+ RenderUtils.highlightBlock(blockpos, new Color(0, 255,255,50), partialTicks, true);
+ RenderUtils.drawTextAtWorld("Superboom", blockpos.getX() + 0.5f, blockpos.getY() + 0.5f, blockpos.getZ() + 0.5f, 0xFFFFFF00, 0.03f, false, false, partialTicks);
+ }
+
+ @Override
+ public String toString() {
+ return "BreakWithSuperboom\n- target: "+target.toString();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionChangeState.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionChangeState.java
new file mode 100755
index 00000000..634129c6
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionChangeState.java
@@ -0,0 +1,75 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.dungeon.mechanics.DungeonDummy;
+import kr.syeyoung.dungeonsguide.dungeon.mechanics.DungeonSecret;
+import kr.syeyoung.dungeonsguide.dungeon.mechanics.dunegonmechanic.DungeonMechanic;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionChangeState extends AbstractAction {
+ @EqualsAndHashCode.Exclude
+ private Set<AbstractAction> preRequisite2 = new HashSet<AbstractAction>();
+
+ private String mechanicName;
+ private String state;
+
+ public ActionChangeState(String mechanicName, String state) {
+ this.mechanicName = mechanicName;
+ this.state = state;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ Set<AbstractAction> set = new HashSet<>(preRequisite2);
+ DungeonMechanic mechanic = dungeonRoom.getMechanics().get(mechanicName);
+ if (mechanic!= null)
+ set.addAll(mechanic.getAction(state, dungeonRoom));
+ return set;
+ }
+ @Override
+ public String toString() {
+ return "ChangeState\n- target: "+mechanicName+"\n- state: "+state;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ DungeonMechanic mechanic = dungeonRoom.getMechanics().get(mechanicName);
+ if (state.equalsIgnoreCase("navigate")) {
+ return true;
+ }
+ if (mechanic == null) {
+ return false;
+ }
+ if (mechanic instanceof DungeonSecret && ((DungeonSecret) mechanic).getSecretType() != DungeonSecret.SecretType.CHEST) {
+ return true;
+ }
+ if (mechanic instanceof DungeonDummy) {
+ return true;
+ }
+ return mechanic.getCurrentState(dungeonRoom).equalsIgnoreCase(state);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClick.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClick.java
new file mode 100755
index 00000000..c9ffb81c
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClick.java
@@ -0,0 +1,82 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter;
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.BlockPos;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionClick extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<AbstractAction>();
+ private OffsetPoint target;
+ private Predicate<ItemStack> predicate = Predicates.alwaysTrue();
+
+ private boolean clicked = false;
+
+ public ActionClick(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return clicked;
+ }
+
+ @Override
+ public void onPlayerInteract(DungeonRoom dungeonRoom, PlayerInteractEvent event, ActionRouteProperties actionRouteProperties) {
+ if (clicked) return;
+ if (target.getBlockPos(dungeonRoom).equals(event.pos) &&
+ (predicate == null || predicate.apply(event.entityLiving.getHeldItem()))) {
+ clicked = true;
+ ChatTransmitter.sendDebugChat("ACTION FINISHED: CLICK");
+ }
+ }
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ BlockPos pos = target.getBlockPos(dungeonRoom);
+ RenderUtils.highlightBlock(pos, new Color(0, 255,255,50),partialTicks, true);
+ RenderUtils.drawTextAtWorld("Click", pos.getX() + 0.5f, pos.getY() + 0.3f, pos.getZ() + 0.5f, 0xFFFFFF00, 0.02f, false, false, partialTicks);
+ }
+
+
+ @Override
+ public String toString() {
+ return "Click\n- target: "+target.toString()+"\n- predicate: "+predicate.getClass().getSimpleName();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClickSet.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClickSet.java
new file mode 100755
index 00000000..01f5b9b2
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionClickSet.java
@@ -0,0 +1,90 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPointSet;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.BlockPos;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionClickSet extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<>();
+ private OffsetPointSet target;
+ private Predicate<ItemStack> predicate = stack -> true;
+
+ public ActionClickSet(OffsetPointSet target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public String toString() {
+ return "ClickSet\n- targets size: "+target.getOffsetPointList().size()+"\n- predicate: "+predicate.getClass().getSimpleName();
+ }
+
+ private boolean clicked = false;
+ @Override
+ public void onPlayerInteract(DungeonRoom dungeonRoom, PlayerInteractEvent event, ActionRouteProperties actionRouteProperties) {
+ if (clicked) return;
+ for (OffsetPoint pt2: target.getOffsetPointList()) {
+ if (pt2.getBlockPos(dungeonRoom).equals(event.pos) && predicate.test(event.entityLiving.getHeldItem())) {
+ clicked = true;
+ }
+ }
+
+ }
+
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ float xAcc = 0;
+ float yAcc = 0;
+ float zAcc = 0;
+ int size = target.getOffsetPointList().size();
+ for (OffsetPoint offsetPoint : target.getOffsetPointList()) {
+ BlockPos pos = offsetPoint.getBlockPos(dungeonRoom);
+ xAcc += pos.getX() + 0.5f;
+ yAcc += pos.getY()+ 0.5f;
+ zAcc += pos.getZ()+ 0.5f;
+ RenderUtils.highlightBlock(offsetPoint.getBlockPos(dungeonRoom), new Color(0, 255,255,50),partialTicks, true);
+ }
+
+ RenderUtils.drawTextAtWorld("Click", xAcc / size, yAcc / size, zAcc / size, 0xFFFFFF00, 0.02f, false, false, partialTicks);
+ }
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return clicked;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionComplete.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionComplete.java
new file mode 100644
index 00000000..32d6bfc3
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionComplete.java
@@ -0,0 +1,41 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+
+import java.util.Collections;
+import java.util.Set;
+
+public class ActionComplete extends AbstractAction {
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "Completed";
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionDropItem.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionDropItem.java
new file mode 100755
index 00000000..0c94e5ae
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionDropItem.java
@@ -0,0 +1,82 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.BlockPos;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class ActionDropItem extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<>();
+ private OffsetPoint target;
+ private Predicate<EntityItem> predicate = Predicates.alwaysTrue();
+
+ public ActionDropItem(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ BlockPos secretLocation = target.getBlockPos(dungeonRoom);
+ List<EntityItem> item = dungeonRoom.getContext().getWorld().getEntitiesWithinAABB(EntityItem.class,
+ AxisAlignedBB.fromBounds(
+ secretLocation.getX(),
+ secretLocation.getY(),
+ secretLocation.getZ(),
+ secretLocation.getX() + 1,
+ secretLocation.getY() + 1,
+ secretLocation.getZ() + 1));
+ if (item.isEmpty()) {
+ return false;
+ }
+ return (predicate == null || predicate.apply(item.get(0)));
+ }
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ BlockPos pos = target.getBlockPos(dungeonRoom);
+ RenderUtils.highlightBlock(pos, new Color(0, 255, 255, 50), partialTicks, true);
+ RenderUtils.drawTextAtWorld("Drop Item", pos.getX() + 0.5f, pos.getY() + 0.3f, pos.getZ() + 0.5f, 0xFFFFFF00, 0.02f, false, false, partialTicks);
+ }
+
+
+ @Override
+ public String toString() {
+ return "DropItem\n- target: " + target.toString() + "\n- predicate: " + predicate.getClass().getSimpleName();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionInteract.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionInteract.java
new file mode 100755
index 00000000..b41e1b7a
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionInteract.java
@@ -0,0 +1,89 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.DungeonActionContext;
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.events.impl.PlayerInteractEntityEvent;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.Vec3;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionInteract extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<>();
+ private OffsetPoint target;
+ private Predicate<Entity> predicate = entity -> false;
+ private int radius;
+
+ public ActionInteract(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return interacted;
+ }
+
+ private boolean interacted = false;
+ @Override
+ public void onLivingInteract(DungeonRoom dungeonRoom, PlayerInteractEntityEvent event, ActionRouteProperties actionRouteProperties) {
+ if (interacted) return;
+
+ Vec3 spawnLoc = DungeonActionContext.getSpawnLocation().get(event.getEntity().getEntityId());
+ if (spawnLoc == null) {
+ return;
+ }
+ if (target.getBlockPos(dungeonRoom).distanceSq(spawnLoc.xCoord, spawnLoc.yCoord, spawnLoc.zCoord) > radius * radius) {
+ return;
+ }
+ if (!predicate.test(event.getEntity())) {
+ return;
+ }
+ interacted = true;
+ }
+
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ BlockPos pos = target.getBlockPos(dungeonRoom);
+ RenderUtils.highlightBlock(pos, new Color(0, 255,255,50),partialTicks, true);
+ RenderUtils.drawTextAtWorld("Interact", pos.getX() + 0.5f, pos.getY() + 0.3f, pos.getZ() + 0.5f, 0xFFFFFF00, 0.02f, false, false, partialTicks);
+ }
+
+ @Override
+ public String toString() {
+ return "InteractEntity\n- target: "+target.toString()+"\n- radius: "+radius+"\n- predicate: "+(predicate.test(null) ? "null" : predicate.getClass().getSimpleName());
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionKill.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionKill.java
new file mode 100755
index 00000000..94569ad1
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionKill.java
@@ -0,0 +1,90 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.DungeonActionContext;
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.Vec3;
+import net.minecraftforge.event.entity.living.LivingDeathEvent;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Predicate;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionKill extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<AbstractAction>();
+ private OffsetPoint target;
+ private Predicate<Entity> predicate = entity -> false;
+ private int radius;
+
+ public ActionKill(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ Vec3 spawn = new Vec3(target.getBlockPos(dungeonRoom));
+ for (Integer killed : DungeonActionContext.getKilleds()) {
+ if (DungeonActionContext.getSpawnLocation().get(killed) == null) continue;
+ if (DungeonActionContext.getSpawnLocation().get(killed).squareDistanceTo(spawn) < 100) {
+ return true;
+ }
+ }
+
+ return killed;
+ }
+
+ private boolean killed = false;
+ @Override
+ public void onLivingDeath(DungeonRoom dungeonRoom, LivingDeathEvent event, ActionRouteProperties actionRouteProperties) {
+ if (killed) return;
+
+ Vec3 spawnLoc = DungeonActionContext.getSpawnLocation().get(event.entity.getEntityId());
+ if (spawnLoc == null) return;
+ if (target.getBlockPos(dungeonRoom).distanceSq(spawnLoc.xCoord, spawnLoc.yCoord, spawnLoc.zCoord) > radius * radius) return;
+ if (!predicate.test(event.entity)) return;
+ killed = true;
+ }
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ BlockPos pos = target.getBlockPos(dungeonRoom);
+ RenderUtils.highlightBlock(pos, new Color(0, 255,255,50),partialTicks, true);
+ RenderUtils.drawTextAtWorld("Spawn", pos.getX() + 0.5f, pos.getY() + 0.3f, pos.getZ() + 0.5f, 0xFFFFFF00, 0.02f, false, false, partialTicks);
+ }
+
+ @Override
+ public String toString() {
+ return "KillEntity\n- target: "+target.toString()+"\n- radius: "+radius+"\n- predicate: "+(predicate.test(null) ? "null" : predicate.getClass().getSimpleName());
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMove.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMove.java
new file mode 100755
index 00000000..f499032d
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMove.java
@@ -0,0 +1,122 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.MathHelper;
+import net.minecraft.util.Vec3;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionMove extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<>();
+ private OffsetPoint target;
+
+ public ActionMove(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return target.getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()) < 25;
+ }
+
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ draw(dungeonRoom, partialTicks, actionRouteProperties, flag, target, poses);
+ }
+
+ static void draw(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag, OffsetPoint target, List<Vec3> poses) {
+ BlockPos pos = target.getBlockPos(dungeonRoom);
+
+ float distance = MathHelper.sqrt_double(pos.distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()));
+ float multiplier = distance / 120f; //mobs only render ~120 blocks away
+ if (flag) multiplier *= 2.0f;
+ float scale = 0.45f * multiplier;
+ scale *= 25.0 / 6.0;
+ if (actionRouteProperties.isBeacon()) {
+ if(!FeatureRegistry.RENDER_BREACONS.isEnabled()){
+ RenderUtils.renderBeaconBeam(pos.getX(), pos.getY(), pos.getZ(), actionRouteProperties.getBeaconBeamColor(), partialTicks);
+ }
+ RenderUtils.highlightBlock(pos, actionRouteProperties.getBeaconColor(), partialTicks);
+ }
+ if(!FeatureRegistry.RENDER_DESTENATION_TEXT.isEnabled()){
+ RenderUtils.drawTextAtWorld("Destination", pos.getX() + 0.5f, pos.getY() + 0.5f + scale, pos.getZ() + 0.5f, 0xFF00FF00, flag ? 2f : 1f, true, false, partialTicks);
+ }
+ RenderUtils.drawTextAtWorld(String.format("%.2f",MathHelper.sqrt_double(pos.distanceSq(Minecraft.getMinecraft().thePlayer.getPosition())))+"m", pos.getX() + 0.5f, pos.getY() + 0.5f - scale, pos.getZ() + 0.5f, 0xFFFFFF00, flag ? 2f : 1f, true, false, partialTicks);
+
+ if (!FeatureRegistry.SECRET_TOGGLE_KEY.isEnabled() || !FeatureRegistry.SECRET_TOGGLE_KEY.togglePathfindStatus) {
+ if (poses != null){
+ RenderUtils.drawLinesVec3(poses, actionRouteProperties.getLineColor(), actionRouteProperties.getLineWidth(), partialTicks, true);
+ }
+ }
+ }
+
+ private int tick = -1;
+ private List<Vec3> poses;
+ private Future<List<Vec3>> latestFuture;
+
+ @Override
+ public void onTick(DungeonRoom dungeonRoom, ActionRouteProperties actionRouteProperties) {
+ tick = (tick+1) % Math.max(1, actionRouteProperties.getLineRefreshRate());
+ if (latestFuture != null && latestFuture.isDone()) {
+ try {
+ poses = latestFuture.get();
+ latestFuture = null;
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (tick == 0 && actionRouteProperties.isPathfind() && latestFuture == null) {
+ if (!FeatureRegistry.SECRET_FREEZE_LINES.isEnabled() || poses == null) {
+ latestFuture = dungeonRoom.createEntityPathTo(dungeonRoom.getContext().getWorld(), Minecraft.getMinecraft().thePlayer, target.getBlockPos(dungeonRoom), Integer.MAX_VALUE, 10000);
+ }
+ }
+ }
+
+ public void forceRefresh(DungeonRoom dungeonRoom) {
+ if (latestFuture == null) {
+ latestFuture = dungeonRoom.createEntityPathTo(dungeonRoom.getContext().getWorld(), Minecraft.getMinecraft().thePlayer, target.getBlockPos(dungeonRoom), Integer.MAX_VALUE, 10000);
+ }
+ }
+ @Override
+ public String toString() {
+ return "Move\n- target: "+target.toString();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMoveNearestAir.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMoveNearestAir.java
new file mode 100755
index 00000000..54e8b1a8
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionMoveNearestAir.java
@@ -0,0 +1,92 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree.ActionRouteProperties;
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.Vec3;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionMoveNearestAir extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<>();
+ private OffsetPoint target;
+
+ public ActionMoveNearestAir(OffsetPoint target) {
+ this.target = target;
+ }
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return target.getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()) < 25;
+ }
+ @Override
+ public void onRenderWorld(DungeonRoom dungeonRoom, float partialTicks, ActionRouteProperties actionRouteProperties, boolean flag) {
+ ActionMove.draw(dungeonRoom, partialTicks, actionRouteProperties, flag, target, poses);
+ }
+
+ private int tick = -1;
+ private List<Vec3> poses;
+ private Future<List<Vec3>> latestFuture;
+ @Override
+ public void onTick(DungeonRoom dungeonRoom, ActionRouteProperties actionRouteProperties) {
+ tick = (tick+1) % Math.max(1, actionRouteProperties.getLineRefreshRate());
+ if (latestFuture != null && latestFuture.isDone()) {
+ try {
+ poses = latestFuture.get();
+ latestFuture = null;
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (tick == 0 && actionRouteProperties.isPathfind() && latestFuture == null) {
+ if (!FeatureRegistry.SECRET_FREEZE_LINES.isEnabled() || poses == null) {
+ latestFuture = dungeonRoom.createEntityPathTo(dungeonRoom.getContext().getWorld(), Minecraft.getMinecraft().thePlayer, target.getBlockPos(dungeonRoom), Integer.MAX_VALUE, 10000);
+ }
+ }
+ }
+
+
+ public void forceRefresh(DungeonRoom dungeonRoom) {
+ if (latestFuture == null) {
+ latestFuture = dungeonRoom.createEntityPathTo(dungeonRoom.getContext().getWorld(), Minecraft.getMinecraft().thePlayer, target.getBlockPos(dungeonRoom), Integer.MAX_VALUE, 10000);
+ }
+ }
+ @Override
+ public String toString() {
+ return "MoveNearestAir\n- target: "+target.toString();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionRoot.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionRoot.java
new file mode 100755
index 00000000..23b9fdce
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/ActionRoot.java
@@ -0,0 +1,47 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+public class ActionRoot extends AbstractAction {
+ private Set<AbstractAction> preRequisite = new HashSet<>();
+
+ @Override
+ public Set<AbstractAction> getPreRequisites(DungeonRoom dungeonRoom) {
+ return preRequisite;
+ }
+
+ @Override
+ public boolean isComplete(DungeonRoom dungeonRoom) {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "Action Root";
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRoute.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRoute.java
new file mode 100644
index 00000000..17cea18d
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRoute.java
@@ -0,0 +1,136 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree;
+
+import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter;
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.*;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.mod.events.impl.PlayerInteractEntityEvent;
+import lombok.Getter;
+import net.minecraft.client.Minecraft;
+import net.minecraftforge.event.entity.living.LivingDeathEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+
+import java.util.List;
+
+public class ActionRoute {
+ @Getter
+ private final String mechanic;
+ @Getter
+ private final String state;
+
+ @Getter
+ private int current;
+ @Getter
+ private final List<AbstractAction> actions;
+
+ private final DungeonRoom dungeonRoom;
+
+ @Getter
+ private final ActionRouteProperties actionRouteProperties;
+
+ public ActionRoute(DungeonRoom dungeonRoom, String mechanic, String state, ActionRouteProperties actionRouteProperties) {
+ this.mechanic = mechanic;
+ this.state = state;
+ this.actionRouteProperties = actionRouteProperties;
+
+ System.out.println("Creating Action Route with mechanic:" + mechanic + " State:" + state);
+ ActionChangeState actionChangeState = new ActionChangeState(mechanic, state);
+ ActionTree tree= ActionTree.buildActionTree(actionChangeState, dungeonRoom);
+ actions = ActionTreeUtil.linearifyActionTree(tree);
+ actions.add(new ActionComplete());
+ ChatTransmitter.sendDebugChat("Created ActionRoute with " + actions.size() + " steps");
+ ChatTransmitter.sendDebugChat("========== STEPS ==========");
+ for (AbstractAction action : actions) {
+ ChatTransmitter.sendDebugChat(action.toString());
+ }
+ ChatTransmitter.sendDebugChat("=========== END ===========");
+
+
+ current = 0;
+ this.dungeonRoom = dungeonRoom;
+ }
+
+ public AbstractAction next() {
+ current ++;
+ if (current >= actions.size()) {
+ current = actions.size() - 1;
+ }
+ return getCurrentAction();
+ }
+
+ public AbstractAction prev() {
+ current --;
+ if (current < 0) {
+ current = 0;
+ }
+ return getCurrentAction();
+ }
+
+ public AbstractAction getCurrentAction() {
+ return actions.get(current);
+ }
+
+
+
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ getCurrentAction().onPlayerInteract(dungeonRoom, event, actionRouteProperties );
+ }
+ public void onLivingDeath(LivingDeathEvent event) {
+ getCurrentAction().onLivingDeath(dungeonRoom, event, actionRouteProperties );
+ }
+ public void onRenderWorld(float partialTicks, boolean flag) {
+
+ if (current -1 >= 0) {
+ AbstractAction abstractAction = actions.get(current - 1);
+ if(((abstractAction instanceof ActionMove && ((ActionMove) abstractAction).getTarget().getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()) >= 25)
+ || (abstractAction instanceof ActionMoveNearestAir && ((ActionMoveNearestAir) abstractAction).getTarget().getBlockPos(dungeonRoom).distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()) >= 25))){
+ abstractAction.onRenderWorld(dungeonRoom, partialTicks, actionRouteProperties, flag );
+ }
+ }
+ getCurrentAction().onRenderWorld(dungeonRoom, partialTicks, actionRouteProperties, flag);
+
+
+ getCurrentAction().onRenderWorld(dungeonRoom, partialTicks, actionRouteProperties, flag);
+ }
+
+ public void onRenderScreen(float partialTicks) {
+ getCurrentAction().onRenderScreen(dungeonRoom, partialTicks, actionRouteProperties);
+ }
+
+ public void onTick() {
+ AbstractAction currentAction = getCurrentAction();
+
+ currentAction.onTick(dungeonRoom, actionRouteProperties);
+ if (this.current -1 >= 0 && (actions.get(this.current-1) instanceof ActionMove || actions.get(this.current-1) instanceof ActionMoveNearestAir)) actions.get(this.current-1).onTick(dungeonRoom, actionRouteProperties );
+
+ if (dungeonRoom.getMechanics().get(mechanic).getCurrentState(dungeonRoom).equals(state)) {
+ this.current = actions.size() - 1;
+ }
+
+ if (currentAction.isComplete(dungeonRoom)) {
+ next();
+ }
+ }
+
+ public void onLivingInteract(PlayerInteractEntityEvent event) {
+ getCurrentAction().onLivingInteract(dungeonRoom, event, actionRouteProperties );
+ }
+
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRouteProperties.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRouteProperties.java
new file mode 100644
index 00000000..df32e718
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionRouteProperties.java
@@ -0,0 +1,16 @@
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree;
+
+import kr.syeyoung.dungeonsguide.mod.config.types.AColor;
+import lombok.Data;
+
+@Data
+public class ActionRouteProperties {
+ private boolean pathfind;
+ private int lineRefreshRate;
+ private AColor lineColor;
+ private float lineWidth;
+
+ private boolean beacon;
+ private AColor beaconColor;
+ private AColor beaconBeamColor;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTree.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTree.java
new file mode 100755
index 00000000..99846fc7
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTree.java
@@ -0,0 +1,94 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.AbstractAction;
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.ActionRoot;
+import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+@Data
+public class ActionTree implements Cloneable {
+ @EqualsAndHashCode.Exclude
+ private Set<ActionTree> parent;
+ private AbstractAction current;
+ private Set<ActionTree> children;
+
+ @Override
+ public int hashCode() { return current == null ? 0 : current.hashCode(); }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ActionTree that = (ActionTree) o;
+ return Objects.equals(parent, that.parent) && Objects.equals(current, that.current) && Objects.equals(children, that.children);
+ }
+
+ public static ActionTree buildActionTree(Set<AbstractAction> actions, DungeonRoom dungeonRoom) {
+ ActionRoot root = new ActionRoot();
+ root.setPreRequisite(actions);
+ ActionTree tree = new ActionTree();
+ tree.setParent(new HashSet<>());
+ tree.setCurrent(root);
+ HashSet<ActionTree> set = new HashSet<>();
+ for (AbstractAction action : actions) {
+ set.add(buildActionTree(tree, action, dungeonRoom, new HashMap<>()));
+ }
+ tree.setChildren(set);
+ return tree;
+ }
+ public static ActionTree buildActionTree(AbstractAction actions, DungeonRoom dungeonRoom) {
+ return buildActionTree(null, actions, dungeonRoom, new HashMap<>());
+ }
+
+
+
+ private static ActionTree buildActionTree(ActionTree parent, @NotNull AbstractAction action,@NotNull DungeonRoom dungeonRoom, @NotNull Map<AbstractAction, ActionTree> alreadyBuilt) {
+ if (alreadyBuilt.containsKey(action)) {
+ ActionTree tree = alreadyBuilt.get(action);
+ tree.getParent().add(parent);
+ return tree;
+ }
+
+ ActionTree tree = new ActionTree();
+ alreadyBuilt.put(action, tree);
+ tree.setParent(new HashSet<>());
+ if (parent != null) {
+ tree.getParent().add(parent);
+ }
+ tree.setCurrent(action);
+ HashSet<ActionTree> set = new HashSet<>();
+
+ Set<AbstractAction> preRequisites = action.getPreRequisites(dungeonRoom);
+ if(preRequisites != null){
+ for (AbstractAction action2 : preRequisites) {
+ ActionTree e = buildActionTree(tree, action2, dungeonRoom, alreadyBuilt);
+ set.add(e);
+ }
+ }
+
+ tree.setChildren(set);
+ return tree;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTreeUtil.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTreeUtil.java
new file mode 100644
index 00000000..18c17c17
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/actions/tree/ActionTreeUtil.java
@@ -0,0 +1,83 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.actions.tree;
+
+import kr.syeyoung.dungeonsguide.mod.dungeon.actions.AbstractAction;
+
+import java.util.*;
+
+public class ActionTreeUtil {
+ public static List<AbstractAction> linearifyActionTree(ActionTree input) {
+ ActionTree tree = copyActionTree(input);
+
+ List<AbstractAction> actions = new ArrayList<AbstractAction>();
+
+ int plsHalt = 0;
+ while (tree.getChildren().size() != 0) {
+ plsHalt ++;
+ if (plsHalt > 1000000) throw new IllegalStateException("Linearifying process ran for 1 million cycle");
+ Set<ActionTree> visited = new HashSet<ActionTree>();
+ ActionTree curr = tree;
+
+ int plsHalt2 = 0;
+ while (curr.getChildren().size() != 0) {
+ plsHalt2 ++;
+ if (plsHalt2 > 1000000) throw new IllegalStateException("Finding the leaf of tree ran for 1 million cycles");
+ if (visited.contains(curr)) throw new IllegalStateException("Circular Reference Detected");
+ visited.add(curr);
+ curr = curr.getChildren().iterator().next();
+ }
+
+ plsHalt2 =0;
+ while(curr.getChildren().size() == 0) {
+ plsHalt2 ++;
+ if (plsHalt2 > 1000000) throw new IllegalStateException("Building of array ran for 1 million cycles");
+
+ actions.add(curr.getCurrent());
+ if (curr.getParent().size() == 0) break;
+ for (ActionTree parentTree:curr.getParent())
+ parentTree.getChildren().remove(curr);
+ curr = curr.getParent().iterator().next();
+ }
+ }
+ return actions;
+ }
+
+ public static ActionTree copyActionTree(ActionTree tree) {
+ Map<ActionTree, ActionTree> built = new HashMap<ActionTree, ActionTree>();
+ if (tree.getParent().size() != 0) throw new IllegalArgumentException("that is not head of tree");
+ return copyActionTree(tree, built);
+ }
+ private static ActionTree copyActionTree(ActionTree tree, Map<ActionTree, ActionTree> preBuilts) {
+ if (preBuilts.containsKey(tree)) return preBuilts.get(tree);
+
+ ActionTree clone = new ActionTree();
+ preBuilts.put(tree, clone);
+
+ clone.setCurrent(tree.getCurrent());
+ clone.setParent(new HashSet<ActionTree>());
+ clone.setChildren(new HashSet<ActionTree>());
+ for (ActionTree tree3 : tree.getChildren()) {
+ ActionTree clone3 = copyActionTree(tree3, preBuilts);
+ clone3.getParent().add(clone);
+ clone.getChildren().add(clone3);
+ }
+ return clone;
+ }
+}