diff --git a/src/main/java/org/auioc/mcmod/arnicalib/game/effect/EffectUtils.java b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/EffectUtils.java new file mode 100644 index 00000000..9abd8e9b --- /dev/null +++ b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/EffectUtils.java @@ -0,0 +1,52 @@ +package org.auioc.mcmod.arnicalib.game.effect; + +import java.util.ArrayList; +import java.util.function.Predicate; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; + +public interface EffectUtils { + + static void removeEffect(LivingEntity entity, Predicate predicate) { + var toRemove = new ArrayList(); + + entity.getActiveEffects().forEach((instance) -> { + if (predicate.test(instance)) toRemove.add(instance.getEffect()); + }); + + toRemove.forEach((effect) -> entity.removeEffect(effect)); + } + + static int getEffectLevel(LivingEntity entity, MobEffect effect) { + var instance = entity.getEffect(effect); + return (instance == null) ? 0 : instance.getAmplifier() + 1; + } + + static MobEffectInstance makeIncurable(MobEffectInstance instance) { + instance.setCurativeItems(new ArrayList()); + return instance; + } + + + static void setDuration(MobEffectInstance instance, int duration) { + ((IHMobEffectInstance) instance).setDuration(duration); + } + + static void setAmplifier(MobEffectInstance instance, int amplifier) { + ((IHMobEffectInstance) instance).setAmplifier(amplifier); + } + + @Deprecated + static void setDurationReflection(MobEffectInstance instance, int duration) { + ObfuscationReflectionHelper.setPrivateValue(MobEffectInstance.class, instance, duration, "f_19503_"); + } + + @Deprecated + static void setAmplifierReflection(MobEffectInstance instance, int amplifier) { + ObfuscationReflectionHelper.setPrivateValue(MobEffectInstance.class, instance, amplifier, "f_19504_"); + } + +} diff --git a/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectInstanceSerializer.java b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectInstanceSerializer.java new file mode 100644 index 00000000..ef69adf9 --- /dev/null +++ b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectInstanceSerializer.java @@ -0,0 +1,81 @@ +package org.auioc.mcmod.arnicalib.game.effect; + +import java.util.ArrayList; +import java.util.List; +import org.auioc.mcmod.arnicalib.base.validate.Validate; +import org.auioc.mcmod.arnicalib.utils.game.ItemUtils; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import net.minecraft.util.GsonHelper; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.item.ItemStack; + +public class MobEffectInstanceSerializer { + + public static MobEffectInstance fromJson(JsonObject json) { + String id = GsonHelper.getAsString(json, "id"); + MobEffect effect = MobEffectRegistry.getOrElseThrow(id); + + int duration = GsonHelper.getAsInt(json, "duration", 1); + + int amplifier = GsonHelper.getAsInt(json, "amplifier", 0); + Validate.isInCloseInterval(0, 255, amplifier); + + boolean ambient = GsonHelper.getAsBoolean(json, "ambient", false); + boolean visible = GsonHelper.getAsBoolean(json, "visible", true); + boolean showIcon = GsonHelper.getAsBoolean(json, "show_icon", true); + + MobEffectInstance hiddenEffect = (MobEffectInstance) null; + if (json.has("hidden_effect")) { + JsonObject hiddenEffectJson = GsonHelper.getAsJsonObject(json, "hidden_effect"); + if (hiddenEffectJson.has("id") && !GsonHelper.getAsString(hiddenEffectJson, "id").equals(id)) throw new JsonSyntaxException("The id of the hidden effect must be unset or equal to the parent effect"); + else hiddenEffectJson.addProperty("id", id); + if (GsonHelper.getAsInt(hiddenEffectJson, "duration", 1) <= duration) throw new JsonSyntaxException("The duration of the hidden effect must be greater than the parent effect"); + hiddenEffect = fromJson(hiddenEffectJson); + } + + MobEffectInstance instance = new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon, hiddenEffect); + + if (json.has("curative_items")) { + JsonArray curativeItemsJson = GsonHelper.getAsJsonArray(json, "curative_items"); + List curativeItems = new ArrayList(); + for (var element : curativeItemsJson) { + var curativeItemId = GsonHelper.convertToString(element, "curative_item"); + curativeItems.add(new ItemStack(ItemUtils.getItemOrElseThrow(curativeItemId))); + } + instance.setCurativeItems(curativeItems); + } + + return instance; + } + + public static void toJson(MobEffectInstance instance, JsonObject json) { + json.addProperty("id", instance.getEffect().getRegistryName().toString()); + json.addProperty("duration", instance.getDuration()); + json.addProperty("amplifier", instance.getAmplifier()); + json.addProperty("ambient", instance.isAmbient()); + json.addProperty("visible", instance.isVisible()); + json.addProperty("show_icon", instance.showIcon()); + + JsonArray curativeItems = new JsonArray(); + for (ItemStack itemStack : instance.getCurativeItems()) { + curativeItems.add(itemStack.getItem().getRegistryName().toString()); + } + json.add("curative_items", curativeItems); + + if (((IHMobEffectInstance) instance).getHiddenEffect() != null) { + JsonObject hiddenEffect = new JsonObject(); + toJson(((IHMobEffectInstance) instance).getHiddenEffect(), hiddenEffect); + json.add("hidden_effect", hiddenEffect); + } + } + + public static JsonObject toJson(MobEffectInstance instance) { + JsonObject json = new JsonObject(); + toJson(instance, json); + return json; + } + +} diff --git a/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectPredicates.java b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectPredicates.java new file mode 100644 index 00000000..ad78d4e8 --- /dev/null +++ b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectPredicates.java @@ -0,0 +1,14 @@ +package org.auioc.mcmod.arnicalib.game.effect; + +import java.util.function.Predicate; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.effect.MobEffectInstance; + +public class MobEffectPredicates { + + public static final Predicate IS_BENEFICIAL = (e) -> e.getEffect().isBeneficial(); + public static final Predicate IS_NOT_BENEFICIAL = (e) -> !e.getEffect().isBeneficial(); + public static final Predicate IS_HARMFUL = (e) -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL; + public static final Predicate IS_NEUTRAL = (e) -> e.getEffect().getCategory() == MobEffectCategory.NEUTRAL; + +} diff --git a/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectRegistry.java b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectRegistry.java new file mode 100644 index 00000000..360480ba --- /dev/null +++ b/src/main/java/org/auioc/mcmod/arnicalib/game/effect/MobEffectRegistry.java @@ -0,0 +1,81 @@ +package org.auioc.mcmod.arnicalib.game.effect; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.auioc.mcmod.arnicalib.base.random.RandomUtils; +import org.auioc.mcmod.arnicalib.game.registry.RegistryEntryException; +import org.auioc.mcmod.arnicalib.utils.game.OrderedForgeRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraftforge.registries.ForgeRegistries; + +public class MobEffectRegistry { + + @Nonnull + @Deprecated + public static Optional get(int id) { + return Optional.ofNullable(MobEffect.byId(id)); + } + + @Nonnull + public static Optional get(ResourceLocation id) { + return Optional.ofNullable(ForgeRegistries.MOB_EFFECTS.containsKey(id) ? ForgeRegistries.MOB_EFFECTS.getValue(id) : null); + } + + @Nonnull + public static Optional get(String id) { + return get(new ResourceLocation(id)); + } + + @Nonnull + public static MobEffect getOrElseThrow(ResourceLocation id) { + return get(id).orElseThrow(RegistryEntryException.UNKNOWN_MOB_EFFECT.create(id.toString())); + } + + @Nonnull + public static MobEffect getOrElseThrow(String id) { + return get(id).orElseThrow(RegistryEntryException.UNKNOWN_MOB_EFFECT.create(id)); + } + + public static List getAll(@Nullable MobEffectCategory type) { + var effectsList = new ArrayList(); + for (var effect : ForgeRegistries.MOB_EFFECTS.getValues()) { + if (type == null || effect.getCategory() == type) { + effectsList.add(effect); + } + } + return effectsList; + } + + public static List getHarmfulEffects() { + return getAll(MobEffectCategory.HARMFUL); + } + + public static List getBeneficialEffects() { + return getAll(MobEffectCategory.BENEFICIAL); + } + + public static List getNeutralEffects() { + return getAll(MobEffectCategory.NEUTRAL); + } + + public static List getAll() { + return getAll(null); + } + + public static MobEffect getRandom(boolean useOrderedRegestry) { + if (useOrderedRegestry) { + return RandomUtils.pickOneFromList(OrderedForgeRegistries.MOB_EFFECTS.get()).getValue(); + } + return RandomUtils.pickOneFromCollection(ForgeRegistries.MOB_EFFECTS.getValues()); + } + + public static MobEffect getRandom() { + return getRandom(true); + } + +} diff --git a/src/main/java/org/auioc/mcmod/arnicalib/server/loot/function/SetCustomEffectsFunction.java b/src/main/java/org/auioc/mcmod/arnicalib/server/loot/function/SetCustomEffectsFunction.java index 253e0973..b718ddd7 100644 --- a/src/main/java/org/auioc/mcmod/arnicalib/server/loot/function/SetCustomEffectsFunction.java +++ b/src/main/java/org/auioc/mcmod/arnicalib/server/loot/function/SetCustomEffectsFunction.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.List; import org.auioc.mcmod.arnicalib.base.validate.Validate; +import org.auioc.mcmod.arnicalib.game.effect.MobEffectInstanceSerializer; import org.auioc.mcmod.arnicalib.server.loot.AHLootItemFunctions; -import org.auioc.mcmod.arnicalib.utils.game.EffectUtils; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonElement; @@ -49,7 +49,7 @@ public SetCustomEffectsFunction deserialize(JsonObject json, JsonDeserialization JsonArray effectsJson = GsonHelper.getAsJsonArray(json, "effects"); Validate.isTrue(!effectsJson.isEmpty(), "The mob effect instance list must be not empty"); for (JsonElement element : effectsJson) { - effects.add(EffectUtils.deserializeFromJson(GsonHelper.convertToJsonObject(element, "mobEffectInstance"))); + effects.add(MobEffectInstanceSerializer.fromJson(GsonHelper.convertToJsonObject(element, "mobEffectInstance"))); } return new SetCustomEffectsFunction(conditions, effects); diff --git a/src/main/java/org/auioc/mcmod/arnicalib/utils/game/EffectUtils.java b/src/main/java/org/auioc/mcmod/arnicalib/utils/game/EffectUtils.java deleted file mode 100644 index e3d03d07..00000000 --- a/src/main/java/org/auioc/mcmod/arnicalib/utils/game/EffectUtils.java +++ /dev/null @@ -1,218 +0,0 @@ -package org.auioc.mcmod.arnicalib.utils.game; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.function.Predicate; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.auioc.mcmod.arnicalib.base.random.RandomUtils; -import org.auioc.mcmod.arnicalib.base.validate.Validate; -import org.auioc.mcmod.arnicalib.game.effect.IHMobEffectInstance; -import org.auioc.mcmod.arnicalib.game.registry.RegistryEntryException; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonSyntaxException; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectCategory; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.fml.util.ObfuscationReflectionHelper; -import net.minecraftforge.registries.ForgeRegistries; - -public interface EffectUtils { - - @Nonnull - @Deprecated - static Optional getEffect(int id) { - return Optional.ofNullable(MobEffect.byId(id)); - } - - @Nonnull - static Optional getEffect(ResourceLocation id) { - return Optional.ofNullable(ForgeRegistries.MOB_EFFECTS.containsKey(id) ? ForgeRegistries.MOB_EFFECTS.getValue(id) : null); - } - - @Nonnull - static Optional getEffect(String id) { - return getEffect(new ResourceLocation(id)); - } - - @Nonnull - static MobEffect getEffectOrElseThrow(ResourceLocation id) { - return getEffect(id).orElseThrow(RegistryEntryException.UNKNOWN_MOB_EFFECT.create(id.toString())); - } - - @Nonnull - static MobEffect getEffectOrElseThrow(String id) { - return getEffect(id).orElseThrow(RegistryEntryException.UNKNOWN_MOB_EFFECT.create(id)); - } - - static List getEffects(@Nullable MobEffectCategory type) { - Collection effects = ForgeRegistries.MOB_EFFECTS.getValues(); - List effectsList = new ArrayList<>(); - for (MobEffect effect : effects) { - if (type == null || effect.getCategory() == type) { - effectsList.add(effect); - } - } - return effectsList; - } - - static List getHarmfulEffects() { - return getEffects(MobEffectCategory.HARMFUL); - } - - static List getBeneficialEffects() { - return getEffects(MobEffectCategory.BENEFICIAL); - } - - static List getNeutralEffects() { - return getEffects(MobEffectCategory.NEUTRAL); - } - - static List getAllEffects() { - return getEffects(null); - } - - static MobEffect getRandomEffect(boolean useOrderedRegestry) { - if (useOrderedRegestry) { - return RandomUtils.pickOneFromList(OrderedForgeRegistries.MOB_EFFECTS.get()).getValue(); - } - return RandomUtils.pickOneFromCollection(ForgeRegistries.MOB_EFFECTS.getValues()); - } - - - @Nullable - static MobEffectInstance createInstance(CompoundTag effect_nbt) { - if (effect_nbt.contains("id", 8) && effect_nbt.contains("duration", 3) && effect_nbt.contains("amplifier", 3)) { - return new MobEffectInstance( - getEffectOrElseThrow(effect_nbt.getString("id")), - effect_nbt.getInt("duration"), - effect_nbt.getInt("amplifier") - ); - } - return null; - } - - static MobEffectInstance deserializeFromJson(JsonObject json) { - String id = GsonHelper.getAsString(json, "id"); - MobEffect effect = getEffectOrElseThrow(id); - - int duration = GsonHelper.getAsInt(json, "duration", 1); - - int amplifier = GsonHelper.getAsInt(json, "amplifier", 0); - Validate.isInCloseInterval(0, 255, amplifier); - - boolean ambient = GsonHelper.getAsBoolean(json, "ambient", false); - boolean visible = GsonHelper.getAsBoolean(json, "visible", true); - boolean showIcon = GsonHelper.getAsBoolean(json, "show_icon", true); - - MobEffectInstance hiddenEffect = (MobEffectInstance) null; - if (json.has("hidden_effect")) { - JsonObject hiddenEffectJson = GsonHelper.getAsJsonObject(json, "hidden_effect"); - if (hiddenEffectJson.has("id") && !GsonHelper.getAsString(hiddenEffectJson, "id").equals(id)) throw new JsonSyntaxException("The id of the hidden effect must be unset or equal to the parent effect"); - else hiddenEffectJson.addProperty("id", id); - if (GsonHelper.getAsInt(hiddenEffectJson, "duration", 1) <= duration) throw new JsonSyntaxException("The duration of the hidden effect must be greater than the parent effect"); - hiddenEffect = deserializeFromJson(hiddenEffectJson); - } - - MobEffectInstance instance = new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon, hiddenEffect); - - if (json.has("curative_items")) { - JsonArray curativeItemsJson = GsonHelper.getAsJsonArray(json, "curative_items"); - List curativeItems = new ArrayList(); - for (var element : curativeItemsJson) { - var curativeItemId = GsonHelper.convertToString(element, "curative_item"); - curativeItems.add(new ItemStack(ItemUtils.getItemOrElseThrow(curativeItemId))); - } - instance.setCurativeItems(curativeItems); - } - - return instance; - } - - static void serializeToJson(MobEffectInstance instance, JsonObject json) { - json.addProperty("id", instance.getEffect().getRegistryName().toString()); - json.addProperty("duration", instance.getDuration()); - json.addProperty("amplifier", instance.getAmplifier()); - json.addProperty("ambient", instance.isAmbient()); - json.addProperty("visible", instance.isVisible()); - json.addProperty("show_icon", instance.showIcon()); - - JsonArray curativeItems = new JsonArray(); - for (ItemStack itemStack : instance.getCurativeItems()) { - curativeItems.add(itemStack.getItem().getRegistryName().toString()); - } - json.add("curative_items", curativeItems); - - if (((IHMobEffectInstance) instance).getHiddenEffect() != null) { - JsonObject hiddenEffect = new JsonObject(); - serializeToJson(((IHMobEffectInstance) instance).getHiddenEffect(), hiddenEffect); - json.add("hidden_effect", hiddenEffect); - } - } - - static JsonObject serializeToJson(MobEffectInstance instance) { - JsonObject json = new JsonObject(); - serializeToJson(instance, json); - return json; - } - - - static void removeEffect(LivingEntity entity, Predicate condition) { - List toRemove = new ArrayList<>(); - - entity.getActiveEffects().forEach(instance -> { - if (condition.test(instance)) { - toRemove.add(instance.getEffect()); - } - }); - - toRemove.forEach(effect -> entity.removeEffect(effect)); - } - - Predicate IS_BENEFICIAL = (e) -> e.getEffect().isBeneficial(); - Predicate IS_NOT_BENEFICIAL = (e) -> !e.getEffect().isBeneficial(); - Predicate IS_HARMFUL = (e) -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL; - Predicate IS_NEUTRAL = (e) -> e.getEffect().getCategory() == MobEffectCategory.NEUTRAL; - - - static int getEffectLevel(LivingEntity entity, MobEffect effect) { - MobEffectInstance instance = entity.getEffect(effect); - if (instance == null) { - return 0; - } - return instance.getAmplifier() + 1; - } - - static MobEffectInstance makeIncurable(MobEffectInstance instance) { - instance.setCurativeItems(new ArrayList()); - return instance; - } - - static void setDuration(MobEffectInstance instance, int duration) { - ((IHMobEffectInstance) instance).setDuration(duration); - } - - - static void setAmplifier(MobEffectInstance instance, int amplifier) { - ((IHMobEffectInstance) instance).setAmplifier(amplifier); - } - - @Deprecated - static void setDurationReflection(MobEffectInstance instance, int duration) { - ObfuscationReflectionHelper.setPrivateValue(MobEffectInstance.class, instance, duration, "f_19503_"); - } - - @Deprecated - static void setAmplifierReflection(MobEffectInstance instance, int amplifier) { - ObfuscationReflectionHelper.setPrivateValue(MobEffectInstance.class, instance, amplifier, "f_19504_"); - } - -}