Skip to content

Commit 83a6e88

Browse files
committed
Kill Recorder Item WIP
1 parent ebf88d4 commit 83a6e88

File tree

7 files changed

+150
-14
lines changed

7 files changed

+150
-14
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package net.roboxgamer.modernutils.data;
2+
3+
import com.mojang.serialization.Codec;
4+
import com.mojang.serialization.codecs.RecordCodecBuilder;
5+
import net.minecraft.network.RegistryFriendlyByteBuf;
6+
import net.minecraft.network.codec.ByteBufCodecs;
7+
import net.minecraft.network.codec.StreamCodec;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import java.util.function.IntFunction;
11+
12+
public record KillData(List<String> kills, boolean isRecording, int totalXp) {
13+
private static final IntFunction<List<String>> LIST_FACTORY = ArrayList::new;
14+
15+
public static final Codec<KillData> CODEC = RecordCodecBuilder.create(instance ->
16+
instance.group(
17+
Codec.list(Codec.STRING).fieldOf("kills").forGetter(KillData::kills),
18+
Codec.BOOL.fieldOf("recording").forGetter(KillData::isRecording),
19+
Codec.INT.fieldOf("totalXp").forGetter(KillData::totalXp)
20+
).apply(instance, KillData::new)
21+
);
22+
23+
public static final StreamCodec<RegistryFriendlyByteBuf, KillData> STREAM_CODEC = StreamCodec.composite(
24+
ByteBufCodecs.collection(LIST_FACTORY, ByteBufCodecs.STRING_UTF8), KillData::kills,
25+
ByteBufCodecs.BOOL, KillData::isRecording,
26+
ByteBufCodecs.INT, KillData::totalXp,
27+
KillData::new);
28+
29+
public KillData addKill(String entityName, int xp) {
30+
List<String> newKills = kills();
31+
newKills.add(entityName);
32+
return new KillData(newKills, isRecording(), totalXp() + xp);
33+
}
34+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package net.roboxgamer.modernutils.event;
2+
3+
import net.minecraft.world.entity.LivingEntity;
4+
import net.minecraft.world.entity.player.Player;
5+
import net.minecraft.world.item.ItemStack;
6+
import net.neoforged.bus.api.SubscribeEvent;
7+
import net.neoforged.fml.common.EventBusSubscriber;
8+
import net.neoforged.neoforge.event.entity.living.LivingDeathEvent;
9+
import net.roboxgamer.modernutils.ModernUtilsMod;
10+
import net.roboxgamer.modernutils.data.KillData;
11+
import net.roboxgamer.modernutils.item.ModCustomDataComponents;
12+
import net.roboxgamer.modernutils.item.ModItems;
13+
import net.minecraft.server.level.ServerLevel;
14+
15+
@EventBusSubscriber(modid = ModernUtilsMod.MODID)
16+
public class ModEvents {
17+
@SubscribeEvent
18+
public static void onEntityKilled(LivingDeathEvent event) {
19+
if (event.getSource().getEntity() instanceof Player player && !player.level().isClientSide()) {
20+
// Check if player has kill recorder in inventory
21+
for (ItemStack stack : player.getInventory().items) {
22+
if (stack.is(ModItems.KILL_RECORDER.get())) {
23+
KillData killData = stack.get(ModCustomDataComponents.KILL_DATA.get());
24+
if (killData != null && killData.isRecording()) {
25+
LivingEntity killedEntity = event.getEntity();
26+
// Get XP from killed entity
27+
int xpReward = killedEntity.getExperienceReward((ServerLevel)killedEntity.level(), player);
28+
// Update kill data with entity name and XP
29+
stack.update(
30+
ModCustomDataComponents.KILL_DATA.get(),
31+
new KillData(killData.kills(), killData.isRecording(), killData.totalXp()),
32+
data -> data.addKill(killedEntity.getName().getString(), xpReward)
33+
);
34+
}
35+
}
36+
}
37+
}
38+
}
39+
}

src/main/java/net/roboxgamer/modernutils/item/ModCustomDataComponents.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,34 @@
33
import net.minecraft.core.BlockPos;
44
import net.minecraft.core.component.DataComponentType;
55
import net.minecraft.core.registries.Registries;
6+
import net.minecraft.network.codec.ByteBufCodecs;
7+
import net.minecraft.network.codec.StreamCodec;
68
import net.neoforged.bus.api.IEventBus;
7-
import net.neoforged.neoforge.registries.DeferredHolder;
89
import net.neoforged.neoforge.registries.DeferredRegister;
910
import net.roboxgamer.modernutils.ModernUtilsMod;
11+
import net.roboxgamer.modernutils.data.KillData;
12+
import java.util.function.Supplier;
1013

1114
public class ModCustomDataComponents {
12-
public static final DeferredRegister.DataComponents DATA_COMPONENTS = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, ModernUtilsMod.MODID);
13-
public static final DeferredHolder<DataComponentType<?>, DataComponentType<BlockPos>> BLOCK_POS_DATA_COMPONENT = DATA_COMPONENTS.registerComponentType(
14-
"block_pos",
15-
builder -> builder
16-
// The codec to read/write the data to disk
17-
.persistent(BlockPos.CODEC) // Here put the codec of the type you want
18-
// The codec to read/write the data across the network
19-
.networkSynchronized(BlockPos.STREAM_CODEC) // Here put the stream codec of the type you want
20-
);
21-
22-
public static void register(IEventBus eventbus) {
23-
DATA_COMPONENTS.register(eventbus);
24-
}
15+
public static final DeferredRegister.DataComponents DATA_COMPONENT_TYPES = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, ModernUtilsMod.MODID);
16+
17+
18+
19+
public static final Supplier<DataComponentType<BlockPos>> LAST_POS = DATA_COMPONENT_TYPES.registerComponentType("last_pos",
20+
builder -> builder
21+
.persistent(BlockPos.CODEC)
22+
.networkSynchronized(StreamCodec.composite(
23+
ByteBufCodecs.INT, BlockPos::getX,
24+
ByteBufCodecs.INT, BlockPos::getY,
25+
ByteBufCodecs.INT, BlockPos::getZ,
26+
(x, y, z) -> new BlockPos(x, y, z))));
27+
28+
public static final Supplier<DataComponentType<KillData>> KILL_DATA = DATA_COMPONENT_TYPES.registerComponentType("kill_data",
29+
builder -> builder
30+
.persistent(KillData.CODEC)
31+
.networkSynchronized(KillData.STREAM_CODEC));
32+
33+
public static void register(IEventBus eventBus) {
34+
DATA_COMPONENT_TYPES.register(eventBus);
35+
}
2536
}

