Skip to content

Commit

Permalink
Add config screen and custom item use cooldown
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryhon0 committed May 23, 2024
1 parent 47521a9 commit 837d1d3
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 27 deletions.
9 changes: 3 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ base {
}

repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
maven { url = "https://maven.terraformersmc.com/" }
}

dependencies {
Expand All @@ -26,7 +22,8 @@ dependencies {

// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"


modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")
}

processResources {
Expand Down
5 changes: 3 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ yarn_mappings=1.20.2+build.4
loader_version=0.15.11

# Mod Properties
mod_version=2.1.0
mod_version=2.2.0
maven_group=xyz.ryhon.replanterplus
archives_base_name=replanter-plus

# Dependencies
fabric_version=0.91.6+1.20.2
fabric_version=0.91.6+1.20.2
modmenu_version=8.0.1
163 changes: 163 additions & 0 deletions src/main/java/xyz/ryhon/replanterplus/ConfigScreen.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package xyz.ryhon.replanterplus;

import java.util.function.Consumer;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ButtonTextures;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.SliderWidget;
import net.minecraft.client.gui.widget.TextWidget;
import net.minecraft.client.gui.widget.ToggleButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

public class ConfigScreen extends Screen {
Screen parent;

SwitchButton enabledButton;
SwitchButton sneakToggleButton;
SimpleSlider tickDelaySlider;
ButtonWidget doneButton;

public ConfigScreen(Screen parent) {
super(Text.empty());
this.parent = parent;
}

@Override
protected void init() {
super.init();

int buttonWidth = 48;
int buttonHeight = 18;
int panelWidth = 256;

enabledButton = new SwitchButton(
(width / 2) + (panelWidth / 2) - (buttonWidth), (height / 2) - (buttonHeight * 2),
buttonWidth, buttonHeight, ReplanterPlus.enabled) {
@Override
public void setToggled(boolean toggled) {
super.setToggled(toggled);
ReplanterPlus.enabled = toggled;
}
};
addDrawableChild(enabledButton);
addSelectableChild(enabledButton);
TextWidget t = new TextWidget(Text.translatable("replanter.configscreen.enabled"), textRenderer);
t.setPosition((width / 2) - (panelWidth / 2),
enabledButton.getY() + (buttonHeight / 2) - (textRenderer.fontHeight / 2));
addDrawableChild(t);

sneakToggleButton = new SwitchButton(
enabledButton.getX(), enabledButton.getY() + enabledButton.getHeight(),
enabledButton.getWidth(), enabledButton.getHeight(),
ReplanterPlus.sneakToggle) {
@Override
public void setToggled(boolean toggled) {
super.setToggled(toggled);
ReplanterPlus.sneakToggle = toggled;
}
};
addDrawableChild(sneakToggleButton);
addSelectableChild(sneakToggleButton);
t = new TextWidget(Text.translatable("replanter.configscreen.sneakToggle"), textRenderer);
t.setPosition((width / 2) - (panelWidth / 2),
sneakToggleButton.getY() + (buttonHeight / 2) - (textRenderer.fontHeight / 2));
addDrawableChild(t);

t = new TextWidget(Text.translatable("replanter.configscreen.tickDelay"), textRenderer);
t.setPosition((width / 2) - (panelWidth / 2),
sneakToggleButton.getY() + buttonHeight);
addDrawableChild(t);

tickDelaySlider = new SimpleSlider(0, 8);
tickDelaySlider.setPosition(t.getX(), t.getY() + t.getHeight());
tickDelaySlider.setWidth(panelWidth);
tickDelaySlider.setHeight(24);
tickDelaySlider.setIValue(ReplanterPlus.useDelay);
tickDelaySlider.onValue = (Long l) ->
{
long i = l;
ReplanterPlus.useDelay = (int)i;
};
addDrawableChild(tickDelaySlider);
addSelectableChild(tickDelaySlider);

doneButton = ButtonWidget.builder(Text.translatable("replanter.configscreen.done"), (ButtonWidget b) -> {
close();
})
.size(96, 24)
.position((width / 2) - (96 / 2), tickDelaySlider.getY() + tickDelaySlider.getHeight() + 8)
.build();
addDrawableChild(doneButton);
addSelectableChild(doneButton);
}

public static class SimpleSlider extends SliderWidget {
long min, max;
long iValue;
public Consumer<Long> onValue;

public SimpleSlider(long min, long max) {
super(0, 0, 0, 0, Text.empty(), 0);
this.min = min;
this.max = max;
updateMessage();
}

public void setIValue(long v) {
iValue = v;
setValue((v - min) / (double) (max - min));
}

@Override
protected void applyValue() {
iValue = (long) Math.round(value * (max - min)) + min;
setIValue(iValue);

updateMessage();
if (onValue != null)
onValue.accept(iValue);
}

@Override
protected void updateMessage() {
setMessage(Text.literal(iValue + " / " + max));
}
}

public class SwitchButton extends ToggleButtonWidget {
private static final ButtonTextures TEXTURES = new ButtonTextures(new Identifier("widget/button"),
new Identifier("widget/button"), new Identifier("widget/button_highlighted"));

public SwitchButton(int x, int y, int width, int height, boolean toggled) {
super(x, y, width, height, toggled);
setTextures(TEXTURES);
}

@Override
protected boolean clicked(double mouseX, double mouseY) {
if (super.clicked(mouseX, mouseY)) {
setToggled(!toggled);
return true;
}
return false;
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(textRenderer,
Text.translatable("replanter.switchbutton.label." + (toggled ? "on" : "off")),
getX() + (width / 2), getY() + (height / 2) - (textRenderer.fontHeight / 2),
toggled ? 0x00ff00 : 0xff0000);
}
}

@Override
public void close() {
client.setScreen(parent);
ReplanterPlus.saveConfig();
}
}
14 changes: 14 additions & 0 deletions src/main/java/xyz/ryhon/replanterplus/ModMenuAPIImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package xyz.ryhon.replanterplus;

import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;

public class ModMenuAPIImpl implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return (currentScreen) ->
{
return new ConfigScreen(currentScreen);
};
}
}
93 changes: 92 additions & 1 deletion src/main/java/xyz/ryhon/replanterplus/ReplanterPlus.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
package xyz.ryhon.replanterplus;

