aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorCobble8 <41165207+Cobble8@users.noreply.github.com>2022-11-02 11:46:03 -0400
committerGitHub <noreply@github.com>2022-11-02 16:46:03 +0100
commit7c59b2081814cf5ad0eccdf8371dbee410ae85f3 (patch)
tree18279433aeaefd9c649c77ebea541d08a7f5991e /src/main/java
parent3ca2f856a5c2aaa5f3ea7e6136b8084d98279af1 (diff)
downloadNotEnoughUpdates-7c59b2081814cf5ad0eccdf8371dbee410ae85f3.tar.gz
NotEnoughUpdates-7c59b2081814cf5ad0eccdf8371dbee410ae85f3.tar.bz2
NotEnoughUpdates-7c59b2081814cf5ad0eccdf8371dbee410ae85f3.zip
Custom Wither Cloak (#375)
Co-authored-by: nopo <nopotheemail@gmail.com> Co-authored-by: IRONM00N <64110067+IRONM00N@users.noreply.github.com> Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java28
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java129
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityChargedCreeper.java49
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java110
5 files changed, 305 insertions, 13 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index fb6e0901..6c6c7169 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -61,6 +61,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.PowerStoneStatsDisplay;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu;
+import io.github.moulberry.notenoughupdates.miscfeatures.WitherCloakChanger;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBlockSounds;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures;
@@ -290,6 +291,7 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(new Constants());
MinecraftForge.EVENT_BUS.register(new DungeonMap());
MinecraftForge.EVENT_BUS.register(new SunTzu());
+ MinecraftForge.EVENT_BUS.register(new WitherCloakChanger());
MinecraftForge.EVENT_BUS.register(new MiningStuff());
MinecraftForge.EVENT_BUS.register(FairySouls.getInstance());
MinecraftForge.EVENT_BUS.register(new CrystalOverlay());
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
index d7bd097a..107c79e9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
@@ -37,11 +37,14 @@ import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.Vec3;
import net.minecraft.util.Vec3i;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.util.vector.Vector3f;
+import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -389,6 +392,31 @@ public class RenderUtils {
renderWayPoint(Arrays.asList(""), new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks, true);
}
+ public static void drawFilledQuadWithTexture(Vec3 p1, Vec3 p2, Vec3 p3, Vec3 p4, float alpha, ResourceLocation texture) {
+ GlStateManager.pushMatrix();
+ Entity v = Minecraft.getMinecraft().getRenderViewEntity();
+ double vX = v.lastTickPosX + (v.posX - v.lastTickPosX);
+ double vY = v.lastTickPosY + (v.posY - v.lastTickPosY);
+ double vZ = v.lastTickPosZ + (v.posZ - v.lastTickPosZ);
+
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldrenderer = tessellator.getWorldRenderer();
+
+ GlStateManager.enableTexture2D();
+ GlStateManager.enableBlend();
+ GlStateManager.disableCull();
+ GlStateManager.color(1.0f, 1.0f, 1.0f, alpha);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
+ worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
+ worldrenderer.pos(p1.xCoord-vX, p1.yCoord-vY, p1.zCoord-vZ).tex(0, 0).endVertex(); //Top Left
+ worldrenderer.pos(p2.xCoord-vX, p2.yCoord-vY, p2.zCoord-vZ).tex(1, 0).endVertex(); //Top Right
+ worldrenderer.pos(p3.xCoord-vX, p3.yCoord-vY, p3.zCoord-vZ).tex(1, 1).endVertex(); //Bottom Right
+ worldrenderer.pos(p4.xCoord-vX, p4.yCoord-vY, p4.zCoord-vZ).tex(0, 1).endVertex(); //Bottom Left
+ tessellator.draw();
+ GlStateManager.enableCull();
+ GlStateManager.popMatrix();
+ }
+
public static void renderWayPoint(List<String> lines, Vector3f loc, float partialTicks, boolean onlyShowDistance) {
GlStateManager.alphaFunc(516, 0.1F);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java
new file mode 100644
index 00000000..84ee76c5
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.Vec3;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+public class WitherCloakChanger {
+ public static boolean isCloakActive = false;
+ public static long lastDeactivate = System.currentTimeMillis();
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onChatMessage(ClientChatReceivedEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return;
+ if (event.message.getUnformattedText().startsWith("Creeper Veil ")) {
+ if (isCloakActive && !event.message.getUnformattedText().equals("Creeper Veil Activated!")) {
+ isCloakActive = false;
+ lastDeactivate = System.currentTimeMillis();
+ } else {
+ isCloakActive = true;
+ }
+ } else if (event.message.getUnformattedText().startsWith("Not enough mana! Creeper Veil De-activated!")) {
+ isCloakActive = false;
+ lastDeactivate = System.currentTimeMillis();
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Unload event) {
+ isCloakActive = false;
+ }
+
+ private static final ResourceLocation witherCloakShield = new ResourceLocation(
+ "notenoughupdates:wither_cloak_shield.png");
+
+ @SubscribeEvent
+ public void onRenderLast(RenderWorldLastEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.isOnSkyblock() || !isCloakActive ||
+ !NotEnoughUpdates.INSTANCE.config.itemOverlays.customWitherCloakToggle) return;
+ Minecraft mc = Minecraft.getMinecraft();
+
+ //CONSTANTS (Other contribs, mess with these as you wish, but you should know I chose these for a reason)
+ final double shieldWidth = 0.8d; //How wide they are
+ final double shieldHeight = 2.0d; //How tall they are
+ final double accuracy =
+ 4.0d; //Will be accurate to 1/accuracy of a degree (so updates every 0.25 degrees with an accuracy of 4)
+
+ for (int i = 0; i < NotEnoughUpdates.INSTANCE.config.itemOverlays.customWitherCloakCount; i++) {
+ double angle = (int) (
+ ((System.currentTimeMillis() / 30 * NotEnoughUpdates.INSTANCE.config.itemOverlays.customWitherCloakSpeed *
+ -0.5 * accuracy)) % (360 * accuracy)) / accuracy;
+ angle += (360d / NotEnoughUpdates.INSTANCE.config.itemOverlays.customWitherCloakCount) * i;
+ angle %= 360;
+ double posX = mc.thePlayer.posX - (shieldWidth / 2);
+ double posY = mc.thePlayer.posY;
+ double posZ = mc.thePlayer.posZ + NotEnoughUpdates.INSTANCE.config.itemOverlays.customWitherCloakDistance;
+
+ Vec3 topLeft = rotateAboutOrigin(
+ mc.thePlayer.posX,
+ mc.thePlayer.posZ,
+ angle,
+ new Vec3(posX, posY + shieldHeight, posZ)
+ );
+ Vec3 topRight = rotateAboutOrigin(
+ mc.thePlayer.posX,
+ mc.thePlayer.posZ,
+ angle,
+ new Vec3(posX + shieldWidth, posY + shieldHeight, posZ)
+ );
+ Vec3 bottomRight = rotateAboutOrigin(
+ mc.thePlayer.posX,
+ mc.thePlayer.posZ,
+ angle,
+ new Vec3(posX + shieldWidth, posY, posZ)
+ );
+ Vec3 bottomLeft = rotateAboutOrigin(mc.thePlayer.posX, mc.thePlayer.posZ, angle, new Vec3(posX, posY, posZ));
+ RenderUtils.drawFilledQuadWithTexture(
+ topLeft,
+ topRight,
+ bottomRight,
+ bottomLeft, /*NotEnoughUpdates.INSTANCE.config.misc.customWitherCloakTransparency*/
+ 1.0f,
+ witherCloakShield
+ );
+ }
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(
+ GL11.GL_SRC_ALPHA,
+ GL11.GL_ONE_MINUS_SRC_ALPHA,
+ GL11.GL_ONE,
+ GL11.GL_ONE_MINUS_SRC_ALPHA
+ );
+ }
+
+ private static Vec3 rotateAboutOrigin(double originX, double originZ, double angle, Vec3 point) {
+ double a = angle * Math.PI / 180;
+ double newX = originX + (Math.cos(a) * (point.xCoord - originX) + Math.sin(a) * (point.zCoord - originZ));
+ double newZ = originZ + (-Math.sin(a) * (point.xCoord - originX) + Math.cos(a) * (point.zCoord - originZ));
+ return new Vec3(newX, point.yCoord, newZ);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityChargedCreeper.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityChargedCreeper.java
new file mode 100644
index 00000000..a9b88d6b
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityChargedCreeper.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.mixins;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.miscfeatures.WitherCloakChanger;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.entity.layers.LayerCreeperCharge;
+import net.minecraft.entity.monster.EntityCreeper;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(LayerCreeperCharge.class)
+public abstract class MixinEntityChargedCreeper {
+
+ @Inject(method = "doRenderLayer(Lnet/minecraft/entity/monster/EntityCreeper;FFFFFFF)V", at = @At("HEAD"), cancellable = true)
+ public void cancelChargedCreeperLayer(EntityCreeper creeper, float f, float g, float partialTicks, float h, float i, float j, float scale, CallbackInfo ci) {
+ //Wither Cloak Creepers: Is toggled on, Are invisible, 20 max health, usually less than 7.5M from the player, only existent when active, and only in sb obviously
+ boolean isWitherCloak =
+ NotEnoughUpdates.INSTANCE.config.itemOverlays.customWitherCloakToggle && creeper.isInvisible() &&
+ creeper.getMaxHealth() == 20.0f && creeper.getDistanceToEntity(Minecraft.getMinecraft().thePlayer) < 7.5f &&
+ (WitherCloakChanger.isCloakActive || System.currentTimeMillis() - WitherCloakChanger.lastDeactivate < 300) &&
+ NotEnoughUpdates.INSTANCE.isOnSkyblock();
+ if (isWitherCloak) {
+ if (ci.isCancellable()) {
+ ci.cancel();
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java
index 3222ce46..ee1e9992 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java
@@ -28,6 +28,7 @@ import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditor
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorColour;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDraggableList;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorFSR;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption;
@@ -206,7 +207,7 @@ public class ItemOverlays {
name = "Etherwarp",
desc = ""
)
- @ConfigEditorAccordion(id = 7)
+ @ConfigEditorAccordion(id = 3)
public boolean etherwarpAccordion = false;
@Expose
@@ -215,7 +216,7 @@ public class ItemOverlays {
desc = "Zoom in on targeted blocks with etherwarp, making it easier to adjust at a distance"
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 7)
+ @ConfigAccordionId(id = 3)
public boolean etherwarpZoom = true;
@Expose
@@ -224,7 +225,7 @@ public class ItemOverlays {
desc = "Display an overlay which tells you if the etherwarp will fail."
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 7)
+ @ConfigAccordionId(id = 3)
public boolean enableEtherwarpHelperOverlay = true;
@Expose
@@ -233,7 +234,7 @@ public class ItemOverlays {
desc = "Display an overlay that tells you what block you will TP to."
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 7)
+ @ConfigAccordionId(id = 3)
public boolean enableEtherwarpBlockOverlay = true;
@Expose
@@ -242,7 +243,7 @@ public class ItemOverlays {
desc = "Don't display the etherwarp block overlay when you can't TP to the block"
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 7)
+ @ConfigAccordionId(id = 3)
public boolean disableOverlayWhenFailed = false;
@Expose
@@ -252,14 +253,14 @@ public class ItemOverlays {
searchTags = "color"
)
@ConfigEditorColour
- @ConfigAccordionId(id = 7)
+ @ConfigAccordionId(id = 3)
public String etherwarpHighlightColour = "00:70:156:8:96";
@ConfigOption(
name = "Bonemerang Overlay",
desc = ""
)
- @ConfigEditorAccordion(id = 3)
+ @ConfigEditorAccordion(id = 4)
public boolean bonemerangAccordion = false;
@Expose
@@ -268,7 +269,7 @@ public class ItemOverlays {
desc = "Shows info about the bonemerang while holding it."
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 3)
+ @ConfigAccordionId(id = 4)
public boolean enableBonemerangOverlay = true;
@Expose
@@ -277,7 +278,7 @@ public class ItemOverlays {
desc = "Highlight entities that will be hit by your bonemerang"
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 3)
+ @ConfigAccordionId(id = 4)
public boolean highlightTargeted = true;
@Expose
@@ -289,7 +290,7 @@ public class ItemOverlays {
runnableId = 9,
buttonText = "Edit"
)
- @ConfigAccordionId(id = 3)
+ @ConfigAccordionId(id = 4)
public Position bonemerangPosition = new Position(-1, -1);
@Expose
@@ -304,7 +305,7 @@ public class ItemOverlays {
"\u00a77Targets: \u00a76\u00a7l10"
}
)
- @ConfigAccordionId(id = 3)
+ @ConfigAccordionId(id = 4)
public List<Integer> bonemerangOverlayText = new ArrayList<>(Arrays.asList(0, 1));
@Expose
@@ -315,7 +316,7 @@ public class ItemOverlays {
@ConfigEditorDropdown(
values = {"Background", "No Shadow", "Shadow Only", "Full Shadow"}
)
- @ConfigAccordionId(id = 3)
+ @ConfigAccordionId(id = 4)
public int bonemerangOverlayStyle = 0;
@Expose
@ConfigOption(
@@ -324,7 +325,7 @@ public class ItemOverlays {
"Might cause some lag."
)
@ConfigEditorBoolean
- @ConfigAccordionId(id = 3)
+ @ConfigAccordionId(id = 4)
public boolean bonemerangFastUpdate = false;
@ConfigOption(
@@ -386,6 +387,89 @@ public class ItemOverlays {
@ConfigAccordionId(id = 6)
public boolean enableDirtWandOverlay = true;
+ @ConfigOption(
+ name="Custom Wither Cloak",
+ desc = ""
+ )
+ @ConfigEditorAccordion(id = 7)
+ public boolean customWitherCloakAccordion = false;
+
+ @Expose
+ @ConfigAccordionId(id = 7)
+ @ConfigOption(
+ name = "Enable Custom Wither Cloak",
+ desc = "Replaces Hypixel Wither Cloak with custom shields due to the Hypixel Wither Cloak being difficult to see through"
+ )
+ @ConfigEditorBoolean
+ public boolean customWitherCloakToggle = true;
+
+ @Expose
+ @ConfigAccordionId(id = 7)
+ @ConfigOption(
+ name = "Shield Count",
+ desc = "The amount of shields circling the player\n0 = No shields"
+ )
+ @ConfigEditorSlider(
+ minValue = 0,
+ maxValue = 20,
+ minStep = 1
+ )
+ public int customWitherCloakCount = 6;
+
+ @Expose
+ @ConfigAccordionId(id = 7)
+ @ConfigOption(
+ name = "Shield Speed",
+ desc = "How fast they circle the player\n0 = Not moving\nNegative = Spinning opposite direction"
+ )
+ @ConfigEditorSlider(
+ minValue = -20f,
+ maxValue = 20f,
+ minStep = 1.0f
+ )
+ public double customWitherCloakSpeed = 2d;
+
+ /*@Expose
+ @ConfigAccordionId(id = 7)
+ @ConfigOption(
+ name = "Shield Transparency",
+ desc = "Changes how visible each shield is\n0 = Invisible"
+ )
+ @ConfigEditorSlider(
+ minValue = 0f,
+ maxValue = 1,
+ minStep = 0.1f
+ )
+ public float customWitherCloakTransparency = 1.0f;
+
+ Couldn't get this to work and couldn't for the life of me figure out why - Cobble8
+ */
+
+ @Expose
+ @ConfigAccordionId(id = 7)
+ @ConfigOption(
+ name = "Shield Distance From Player",
+ desc = "How far (in blocks) each shield is from the player\n" +
+ "0 = Inside the player"
+ )
+ @ConfigEditorSlider(
+ minValue = 0f,
+ maxValue = 3.0f,
+ minStep = 0.1f
+ )
+ public float customWitherCloakDistance = 1.2f;
+
+ @Expose
+ @ConfigAccordionId(id = 7)
+ @ConfigOption(
+ name = "\u00A7aInspiration:",
+ desc = "\u00A76u/Sori0612 \u00A77on \u00A7cReddit\n\n\u00A78https://tinyurl.com/creeperveil"
+ )
+ @ConfigEditorFSR(
+ runnableId = 12
+ )
+ public boolean customWitherCloakCredit = false;
+
@Expose
@ConfigOption(
name = "Pickaxe Ability Cooldown",