From 47bdf220fe2f56f33ac718d571e1192295931916 Mon Sep 17 00:00:00 2001 From: Michael Hillcox Date: Tue, 31 Jan 2023 18:35:55 +0000 Subject: [PATCH] feat: Starting Items Event, better class names, new Ku.Player helpers --- CHANGELOG.md | 35 ++++++- gradle.properties | 2 +- .../java/pro/mikey/kubeutils/KubeUtils.java | 10 +- .../pro/mikey/kubeutils/events/KuEvents.java | 17 ++++ .../kubeutils/events/OnPlayerLoginEvent.java | 16 ++++ .../mikey/kubeutils/kubejs/BaseBindings.java | 9 +- .../kubeutils/kubejs/KubeUtilsPlugin.java | 12 +++ .../kubejs/events/PlayerStarterItems.java | 94 +++++++++++++++++++ .../modules/{Fluids.java => FluidsKu.java} | 6 +- .../modules/{LevelUtils.java => LevelKu.java} | 5 +- .../{ListActions.java => ListsKu.java} | 6 +- .../kubeutils/kubejs/modules/PlayerKu.java | 87 +++++++++++++++++ .../modules/{Utils.java => UtilsKu.java} | 7 +- .../java/pro/mikey/kubeutils/utils/Utils.java | 15 +++ .../kubeutils/utils/annotations/KuEvent.java | 13 +++ src/main/resources/kubeutils.mixins.json | 1 + 16 files changed, 314 insertions(+), 21 deletions(-) create mode 100644 src/main/java/pro/mikey/kubeutils/events/KuEvents.java create mode 100644 src/main/java/pro/mikey/kubeutils/events/OnPlayerLoginEvent.java create mode 100644 src/main/java/pro/mikey/kubeutils/kubejs/events/PlayerStarterItems.java rename src/main/java/pro/mikey/kubeutils/kubejs/modules/{Fluids.java => FluidsKu.java} (93%) rename src/main/java/pro/mikey/kubeutils/kubejs/modules/{LevelUtils.java => LevelKu.java} (98%) rename src/main/java/pro/mikey/kubeutils/kubejs/modules/{ListActions.java => ListsKu.java} (94%) create mode 100644 src/main/java/pro/mikey/kubeutils/kubejs/modules/PlayerKu.java rename src/main/java/pro/mikey/kubeutils/kubejs/modules/{Utils.java => UtilsKu.java} (93%) create mode 100644 src/main/java/pro/mikey/kubeutils/utils/Utils.java create mode 100644 src/main/java/pro/mikey/kubeutils/utils/annotations/KuEvent.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e488ad..a921c32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,38 @@ # Kube Utils Changelog -## [0.1.3] +## [0.1.4] ### Added -- Released for 1.18.2 +- A new `ku.player.starter-items` event that, once used and successfully gave items, will stop running + - You can define an item and equipment slot (For things like armor) too + ```javascript + onEvent("ku.player.starter-items", event => { + // Item.of is optional here + event.addItems("5x minecraft:gold_ingot", Item.of("2x minecraft:grass_block")) + + // Valid options are part of the EquipmentSlot Enum + event.addEquipmentItem("chest", "minecraft:golden_chestplate") + event.addEquipmentItem("offhand", "minecraft:stone") + }) + ``` +- A new `Ku.Player` class that brings some helpful methods + - `showActionBar(text: string, color?: Color = Color.WHITE, bold = false, italic = false)` + - Uses the built-in client action bar to display a message. This is already supported through the player class but this method allows for less boilerplate and stable code ports + - `showActionBarComponent(component: Component)` + - Mostly the same as the above but gives you access to use a JS Object as your component which might look a something like this + ```javascript + const player = Ku.Player(event.player); + player.showActionBarComponent({ + text: "Hello", + bold: true + }) + ``` + - `clearStarterItemsFlag` + - This method simply reset the flag for the `ku.player.starter-items` meaning on the next login, the player will be given the items once again + - `isClientSide` + - Lets you know if the client being wrapped is client side. This was mostly a helper for my code but it could be helpful + +### Changed + +- Renamed the internal binding classes to be suffixed with Ku so they're visually different from vanilla and KubeJS diff --git a/gradle.properties b/gradle.properties index 54a8843..f8bf042 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ loom.platform=forge minecraft_version=1.18.2 forge_version=1.18.2-40.1.54 -mod_version=0.1.3 +mod_version=0.1.4 maven_group=pro.mikey.mods archives_base_name=kube-utils mod_id=kubeutils diff --git a/src/main/java/pro/mikey/kubeutils/KubeUtils.java b/src/main/java/pro/mikey/kubeutils/KubeUtils.java index e6b1868..04223fa 100644 --- a/src/main/java/pro/mikey/kubeutils/KubeUtils.java +++ b/src/main/java/pro/mikey/kubeutils/KubeUtils.java @@ -1,15 +1,23 @@ package pro.mikey.kubeutils; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Mod; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import pro.mikey.kubeutils.events.OnPlayerLoginEvent; @Mod(KubeUtils.MOD_ID) public class KubeUtils { public static final String MOD_ID = "kubeutils"; public static final Logger LOGGER = LogManager.getLogger(); - public KubeUtils() {} + public KubeUtils() { + this.registerEvents(); + } + + private void registerEvents() { + MinecraftForge.EVENT_BUS.register(new OnPlayerLoginEvent()); + } public static String getId() { return MOD_ID; diff --git a/src/main/java/pro/mikey/kubeutils/events/KuEvents.java b/src/main/java/pro/mikey/kubeutils/events/KuEvents.java new file mode 100644 index 0000000..a0f5142 --- /dev/null +++ b/src/main/java/pro/mikey/kubeutils/events/KuEvents.java @@ -0,0 +1,17 @@ +package pro.mikey.kubeutils.events; + +import pro.mikey.kubeutils.utils.Utils; + +public enum KuEvents { + PLAYER_STARTER_ITEMS("player.starter-items"); + + private final String id; + + KuEvents(String id) { + this.id = "%s.%s".formatted(Utils.PREFIX, id); + } + + public String id() { + return id; + } +} diff --git a/src/main/java/pro/mikey/kubeutils/events/OnPlayerLoginEvent.java b/src/main/java/pro/mikey/kubeutils/events/OnPlayerLoginEvent.java new file mode 100644 index 0000000..ad4708b --- /dev/null +++ b/src/main/java/pro/mikey/kubeutils/events/OnPlayerLoginEvent.java @@ -0,0 +1,16 @@ +package pro.mikey.kubeutils.events; + +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import pro.mikey.kubeutils.kubejs.events.PlayerStarterItems; + +// NOTE: Maybe move this to a single class of events? +public class OnPlayerLoginEvent { + + @SubscribeEvent + void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { + if (!event.getPlayer().getPersistentDataKJS().getBoolean(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG)) { + new PlayerStarterItems(event.getPlayer()).post(KuEvents.PLAYER_STARTER_ITEMS.id()); + } + } +} diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/BaseBindings.java b/src/main/java/pro/mikey/kubeutils/kubejs/BaseBindings.java index 0915ef6..06030b1 100644 --- a/src/main/java/pro/mikey/kubeutils/kubejs/BaseBindings.java +++ b/src/main/java/pro/mikey/kubeutils/kubejs/BaseBindings.java @@ -4,9 +4,10 @@ import pro.mikey.kubeutils.kubejs.modules.*; public interface BaseBindings { - Fluids Fluids = new Fluids(); - Utils Utils = new Utils(); + FluidsKu Fluids = new FluidsKu(); + UtilsKu Utils = new UtilsKu(); StreamsHelper Streams = new StreamsHelper(); - ListActions Lists = new ListActions(); - ClassWrapper Level = new ClassWrapper<>(LevelUtils.class); + ListsKu Lists = new ListsKu(); + ClassWrapper Level = new ClassWrapper<>(LevelKu.class); + ClassWrapper Player = new ClassWrapper<>(PlayerKu.class); } diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/KubeUtilsPlugin.java b/src/main/java/pro/mikey/kubeutils/kubejs/KubeUtilsPlugin.java index 9dfbc21..06fdcb7 100644 --- a/src/main/java/pro/mikey/kubeutils/kubejs/KubeUtilsPlugin.java +++ b/src/main/java/pro/mikey/kubeutils/kubejs/KubeUtilsPlugin.java @@ -2,10 +2,22 @@ import dev.latvian.mods.kubejs.KubeJSPlugin; import dev.latvian.mods.kubejs.script.BindingsEvent; +import dev.latvian.mods.kubejs.script.ScriptType; +import dev.latvian.mods.kubejs.util.ClassFilter; +import pro.mikey.kubeutils.utils.Utils; public class KubeUtilsPlugin extends KubeJSPlugin { @Override public void addBindings(BindingsEvent event) { event.add("Ku", BaseBindings.class); } + + @Override + public void addClasses(ScriptType type, ClassFilter filter) { + filter.deny(Utils.class); + filter.deny(BaseBindings.class); + filter.deny(KubeUtilsPlugin.class); + } + + } diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/events/PlayerStarterItems.java b/src/main/java/pro/mikey/kubeutils/kubejs/events/PlayerStarterItems.java new file mode 100644 index 0000000..809cd18 --- /dev/null +++ b/src/main/java/pro/mikey/kubeutils/kubejs/events/PlayerStarterItems.java @@ -0,0 +1,94 @@ +package pro.mikey.kubeutils.kubejs.events; + +import dev.latvian.mods.kubejs.entity.EntityJS; +import dev.latvian.mods.kubejs.item.ItemHandlerUtils; +import dev.latvian.mods.kubejs.player.PlayerEventJS; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import pro.mikey.kubeutils.events.KuEvents; +import pro.mikey.kubeutils.kubejs.modules.PlayerKu; +import pro.mikey.kubeutils.utils.Utils; +import pro.mikey.kubeutils.utils.annotations.KuEvent; + +import java.util.*; + +/** + * Custom event fired when the player logins in and does not have the {@link PlayerStarterItems#STARTER_ITEMS_GIVEN_FLAG} + * flag enabled. You can reset this flag at any point using {@link PlayerKu#clearStarterItemsFlag()} + * + * To add items, simply call the event and use the `addItems` method. + *

