Skip to content

Commit 47bdf22

Browse files
feat: Starting Items Event, better class names, new Ku.Player helpers
1 parent 33ab39b commit 47bdf22

16 files changed

+314
-21
lines changed

Diff for: CHANGELOG.md

+33-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,38 @@
11
# Kube Utils Changelog
22

3-
## [0.1.3]
3+
## [0.1.4]
44

55
### Added
66

7-
- Released for 1.18.2
7+
- A new `ku.player.starter-items` event that, once used and successfully gave items, will stop running
8+
- You can define an item and equipment slot (For things like armor) too
9+
```javascript
10+
onEvent("ku.player.starter-items", event => {
11+
// Item.of is optional here
12+
event.addItems("5x minecraft:gold_ingot", Item.of("2x minecraft:grass_block"))
13+
14+
// Valid options are part of the EquipmentSlot Enum
15+
event.addEquipmentItem("chest", "minecraft:golden_chestplate")
16+
event.addEquipmentItem("offhand", "minecraft:stone")
17+
})
18+
```
19+
- A new `Ku.Player` class that brings some helpful methods
20+
- `showActionBar(text: string, color?: Color = Color.WHITE, bold = false, italic = false)`
21+
- 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
22+
- `showActionBarComponent(component: Component)`
23+
- 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
24+
```javascript
25+
const player = Ku.Player(event.player);
26+
player.showActionBarComponent({
27+
text: "Hello",
28+
bold: true
29+
})
30+
```
31+
- `clearStarterItemsFlag`
32+
- 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
33+
- `isClientSide`
34+
- Lets you know if the client being wrapped is client side. This was mostly a helper for my code but it could be helpful
35+
36+
### Changed
37+
38+
- Renamed the internal binding classes to be suffixed with Ku so they're visually different from vanilla and KubeJS

Diff for: gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ loom.platform=forge
66
minecraft_version=1.18.2
77
forge_version=1.18.2-40.1.54
88

9-
mod_version=0.1.3
9+
mod_version=0.1.4
1010
maven_group=pro.mikey.mods
1111
archives_base_name=kube-utils
1212
mod_id=kubeutils

Diff for: src/main/java/pro/mikey/kubeutils/KubeUtils.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
package pro.mikey.kubeutils;
22

3+
import net.minecraftforge.common.MinecraftForge;
34
import net.minecraftforge.fml.common.Mod;
45
import org.apache.logging.log4j.LogManager;
56
import org.apache.logging.log4j.Logger;
7+
import pro.mikey.kubeutils.events.OnPlayerLoginEvent;
68