import java.nio.file.Files;
import java.nio.file.Path;

import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;

import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.player.PlayerEntity;
Expand All @@ -29,10 +43,44 @@ public class ReplanterPlus implements ModInitializer {
private static final MinecraftClient mc = MinecraftClient.getInstance();
static Boolean useIgnore = false;

public static Boolean enabled = true;
public static Boolean sneakToggle = true;
public static int useDelay = 4;

int ticks = 0;
final int autoSaveTicks = 20 * 60 * 3;

@Override
public void onInitialize() {
loadConfig();

String bindCategory = "category.replanter";
KeyBinding menuBind = new KeyBinding("key.replanter.menu", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN,
bindCategory);
KeyBindingHelper.registerKeyBinding(menuBind);
KeyBinding toggleBind = new KeyBinding("key.replanter.toggle", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN,
bindCategory);
KeyBindingHelper.registerKeyBinding(toggleBind);

ClientTickEvents.END_CLIENT_TICK.register((client) -> {
ticks++;
if (ticks == autoSaveTicks) {
ticks = 0;
saveConfig();
}

if (menuBind.wasPressed())
client.setScreen(new ConfigScreen(null));

if (toggleBind.wasPressed())
enabled = !enabled;
});

UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
if (player instanceof ServerPlayerEntity || useIgnore || player.isSneaking())
if (player instanceof ServerPlayerEntity || useIgnore)
return ActionResult.PASS;

if (!enabled || (sneakToggle && player.isSneaking()))
return ActionResult.PASS;

ClientPlayerEntity p = (ClientPlayerEntity) player;
Expand Down Expand Up @@ -122,8 +170,11 @@ void breakAndReplant(ClientPlayerEntity player, BlockHitResult hit) {
mc.interactionManager.attackBlock(hit.getBlockPos(), hit.getSide());

if (findAndEquipSeed(player, seed)) {
useIgnore = true;
mc.interactionManager.interactBlock(player, Hand.OFF_HAND, hit.withBlockPos(
hit.getBlockPos()));
useIgnore = false;
mc.itemUseCooldown = useDelay;
} else {
player.sendMessage(
Text.translatable(seed.getTranslationKey())
Expand Down Expand Up @@ -152,6 +203,7 @@ void breakAndReplantCocoa(ClientPlayerEntity p, BlockState state, BlockHitResult
useIgnore = true;
mc.interactionManager.interactBlock(p, Hand.OFF_HAND, placeHit);
useIgnore = false;
mc.itemUseCooldown = useDelay;
} else {
p.sendMessage(
Text.translatable(state.getBlock().asItem().getTranslationKey())
Expand Down Expand Up @@ -213,4 +265,43 @@ void holdFortuneItem(PlayerEntity p) {
mc.interactionManager.syncSelectedSlot();
}
}

static Path configDir = FabricLoader.getInstance().getConfigDir().resolve("replanterplus");
static Path configFile = configDir.resolve("config.json");

static void loadConfig() {
try {
Files.createDirectories(configDir);
if (!Files.exists(configFile))
return;

String str = Files.readString(configFile);
JsonObject jo = (JsonObject) JsonParser.parseString(str);

if (jo.has("enabled"))
enabled = jo.get("enabled").getAsBoolean();
if (jo.has("sneakToggle"))
sneakToggle = jo.get("sneakToggle").getAsBoolean();
if (jo.has("useDelay"))
useDelay = jo.get("useDelay").getAsInt();

} catch (Exception e) {
LOGGER.error("Failed to load config", e);
}
}

static void saveConfig() {
JsonObject jo = new JsonObject();

jo.add("enabled", new JsonPrimitive(enabled));
jo.add("sneakToggle", new JsonPrimitive(sneakToggle));
jo.add("useDelay", new JsonPrimitive(useDelay));

try {
Files.createDirectories(configDir);
Files.writeString(configFile, new Gson().toJson(jo));
} catch (Exception e) {
LOGGER.error("Failed to save config", e);
}
}
}
15 changes: 0 additions & 15 deletions src/main/java/xyz/ryhon/replanterplus/mixin/ExampleMixin.java

This file was deleted.

11 changes: 10 additions & 1 deletion src/main/resources/assets/replanter-plus/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
{
"replanter.gui.seed_not_found": ": item not in hotbar"
"category.replanter": "Replanter Plus",
"key.replanter.menu": "Open Config Scren",
"key.replanter.toggle": "Toggle Replanter",
"replanter.gui.seed_not_found": ": item not in hotbar",
"replanter.configscreen.enabled": "Enabled",
"replanter.configscreen.sneakToggle": "Disable When Sneaking",
"replanter.configscreen.tickDelay": "Item Use Delay",
"replanter.configscreen.done": "Done",
"replanter.switchbutton.label.on": "on",
"replanter.switchbutton.label.off": "off"
}
Loading

0 comments on commit 837d1d3

Please sign in to comment.