+ * + * // 1.18 + * // Item.of is optional here + * onEvent("ku.player.starter-items", event => { + * event.addItems("5x minecraft:gold_ingot", Item.of("2x minecraft:grass_block")) + * }) + * items = new ArrayList<>(); + private final Map armorItems = new HashMap<>(); + + public PlayerStarterItems(Player player) { + this.player = player; + } + + public void addItems(ItemStack... items) { + this.items.addAll(List.of(items)); + } + + public void addEquipmentItem(String equipmentSlot, ItemStack item) { + var slot = Arrays.stream(EquipmentSlot.values()) + .filter(e -> e.getName().equalsIgnoreCase(equipmentSlot)) + .findFirst() + .orElse(EquipmentSlot.CHEST); + + this.armorItems.put(slot, item); + } + + @Override + protected void afterPosted(boolean cancelled) { + if (cancelled) { + return; + } + + boolean inserted = false; + if (this.items.size() > 0) { + this.items.forEach(item -> ItemHandlerUtils.giveItemToPlayer(this.player, item, -1)); + inserted = true; + } + + if (this.armorItems.size() > 0) { + this.armorItems.forEach((key, value) -> { + this.player.setItemSlot(key, value); + + // If it didn't place, put it in their inventory + if (this.player.getItemBySlot(key).getItem() != value.getItem()) { + ItemHandlerUtils.giveItemToPlayer(this.player, value, -1); + } + }); + + inserted = true; + } + + if (inserted) { + this.player.getPersistentDataKJS().putBoolean(STARTER_ITEMS_GIVEN_FLAG, true); + } + } + + @Override + public EntityJS getEntity() { + return entityOf(this.player); + } + + record SlotTargetedItemStack( + int slotId, + ItemStack stack + ) {} +} diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/modules/Fluids.java b/src/main/java/pro/mikey/kubeutils/kubejs/modules/FluidsKu.java similarity index 93% rename from src/main/java/pro/mikey/kubeutils/kubejs/modules/Fluids.java rename to src/main/java/pro/mikey/kubeutils/kubejs/modules/FluidsKu.java index 297867c..f15ad0b 100644 --- a/src/main/java/pro/mikey/kubeutils/kubejs/modules/Fluids.java +++ b/src/main/java/pro/mikey/kubeutils/kubejs/modules/FluidsKu.java @@ -10,8 +10,8 @@ /** * Fluid helpers module */ -public class Fluids { - public Fluids() { +public class FluidsKu { + public FluidsKu() { } /** @@ -33,7 +33,7 @@ public List getFluidsByNamespace(@Nullable String namespace) { } /** - * Same as {@link Fluids#getFluidsByNamespace(String)} but accepts a list of namespaces + * Same as {@link FluidsKu#getFluidsByNamespace(String)} but accepts a list of namespaces * * @param namespaces the namespaces you want to fetch the fluids for * diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelUtils.java b/src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelKu.java similarity index 98% rename from src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelUtils.java rename to src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelKu.java index b954e4d..296eed0 100644 --- a/src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelUtils.java +++ b/src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelKu.java @@ -5,6 +5,7 @@ import net.minecraft.core.Registry; import net.minecraft.core.Vec3i; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.commands.TitleCommand; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -22,11 +23,11 @@ import java.util.*; import java.util.function.Predicate; -public class LevelUtils { +public class LevelKu { private static final ResourceLocation UNKNOWN = new ResourceLocation(KubeUtils.getId(), "unknown"); private final ServerLevel level; - public LevelUtils(ServerLevelJS level) { + public LevelKu(ServerLevelJS level) { this.level = level.getMinecraftLevel(); } diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/modules/ListActions.java b/src/main/java/pro/mikey/kubeutils/kubejs/modules/ListsKu.java similarity index 94% rename from src/main/java/pro/mikey/kubeutils/kubejs/modules/ListActions.java rename to src/main/java/pro/mikey/kubeutils/kubejs/modules/ListsKu.java index 259ec64..7ffdadd 100644 --- a/src/main/java/pro/mikey/kubeutils/kubejs/modules/ListActions.java +++ b/src/main/java/pro/mikey/kubeutils/kubejs/modules/ListsKu.java @@ -5,10 +5,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ListActions { - private static final Logger LOGGER = LoggerFactory.getLogger(ListActions.class); +public class ListsKu { + private static final Logger LOGGER = LoggerFactory.getLogger(ListsKu.class); - public ListActions() { + public ListsKu() { } /** diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/modules/PlayerKu.java b/src/main/java/pro/mikey/kubeutils/kubejs/modules/PlayerKu.java new file mode 100644 index 0000000..bc99b7b --- /dev/null +++ b/src/main/java/pro/mikey/kubeutils/kubejs/modules/PlayerKu.java @@ -0,0 +1,87 @@ +package pro.mikey.kubeutils.kubejs.modules; + +import dev.latvian.mods.kubejs.player.PlayerJS; +import dev.latvian.mods.rhino.mod.util.color.Color; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.entity.player.Player; +import pro.mikey.kubeutils.kubejs.events.PlayerStarterItems; + + +/** + * Some player helper methods + */ +public class PlayerKu { + private final Player player; + + public PlayerKu(PlayerJS player) { + this.player = player.minecraftPlayer; + } + + //#region actionBar + /** + * Provides a simple method for displaying a client message on the action bar. Supports all the normal things that + * the {@link Component} class can offer whilst having alternative methods to display simpler text like a string. + * + * @see #showActionBar(String) + * @see #showActionBar(String, Color, boolean, boolean) + * + * Example + * + * const player = Ku.Player(event.player); + *