src/main/java/net/roboxgamer/modernutils/item/ModItems.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.neoforged.neoforge.registries.DeferredItem;
66
import net.neoforged.neoforge.registries.DeferredRegister;
77
import net.roboxgamer.modernutils.ModernUtilsMod;
8+
import net.roboxgamer.modernutils.item.custom.KillRecorderItem;
89

910
public class ModItems {
1011
public static final DeferredRegister.Items ITEMS =
@@ -14,6 +15,9 @@ public class ModItems {
1415
DeferredRegister.createItems(ModernUtilsMod.MODID);
1516

1617
public static final DeferredItem<Item> EXAMPLE_ITEM = WIP_ITEMS.register("example_item",()-> new Item(new Item.Properties()));
18+
19+
public static final DeferredItem<Item> KILL_RECORDER = ITEMS.register("kill_recorder",
20+
() -> new KillRecorderItem(new Item.Properties()));
1721

1822
public static void register(IEventBus eventBus) {
1923
ITEMS.register(eventBus);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package net.roboxgamer.modernutils.item.custom;
2+
3+
import net.minecraft.network.chat.Component;
4+
import net.minecraft.server.level.ServerPlayer;
5+
import net.minecraft.world.InteractionHand;
6+
import net.minecraft.world.InteractionResultHolder;
7+
import net.minecraft.world.entity.player.Player;
8+
import net.minecraft.world.item.Item;
9+
import net.minecraft.world.item.ItemStack;
10+
import net.minecraft.world.level.Level;
11+
import net.minecraft.core.component.DataComponentType;
12+
import net.roboxgamer.modernutils.data.KillData;
13+
import net.roboxgamer.modernutils.item.ModCustomDataComponents;
14+
15+
import java.util.ArrayList;
16+
17+
public class KillRecorderItem extends Item {
18+
public KillRecorderItem(Properties properties) {
19+
super(properties.setNoRepair());
20+
}
21+
22+
@Override
23+
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
24+
if (!level.isClientSide() && player instanceof ServerPlayer) {
25+
ItemStack stack = player.getItemInHand(hand);
26+
27+
if (player.isShiftKeyDown()) {
28+
DataComponentType<KillData> killDataType = ModCustomDataComponents.KILL_DATA.get();
29+
KillData currentData = stack.getOrDefault(killDataType, new KillData(new ArrayList<>(), false, 0));
30+
31+
// Toggle recording state
32+
KillData newData = new KillData(currentData.kills(), !currentData.isRecording(), currentData.totalXp());
33+
stack.set(killDataType, newData);
34+
35+
player.displayClientMessage(Component.literal("Kill Recording: " +
36+
(newData.isRecording() ? "Enabled" : "Disabled")), true);
37+
}
38+
}
39+
return super.use(level, player, hand);
40+
}
41+
}

src/main/resources/assets/modernutils/lang/en_us.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"item.modernutils.example_item": "Example Item",
3+
"item.modernutils.kill_recorder": "Kill Recorder",
34
"block.modernutils.example_block": "Example Block",
45
"block.modernutils.magic_block": "Magic Block",
56
"block.modernutils.mechanical_crafter_block": "Mechanical Crafter",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"parent": "item/generated",
3+
"textures": {
4+
"layer0": "modernutils:item/kill_recorder"
5+
}
6+
}

0 commit comments

Comments
 (0)