79
@Mod(KubeUtils.MOD_ID)
810
public class KubeUtils {
911
public static final String MOD_ID = "kubeutils";
1012
public static final Logger LOGGER = LogManager.getLogger();
1113

12-
public KubeUtils() {}
14+
public KubeUtils() {
15+
this.registerEvents();
16+
}
17+
18+
private void registerEvents() {
19+
MinecraftForge.EVENT_BUS.register(new OnPlayerLoginEvent());
20+
}
1321

1422
public static String getId() {
1523
return MOD_ID;
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package pro.mikey.kubeutils.events;
2+
3+
import pro.mikey.kubeutils.utils.Utils;
4+
5+
public enum KuEvents {
6+
PLAYER_STARTER_ITEMS("player.starter-items");
7+
8+
private final String id;
9+
10+
KuEvents(String id) {
11+
this.id = "%s.%s".formatted(Utils.PREFIX, id);
12+
}
13+
14+
public String id() {
15+
return id;
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package pro.mikey.kubeutils.events;
2+
3+
import net.minecraftforge.event.entity.player.PlayerEvent;
4+
import net.minecraftforge.eventbus.api.SubscribeEvent;
5+
import pro.mikey.kubeutils.kubejs.events.PlayerStarterItems;
6+
7+
// NOTE: Maybe move this to a single class of events?
8+
public class OnPlayerLoginEvent {
9+
10+
@SubscribeEvent
11+
void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
12+
if (!event.getPlayer().getPersistentDataKJS().getBoolean(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG)) {
13+
new PlayerStarterItems(event.getPlayer()).post(KuEvents.PLAYER_STARTER_ITEMS.id());
14+
}
15+
}
16+
}

Diff for: src/main/java/pro/mikey/kubeutils/kubejs/BaseBindings.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import pro.mikey.kubeutils.kubejs.modules.*;
55

66
public interface BaseBindings {
7-
Fluids Fluids = new Fluids();
8-
Utils Utils = new Utils();
7+
FluidsKu Fluids = new FluidsKu();
8+
UtilsKu Utils = new UtilsKu();
99
StreamsHelper Streams = new StreamsHelper();
10-
ListActions Lists = new ListActions();
11-
ClassWrapper<LevelUtils> Level = new ClassWrapper<>(LevelUtils.class);
10+
ListsKu Lists = new ListsKu();
11+
ClassWrapper<LevelKu> Level = new ClassWrapper<>(LevelKu.class);
12+
ClassWrapper<PlayerKu> Player = new ClassWrapper<>(PlayerKu.class);
1213
}

Diff for: src/main/java/pro/mikey/kubeutils/kubejs/KubeUtilsPlugin.java

+12
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,22 @@
22

33
import dev.latvian.mods.kubejs.KubeJSPlugin;
44
import dev.latvian.mods.kubejs.script.BindingsEvent;
5+
import dev.latvian.mods.kubejs.script.ScriptType;
6+
import dev.latvian.mods.kubejs.util.ClassFilter;
7+
import pro.mikey.kubeutils.utils.Utils;
58

69
public class KubeUtilsPlugin extends KubeJSPlugin {
710
@Override
811
public void addBindings(BindingsEvent event) {
912
event.add("Ku", BaseBindings.class);
1013
}
14+
15+
@Override
16+
public void addClasses(ScriptType type, ClassFilter filter) {
17+
filter.deny(Utils.class);
18+
filter.deny(BaseBindings.class);
19+
filter.deny(KubeUtilsPlugin.class);
20+
}
21+
22+
1123
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package pro.mikey.kubeutils.kubejs.events;
2+
3+
import dev.latvian.mods.kubejs.entity.EntityJS;
4+
import dev.latvian.mods.kubejs.item.ItemHandlerUtils;
5+
import dev.latvian.mods.kubejs.player.PlayerEventJS;
6+
import net.minecraft.world.entity.EquipmentSlot;
7+
import net.minecraft.world.entity.player.Player;
8+
import net.minecraft.world.item.ItemStack;
9+
import pro.mikey.kubeutils.events.KuEvents;
10+
import pro.mikey.kubeutils.kubejs.modules.PlayerKu;
11+
import pro.mikey.kubeutils.utils.Utils;
12+
import pro.mikey.kubeutils.utils.annotations.KuEvent;
13+
14+
import java.util.*;
15+
16+
/**
17+
* Custom event fired when the player logins in and does not have the {@link PlayerStarterItems#STARTER_ITEMS_GIVEN_FLAG}
18+
* flag enabled. You can reset this flag at any point using {@link PlayerKu#clearStarterItemsFlag()}
19+
*
20+
* To add items, simply call the event and use the `addItems` method.
21+
* <p>
22+
* <code>
23+
* // 1.18
24+
* // Item.of is optional here
25+
* onEvent("ku.player.starter-items", event => {
26+
* event.addItems("5x minecraft:gold_ingot", Item.of("2x minecraft:grass_block"))
27+
* })
28+
* </code
29+
*/
30+
@KuEvent(KuEvents.PLAYER_STARTER_ITEMS)
31+
public class PlayerStarterItems extends PlayerEventJS {
32+
public static final String STARTER_ITEMS_GIVEN_FLAG = Utils.kuIdStorage("sig");
33+
34+
private final Player player;
35+
private final List<ItemStack> items = new ArrayList<>();
36+
private final Map<EquipmentSlot, ItemStack> armorItems = new HashMap<>();
37+
38+
public PlayerStarterItems(Player player) {
39+
this.player = player;
40+
}
41+
42+
public void addItems(ItemStack... items) {
43+
this.items.addAll(List.of(items));
44+
}
45+
46+
public void addEquipmentItem(String equipmentSlot, ItemStack item) {
47+
var slot = Arrays.stream(EquipmentSlot.values())
48+
.filter(e -> e.getName().equalsIgnoreCase(equipmentSlot))
49+
.findFirst()
50+
.orElse(EquipmentSlot.CHEST);
51+
52+
this.armorItems.put(slot, item);
53+
}
54+
55+
@Override
56+
protected void afterPosted(boolean cancelled) {
57+
if (cancelled) {
58+
return;
59+
}
60+
61+
boolean inserted = false;
62+
if (this.items.size() > 0) {
63+
this.items.forEach(item -> ItemHandlerUtils.giveItemToPlayer(this.player, item, -1));
64+
inserted = true;
65+
}
66+
67+
if (this.armorItems.size() > 0) {
68+
this.armorItems.forEach((key, value) -> {
69+
this.player.setItemSlot(key, value);
70+
71+
// If it didn't place, put it in their inventory
72+
if (this.player.getItemBySlot(key).getItem() != value.getItem()) {
73+
ItemHandlerUtils.giveItemToPlayer(this.player, value, -1);
74+
}
75+
});
76+
77+
inserted = true;
78+
}
79+
80+
if (inserted) {
81+
this.player.getPersistentDataKJS().putBoolean(STARTER_ITEMS_GIVEN_FLAG, true);
82+
}
83+
}
84+
85+
@Override
86+
public EntityJS getEntity() {
87+
return entityOf(this.player);
88+
}
89+
90+
record SlotTargetedItemStack(
91+
int slotId,
92+
ItemStack stack
93+
) {}
94+
}

Diff for: src/main/java/pro/mikey/kubeutils/kubejs/modules/Fluids.java renamed to src/main/java/pro/mikey/kubeutils/kubejs/modules/FluidsKu.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
/**
1111
* Fluid helpers module
1212
*/
13-
public class Fluids {
14-
public Fluids() {
13+
public class FluidsKu {
14+
public FluidsKu() {
1515
}
1616

1717
/**
@@ -33,7 +33,7 @@ public List<Fluid> getFluidsByNamespace(@Nullable String namespace) {
3333
}
3434

3535
/**
36-
* Same as {@link Fluids#getFluidsByNamespace(String)} but accepts a list of namespaces
36+
* Same as {@link FluidsKu#getFluidsByNamespace(String)} but accepts a list of namespaces
3737
*
3838
* @param namespaces the namespaces you want to fetch the fluids for
3939
*

Diff for: src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelUtils.java renamed to src/main/java/pro/mikey/kubeutils/kubejs/modules/LevelKu.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.minecraft.core.Registry;
66
import net.minecraft.core.Vec3i;
77
import net.minecraft.resources.ResourceLocation;
8+
import net.minecraft.server.commands.TitleCommand;
89
import net.minecraft.server.level.ServerLevel;
910
import net.minecraft.util.Mth;
1011
import net.minecraft.world.entity.Entity;
@@ -22,11 +23,11 @@
2223
import java.util.*;
2324
import java.util.function.Predicate;
2425

25-
public class LevelUtils {
26+
public class LevelKu {
2627
private static final ResourceLocation UNKNOWN = new ResourceLocation(KubeUtils.getId(), "unknown");
2728
private final ServerLevel level;
2829

29-
public LevelUtils(ServerLevelJS level) {
30+
public LevelKu(ServerLevelJS level) {
3031
this.level = level.getMinecraftLevel();
3132
}
3233

Diff for: src/main/java/pro/mikey/kubeutils/kubejs/modules/ListActions.java renamed to src/main/java/pro/mikey/kubeutils/kubejs/modules/ListsKu.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
77

8-
public class ListActions {
9-
private static final Logger LOGGER = LoggerFactory.getLogger(ListActions.class);
8+
public class ListsKu {
9+
private static final Logger LOGGER = LoggerFactory.getLogger(ListsKu.class);
1010

11-
public ListActions() {
11+
public ListsKu() {
1212
}
1313

1414
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package pro.mikey.kubeutils.kubejs.modules;
2+
3+
import dev.latvian.mods.kubejs.player.PlayerJS;
4+
import dev.latvian.mods.rhino.mod.util.color.Color;
5+
import net.minecraft.client.player.LocalPlayer;
6+
import net.minecraft.nbt.CompoundTag;
7+
import net.minecraft.network.chat.Component;
8+
import net.minecraft.network.chat.TextComponent;
9+
import net.minecraft.world.entity.player.Player;
10+
import pro.mikey.kubeutils.kubejs.events.PlayerStarterItems;
11+
12+
13+
/**
14+
* Some player helper methods
15+
*/
16+
public class PlayerKu {
17+
private final Player player;
18+
19+
public PlayerKu(PlayerJS<?> player) {
20+
this.player = player.minecraftPlayer;
21+
}
22+
23+
//#region actionBar
24+
/**
25+
* Provides a simple method for displaying a client message on the action bar. Supports all the normal things that
26+
* the {@link Component} class can offer whilst having alternative methods to display simpler text like a string.
27+
*
28+
* @see #showActionBar(String)
29+
* @see #showActionBar(String, Color, boolean, boolean)
30+
*
31+
* <b>Example</b>
32+
* <code>
33+
* const player = Ku.Player(event.player);
34+
* <p>
35+
* player.showActionBarComponent({
36+
* "text": "Hello",
37+
* "bold": true
38+
* })
39+
* </code>
40+
*
41+
* @param component The component. You can make this two ways `Component.of` or pass a raw js object
42+
*/
43+
public void showActionBarComponent(Component component) {
44+
this.player.displayClientMessage(component, true);
45+
}
46+
47+
public void showActionBar(String text) {
48+
this.player.displayClientMessage(new TextComponent(text), true);
49+
}
50+
51+
public void showActionBar(String text, Color color, boolean bold, boolean italic) {
52+
this.player.displayClientMessage(new TextComponent(text).color(color).bold(bold).italic(italic), true);
53+
}
54+
55+
public void showActionBar(String text, Color color) {
56+
this.showActionBar(text, color, false, false);
57+
}
58+
59+
public void showActionBar(String text, Color color, boolean bold) {
60+
this.showActionBar(text, color, bold, false);
61+
}
62+
//#endregion
63+
64+
/**
65+
* Allows you to clear the flag that prevents the {@link PlayerStarterItems} event from being called on a player
66+
*
67+
* @return if the clear happened
68+
*/
69+
public boolean clearStarterItemsFlag() {
70+
CompoundTag kubePersistent = this.player.getPersistentDataKJS();
71+
if (kubePersistent.contains(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG) && kubePersistent.getBoolean(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG)) {
72+
kubePersistent.putBoolean(PlayerStarterItems.STARTER_ITEMS_GIVEN_FLAG, false);
73+
return true;
74+
}
75+
76+
return false;
77+
}
78+
79+
/**
80+
* If the client is an instance of the local player of if they are a server player
81+
*
82+
* @return if the player is a client side player
83+
*/
84+
public boolean isClientSide() {
85+
return this.player instanceof LocalPlayer;
86+
}
87+
}

0 commit comments

Comments
 (0)