+ * player.showActionBarComponent({ + * "text": "Hello", + * "bold": true + * }) + * + * + * @param component The component. You can make this two ways `Component.of` or pass a raw js object + */ + public void showActionBarComponent(Component component) { + this.player.displayClientMessage(component, true); + } + + public void showActionBar(String text) { + this.player.displayClientMessage(new TextComponent(text), true); + } + + public void showActionBar(String text, Color color, boolean bold, boolean italic) { + this.player.displayClientMessage(new TextComponent(text).color(color).bold(bold).italic(italic), true); + } + + public void showActionBar(String text, Color color) { + this.showActionBar(text, color, false, false); + } + + public void showActionBar(String text, Color color, boolean bold) { + this.showActionBar(text, color, bold, false); + } + //#endregion + + /** + * Allows you to clear the flag that prevents the {@link PlayerStarterItems} event from being called on a player + * + * @return if the clear happened + */ + public boolean clearStarterItemsFlag() { + CompoundTag kubePersistent = this.player.getPersistentDataKJS(); + if (kubePersistent.contains(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG) && kubePersistent.getBoolean(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG)) { + kubePersistent.putBoolean(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG, false); + return true; + } + + return false; + } + + /** + * If the client is an instance of the local player of if they are a server player + * + * @return if the player is a client side player + */ + public boolean isClientSide() { + return this.player instanceof LocalPlayer; + } +} diff --git a/src/main/java/pro/mikey/kubeutils/kubejs/modules/Utils.java b/src/main/java/pro/mikey/kubeutils/kubejs/modules/UtilsKu.java similarity index 93% rename from src/main/java/pro/mikey/kubeutils/kubejs/modules/Utils.java rename to src/main/java/pro/mikey/kubeutils/kubejs/modules/UtilsKu.java index 2ac8a55..71fcc96 100644 --- a/src/main/java/pro/mikey/kubeutils/kubejs/modules/Utils.java +++ b/src/main/java/pro/mikey/kubeutils/kubejs/modules/UtilsKu.java @@ -1,12 +1,9 @@ package pro.mikey.kubeutils.kubejs.modules; -import dev.latvian.mods.kubejs.entity.EntityJS; import dev.latvian.mods.kubejs.item.ItemStackJS; import dev.latvian.mods.kubejs.level.BlockContainerJS; import dev.latvian.mods.rhino.Undefined; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -17,11 +14,11 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -public class Utils { +public class UtilsKu { private static final ResourceLocation EMPTY_LOCATION = new ResourceLocation("minecraft:empty"); private static final ResourceLocation AIR_LOCATION = new ResourceLocation("minecraft:air"); - public Utils() { + public UtilsKu() { } /** diff --git a/src/main/java/pro/mikey/kubeutils/utils/Utils.java b/src/main/java/pro/mikey/kubeutils/utils/Utils.java new file mode 100644 index 0000000..7c80b6c --- /dev/null +++ b/src/main/java/pro/mikey/kubeutils/utils/Utils.java @@ -0,0 +1,15 @@ +package pro.mikey.kubeutils.utils; + +public class Utils { + public static final String PREFIX = "ku"; + private static final String STORAGE_PERSISTENT = "pr"; + private static final String STORAGE_GENERIC = "gn"; + + public static String kuId(String suffix) { + return String.join(".", PREFIX, STORAGE_GENERIC, suffix); + } + + public static String kuIdStorage(String suffix) { + return String.join(".", PREFIX, STORAGE_PERSISTENT, suffix); + } +} diff --git a/src/main/java/pro/mikey/kubeutils/utils/annotations/KuEvent.java b/src/main/java/pro/mikey/kubeutils/utils/annotations/KuEvent.java new file mode 100644 index 0000000..c936d00 --- /dev/null +++ b/src/main/java/pro/mikey/kubeutils/utils/annotations/KuEvent.java @@ -0,0 +1,13 @@ +package pro.mikey.kubeutils.utils.annotations; + +import pro.mikey.kubeutils.events.KuEvents; + +import java.lang.annotation.*; + +/** + * Right now it's just a marker but it'll be used for docs eventually + */ +@Target(ElementType.TYPE) +public @interface KuEvent { + KuEvents value(); +} diff --git a/src/main/resources/kubeutils.mixins.json b/src/main/resources/kubeutils.mixins.json index 449d939..b5332df 100644 --- a/src/main/resources/kubeutils.mixins.json +++ b/src/main/resources/kubeutils.mixins.json @@ -1,6 +1,7 @@ { "required": true, "package": "pro.mikey.kubeutils.mixin", + "minVersion": "0.7.0", "compatibilityLevel": "JAVA_17", "mixins": [], "client": [],