From cb9b24a15cbcd3e534dcc7939b3c566ab0204436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sun, 12 Oct 2025 17:02:48 +0200 Subject: feat(player): represents custom data --- .../java/world/anhgelus/lifesteal/LifeStealer.java | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/main/java/world/anhgelus/lifesteal/LifeStealer.java (limited to 'src') diff --git a/src/main/java/world/anhgelus/lifesteal/LifeStealer.java b/src/main/java/world/anhgelus/lifesteal/LifeStealer.java new file mode 100644 index 0000000..86410de --- /dev/null +++ b/src/main/java/world/anhgelus/lifesteal/LifeStealer.java @@ -0,0 +1,98 @@ +package world.anhgelus.lifesteal; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.NbtComponent; +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class LifeStealer { + public static final Identifier HEALTH_MODIFIER = Identifier.of(LifeSteal.MOD_ID, "health_modifier"); + public static final String PLAYER_KEY = "player"; + + private ServerPlayerEntity player; + private final UUID uuid; + private float healthModifier; + + public LifeStealer(ServerPlayerEntity player, Data data) { + this.player = player; + this.uuid = player.getUuid(); + this.healthModifier = data.healthModifier(); + } + + private void updateHealth() { + healthModifier = MathHelper.clamp(healthModifier, -20, 20); + final var attr = player.getAttributeInstance(EntityAttributes.MAX_HEALTH); + if (attr == null) throw new IllegalStateException("No health attribute assigned to LifeStealer"); + if (attr.hasModifier(HEALTH_MODIFIER)) attr.removeModifier(HEALTH_MODIFIER); + final var modifier = new EntityAttributeModifier(HEALTH_MODIFIER, healthModifier, EntityAttributeModifier.Operation.ADD_VALUE); + attr.addTemporaryModifier(modifier); + } + + public ItemStack getHeart() { + final var nbt = new NbtCompound(); + nbt.putString(PLAYER_KEY, player.getUuid().toString()); + final var is = new ItemStack(Items.NETHER_STAR); + is.set(DataComponentTypes.CUSTOM_NAME, player.getName()); + is.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(nbt)); + return is; + } + + public void respawn(ServerPlayerEntity newPlayer) { + if (!newPlayer.getUuid().equals(uuid)) throw new IllegalArgumentException("Player does not have the same UUID"); + this.player = newPlayer; + updateHealth(); + } + + public void kill() { + healthModifier = MathHelper.clamp(healthModifier + 2, -20, 20); + updateHealth(); + } + + public void killed() { + healthModifier = MathHelper.clamp(healthModifier - 2, -20, 20); + if (healthModifier <= 0) { + //TODO: ban player + return; + } + updateHealth(); + } + + public float getHealthModifier() { + return healthModifier; + } + + public record Data(float healthModifier) { + public final static String HEALTH_MODIFIER_KEY = "health_modifier"; + public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( + Codec.FLOAT.fieldOf(HEALTH_MODIFIER_KEY).forGetter(Data::healthModifier) + ).apply(i, Data::new)); + + public static Data DEFAULT = new Data(0.0F); + } + + public static class Manager { + private static final Map players = new HashMap<>(); + + public static LifeStealer getLifeStealer(ServerPlayerEntity player) { + return players.computeIfAbsent(player.getUuid(), k -> new LifeStealer(player, Data.DEFAULT)); + } + + @Nullable + public static LifeStealer getLifeStealer(UUID uuid) { + return players.get(uuid); + } + } +} -- cgit v1.2.3