From 6c7291d24c674d61554869212d1a20f670b9b84a Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 7 Oct 2024 01:39:00 +0100 Subject: [PATCH] Update enchantment logic to use tags and fix the getLevel methods to work with the asked for enchantment --- .../com/minelittlepony/unicopia/UTags.java | 12 ++ .../ability/EarthPonyStompAbility.java | 11 +- .../magic/spell/effect/AttractionUtils.java | 4 +- .../unicopia/block/JarBlock.java | 7 +- .../providers/UEnchantmentProvider.java | 7 +- .../unicopia/entity/Living.java | 4 +- .../entity/ai/WantItNeedItSensor.java | 4 +- .../unicopia/entity/ai/WantItTakeItGoal.java | 3 +- .../unicopia/entity/player/PlayerPhysics.java | 18 +-- .../ConsumptionEnchantmentUtil.java | 4 +- .../item/enchantment/EnchantmentUtil.java | 111 ++++++++++++++++-- .../GroupBasedAttributeEnchantmentEffect.java | 11 +- 12 files changed, 146 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index f2c0080b..b7f44a49 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia; import net.minecraft.block.Block; +import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.EntityType; import net.minecraft.entity.damage.DamageType; import net.minecraft.entity.effect.StatusEffect; @@ -157,4 +158,15 @@ public interface UTags { return TagKey.of(RegistryKeys.SOUND_EVENT, Unicopia.id(name)); } } + + interface Enchantments { + TagKey HERDING = enchantment("herding"); + TagKey CAN_BREAK_JARS_SAFELY = enchantment("can_break_jars_safely"); + TagKey CONVERTS_DROPS_TO_XP = enchantment("converts_drops_to_xp"); + TagKey PERMITS_CLOUD_INTERACTION = enchantment("permits_cloud_interaction"); + + private static TagKey enchantment(String name) { + return TagKey.of(RegistryKeys.ENCHANTMENT, Unicopia.id(name)); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java index 7e50df3b..6fac4764 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java @@ -16,7 +16,6 @@ import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; -import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.server.world.BlockDestructionManager; @@ -125,7 +124,7 @@ public class EarthPonyStompAbility implements Ability { player.fallDistance = 0; BlockPos center = PosHelper.findSolidGroundAt(player.getEntityWorld(), player.getBlockPos(), iplayer.getPhysics().getGravitySignum()); - float heavyness = 1 + EnchantmentUtil.getLevel(UEnchantments.HEAVY, player); + float heavyness = EnchantmentUtil.getWeight(player); iplayer.asWorld().getOtherEntities(player, areaOfEffect.offset(iplayer.getOriginVector())).forEach(i -> { double dist = Math.sqrt(center.getSquaredDistance(i.getBlockPos())); @@ -133,8 +132,8 @@ public class EarthPonyStompAbility implements Ability { if (dist <= rad + 3) { double inertia = 2 / dist; - if (i instanceof LivingEntity) { - inertia *= 1 + EnchantmentUtil.getLevel(UEnchantments.HEAVY, (LivingEntity)i); + if (i instanceof LivingEntity l) { + inertia *= EnchantmentUtil.getWeight(l); } inertia /= heavyness; @@ -158,8 +157,8 @@ public class EarthPonyStompAbility implements Ability { } } - if (i instanceof LivingEntity) { - amount /= 1 + (EnchantmentUtil.getLevel(UEnchantments.PADDED, (LivingEntity)i) / 6F); + if (i instanceof LivingEntity l) { + amount /= EnchantmentUtil.getImpactReduction(l); } i.damage(iplayer.damageOf(UDamageTypes.SMASH, iplayer), (float)amount); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractionUtils.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractionUtils.java index 66272eff..a2f9fce1 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractionUtils.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractionUtils.java @@ -6,8 +6,6 @@ import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; -import com.minelittlepony.unicopia.item.enchantment.UEnchantments; - import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; @@ -44,7 +42,7 @@ public interface AttractionUtils { center = target.getPos().subtract(center).normalize().multiply(force); if (target instanceof LivingEntity) { - center = center.multiply(1 / (1 + EnchantmentUtil.getLevel(UEnchantments.HEAVY, (LivingEntity)target))); + center = center.multiply(1 / EnchantmentUtil.getWeight((LivingEntity)target)); } target.addVelocity( diff --git a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java index aa1975e5..fa6711f6 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java @@ -4,8 +4,8 @@ import java.util.Optional; import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.item.WeatherJarItem; -import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.mojang.serialization.MapCodec; @@ -15,7 +15,7 @@ import net.minecraft.block.ShapeContext; import net.minecraft.block.TransparentBlock; import net.minecraft.block.Waterloggable; import net.minecraft.block.entity.BlockEntity; -import net.minecraft.enchantment.Enchantments; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.FluidState; import net.minecraft.fluid.Fluids; @@ -100,8 +100,7 @@ public class JarBlock extends TransparentBlock implements Waterloggable { @Override public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { super.afterBreak(world, player, pos, state, blockEntity, tool); - // TODO: Enchantment tag - if (EnchantmentUtil.getLevel(world, Enchantments.SILK_TOUCH, tool) == 0 && !player.shouldCancelInteraction()) { + if (EnchantmentHelper.hasAnyEnchantmentsIn(tool, UTags.Enchantments.CAN_BREAK_JARS_SAFELY) && !player.shouldCancelInteraction()) { if (asItem() instanceof WeatherJarItem jar) { jar.releaseContents(world, pos); } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UEnchantmentProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UEnchantmentProvider.java index e75de143..f1c5faef 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UEnchantmentProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UEnchantmentProvider.java @@ -15,6 +15,7 @@ import net.minecraft.component.EnchantmentEffectComponentTypes; import net.minecraft.component.type.AttributeModifierSlot; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentLevelBasedValue; +import net.minecraft.enchantment.Enchantments; import net.minecraft.enchantment.effect.AttributeEnchantmentEffect; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributes; @@ -92,7 +93,7 @@ public class UEnchantmentProvider extends DataGenRegistryProvider { EntityAttributes.GENERIC_ATTACK_DAMAGE, EnchantmentLevelBasedValue.linear(0, 1), Operation.ADD_VALUE - ), EnchantmentLevelBasedValue.linear(2, 2)))); + ), EnchantmentLevelBasedValue.linear(2, 2), UTags.Enchantments.HERDING))); register(registry, UEnchantments.REPULSION, Enchantment.builder( Enchantment.definition( @@ -189,5 +190,9 @@ public class UEnchantmentProvider extends DataGenRegistryProvider { tagProvider.getOrCreateTagBuilder(EnchantmentTags.CURSE).add( UEnchantments.WANT_IT_NEED_IT, UEnchantments.POISONED_JOKE, UEnchantments.STRESSED ); + tagProvider.getOrCreateTagBuilder(UTags.Enchantments.HERDING).add(UEnchantments.HERDS); + tagProvider.getOrCreateTagBuilder(UTags.Enchantments.CAN_BREAK_JARS_SAFELY).add(Enchantments.SILK_TOUCH); + tagProvider.getOrCreateTagBuilder(UTags.Enchantments.CONVERTS_DROPS_TO_XP).add(UEnchantments.CONSUMPTION); + tagProvider.getOrCreateTagBuilder(UTags.Enchantments.PERMITS_CLOUD_INTERACTION).add(UEnchantments.FEATHER_TOUCH); } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 48680ca1..dc881d44 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -204,7 +204,7 @@ public abstract class Living implements Equine, Caste @Override public boolean hasFeatherTouch() { - return EnchantmentUtil.getLevel(UEnchantments.FEATHER_TOUCH, entity) > 0; + return EnchantmentUtil.hasAnyEnchantmentsIn(entity, UTags.Enchantments.PERMITS_CLOUD_INTERACTION); } @Override @@ -378,7 +378,7 @@ public abstract class Living implements Equine, Caste } if (source instanceof MagicalDamageSource magical) { - Caster attacker = ((MagicalDamageSource)source).getSpell(); + Caster attacker = magical.getSpell(); if (attacker != null) { this.attacker = attacker; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItNeedItSensor.java b/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItNeedItSensor.java index 1a838027..f76e7e42 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItNeedItSensor.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItNeedItSensor.java @@ -4,8 +4,6 @@ import java.util.Set; import com.google.common.collect.ImmutableSet; import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; -import com.minelittlepony.unicopia.item.enchantment.UEnchantments; - import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.ai.brain.sensor.Sensor; @@ -22,7 +20,7 @@ public class WantItNeedItSensor extends Sensor { protected void sense(ServerWorld world, LivingEntity entity) { entity.getBrain().getOptionalMemory(MemoryModuleType.VISIBLE_MOBS).ifPresent(targets -> { entity.getBrain().remember(MemoryModuleType.ATTACK_TARGET, targets - .findFirst(e -> (EnchantmentUtil.getLevel(UEnchantments.WANT_IT_NEED_IT, e) * 10) >= entity.distanceTo(e))); + .findFirst(e -> (EnchantmentUtil.getWantItNeedItLevel(e) * 10) >= entity.distanceTo(e))); }); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItTakeItGoal.java b/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItTakeItGoal.java index 9bd1b5af..491b733a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItTakeItGoal.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ai/WantItTakeItGoal.java @@ -4,7 +4,6 @@ import com.minelittlepony.unicopia.AwaitTickQueue; import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.entity.Creature; import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; -import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.particle.FollowingParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; @@ -76,7 +75,7 @@ public class WantItTakeItGoal extends BreakHeartGoal { if (mob.getWorld().random.nextInt(20) == 0) { for (EquipmentSlot slot : EquipmentSlot.values()) { ItemStack stack = living.getEquippedStack(slot); - if (EnchantmentUtil.getLevel(UEnchantments.WANT_IT_NEED_IT, stack) > 0) { + if (EnchantmentUtil.getWantItNeedItLevel(stack) > 0) { AwaitTickQueue.scheduleTask(mob.getWorld(), w -> { living.equipStack(slot, ItemStack.EMPTY); mob.tryEquip(stack); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 38dc3dbf..4f33a55c 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -24,7 +24,6 @@ import com.minelittlepony.unicopia.item.AmuletItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.component.Charges; import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; -import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgPlayerFlightControlsInput; import com.minelittlepony.unicopia.network.track.DataTracker; @@ -388,7 +387,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.z = MathHelper.clamp(velocity.z, -maximum, maximum); if (!entity.isOnGround()) { - float heavyness = 1 + EnchantmentUtil.getLevel(UEnchantments.HEAVY, entity) * 0.009F; + float heavyness = EnchantmentUtil.getAirResistance(entity); velocity.x /= heavyness; velocity.z /= heavyness; } @@ -654,11 +653,10 @@ public class PlayerPhysics extends EntityPhysics implements Tickab float distance = (float)(motion * 20 - 3); - float bouncyness = EnchantmentUtil.getLevel(UEnchantments.PADDED, entity) * 6; - if (distance > 0) { wallHitCooldown = MAX_WALL_HIT_CALLDOWN; + float bouncyness = EnchantmentUtil.getBouncyness(entity); if (bouncyness > 0) { playSound(USounds.ENTITY_PLAYER_REBOUND, 1, entity.getSoundPitch()); ProjectileUtil.ricochet(entity, Vec3d.of(pos), 0.4F + Math.min(2, bouncyness / 18F)); @@ -750,13 +748,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab } } - float heavyness = EnchantmentUtil.getLevel(UEnchantments.HEAVY, entity); - float thrustStrength = 0.235F * thrustScale; - - if (heavyness > 0) { - thrustStrength /= 1 + heavyness; - } - + float thrustStrength = (0.235F * thrustScale) / EnchantmentUtil.getWeight(entity); Vec3d direction = entity.getRotationVec(1).normalize().multiply(thrustStrength); if (hovering || !manualFlap) { @@ -768,7 +760,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab } else { velocity.x += direction.x * 1.3F; velocity.z += direction.z * 1.3F; - velocity.y += ((direction.y * 2.45 + Math.abs(direction.y) * 10));// - heavyness / 5F + velocity.y += ((direction.y * 2.45 + Math.abs(direction.y) * 10)); } if (velocity.y < 0 && hovering) { @@ -791,7 +783,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab SoundEmitter.playSoundAt(entity, USounds.AMBIENT_WIND_GUST, SoundCategory.AMBIENT, 3, 1); } - float weight = 1 + (EnchantmentUtil.getLevel(UEnchantments.HEAVY, entity) * 0.8F) + (pony.getCompositeRace().canUseEarth() ? 1 : 0); + float weight = EnchantmentUtil.getWindBuffetResistance(entity); Vec3d airflow = WeatherConditions.getAirflow(entity.getBlockPos(), entity.getWorld()) .multiply(0.04F * effectStrength) diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/ConsumptionEnchantmentUtil.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/ConsumptionEnchantmentUtil.java index b3fd18dc..4a4bd47f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/ConsumptionEnchantmentUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/ConsumptionEnchantmentUtil.java @@ -5,12 +5,14 @@ import java.util.function.DoubleSupplier; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.util.VecHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.ExperienceOrbEntity; import net.minecraft.entity.LivingEntity; @@ -31,7 +33,7 @@ public class ConsumptionEnchantmentUtil { tool = l.getMainHandStack(); } - if (EnchantmentUtil.getLevel(w, UEnchantments.CONSUMPTION, tool) <= 0) { + if (!EnchantmentHelper.hasAnyEnchantmentsIn(tool, UTags.Enchantments.CONVERTS_DROPS_TO_XP)) { return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java index 7585f043..16c9d943 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java @@ -1,14 +1,22 @@ package com.minelittlepony.unicopia.item.enchantment; +import java.util.function.Predicate; + import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.entity.Living; +import com.minelittlepony.unicopia.util.RegistryUtils; +import net.minecraft.component.ComponentType; +import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.ItemEnchantmentsComponent; import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentEffectContext; import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.FlyingItemEntity; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.effect.StatusEffect; @@ -17,9 +25,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.tag.TagKey; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.random.Random; -import net.minecraft.world.World; public interface EnchantmentUtil { String HEART_BOUND_CONSUMED_FLAG = "unicopia:heart_bound_consumed"; @@ -44,14 +52,15 @@ public interface EnchantmentUtil { static boolean prefersEquipment(ItemStack newStack, ItemStack oldStack) { - int newLevel = EnchantmentUtil.getLevel(UEnchantments.WANT_IT_NEED_IT, newStack); - int oldLevel = EnchantmentUtil.getLevel(UEnchantments.WANT_IT_NEED_IT, oldStack); + int newLevel = getWantItNeedItLevel(newStack); + int oldLevel = getWantItNeedItLevel(oldStack); return newLevel > oldLevel; } static int getWantItNeedItLevel(Entity entity) { return entity instanceof LivingEntity l ? getWantItNeedItLevel(l) : entity instanceof ItemEntity i ? getWantItNeedItLevel(i) + : entity instanceof FlyingItemEntity p ? getWantItNeedItLevel(p.getStack()) : 0; } @@ -63,6 +72,11 @@ public interface EnchantmentUtil { return getLevel(UEnchantments.WANT_IT_NEED_IT, entity); } + static int getWantItNeedItLevel(ItemStack stack) { + return getLevel(UEnchantments.WANT_IT_NEED_IT, stack); + } + + static int getLuck(int baseline, LivingEntity entity) { boolean naturallyLucky = Living.getOrEmpty(entity).filter(c -> c.getCompositeRace().canUseEarth()).isPresent(); if (naturallyLucky) { @@ -81,21 +95,94 @@ public interface EnchantmentUtil { .filter(entry -> entry.matchesKey(enchantment)).map(enchantments::getLevel).findFirst().orElse(0); } - @Deprecated - static int getLevel(World world, RegistryKey enchantment, ItemStack stack) { - return world.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(Enchantments.LOOTING).map(entry -> { - return EnchantmentHelper.getLevel(entry, stack); - }).orElse(0); + private static boolean forEachEnchantment(ItemStack stack, EquipmentSlot slot, LivingEntity entity, Predicate> consumer) { + if (!stack.isEmpty()) { + ItemEnchantmentsComponent component = stack.get(DataComponentTypes.ENCHANTMENTS); + if (component != null && !component.isEmpty()) { + for (var entry : component.getEnchantmentEntries()) { + RegistryEntry enchantment = entry.getKey(); + if (enchantment.value().slotMatches(slot)) { + if (consumer.test(enchantment)) { + return true; + } + } + } + } + } + + return false; + } + + private static boolean forEachEnchantment(LivingEntity entity, Predicate> predicate) { + for (EquipmentSlot slot : EquipmentSlot.values()) { + if (forEachEnchantment(entity.getEquippedStack(slot), slot, entity, predicate)) { + return true; + } + } + return false; + } + + static boolean hasAnyEnchantmentsIn(LivingEntity user, TagKey tag) { + return forEachEnchantment(user, enchantment -> enchantment.isIn(tag)); + } + + static boolean hasAnyEnchantmentsWith(LivingEntity user, ComponentType componentType) { + return forEachEnchantment(user, enchantment -> enchantment.value().effects().contains(componentType)); + } + + static int getLevel(LivingEntity user, TagKey tag) { + return RegistryUtils.entriesForTag(user.getWorld(), tag) + .stream() + .mapToInt(entry -> EnchantmentHelper.getEquipmentLevel(entry, user)).sum(); } @Deprecated static int getLevel(RegistryKey enchantment, LivingEntity entity) { - return entity.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(Enchantments.LOOTING).map(entry -> { - return EnchantmentHelper.getEquipmentLevel(entry, entity); - }).orElse(0); + return entity.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(enchantment) + .map(entry -> EnchantmentHelper.getEquipmentLevel(entry, entity)) + .orElse(0); + } + + private static int getTotalLevel(RegistryKey enchantment, LivingEntity entity) { + return entity.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(enchantment) + .map(entry -> getTotalEquipmentLevel(entry, entity)) + .orElse(0); + } + + static int getTotalEquipmentLevel(RegistryEntry enchantment, LivingEntity entity) { + int level = 0; + for (ItemStack stack : enchantment.value().getEquipment(entity).values()) { + level += EnchantmentHelper.getLevel(enchantment, stack); + } + return level; } static int getEffectAmplifier(LivingEntity entity, RegistryEntry effect) { return entity.hasStatusEffect(effect) ? entity.getStatusEffect(effect).getAmplifier() : 0; } + + static float getWeight(LivingEntity entity) { + return 1 + getTotalLevel(UEnchantments.HEAVY, entity); + } + + static float getWindBuffetResistance(LivingEntity entity) { + return 1 + (getTotalLevel(UEnchantments.HEAVY, entity) * 0.8F) + (EquinePredicates.PLAYER_EARTH.test(entity) ? 1 : 0); + } + + static float getImpactReduction(LivingEntity entity) { + return 1 + (getTotalLevel(UEnchantments.PADDED, entity) / 6F); + } + + static float getBouncyness(LivingEntity entity) { + return getTotalLevel(UEnchantments.PADDED, entity) * 6; + } + + static float getAirResistance(LivingEntity entity) { + return 1 + getTotalLevel(UEnchantments.HEAVY, entity) * 0.009F; + } + + @FunctionalInterface + interface ContextAwareConsumer { + boolean accept(RegistryEntry enchantment, int level, EnchantmentEffectContext context); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/GroupBasedAttributeEnchantmentEffect.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/GroupBasedAttributeEnchantmentEffect.java index 870b52e0..34775ea9 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/GroupBasedAttributeEnchantmentEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/GroupBasedAttributeEnchantmentEffect.java @@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.entity.Living; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentEffectContext; import net.minecraft.enchantment.EnchantmentLevelBasedValue; import net.minecraft.enchantment.effect.AttributeEnchantmentEffect; @@ -11,16 +12,20 @@ import net.minecraft.enchantment.effect.EnchantmentEntityEffect; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; import net.minecraft.util.math.Vec3d; import net.minecraft.server.world.ServerWorld; public record GroupBasedAttributeEnchantmentEffect ( AttributeEnchantmentEffect attribute, - EnchantmentLevelBasedValue range + EnchantmentLevelBasedValue range, + TagKey validTeamMateEnchantmentKey ) implements EnchantmentEntityEffect { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( AttributeEnchantmentEffect.CODEC.fieldOf("attribute").forGetter(GroupBasedAttributeEnchantmentEffect::attribute), - EnchantmentLevelBasedValue.CODEC.fieldOf("range").forGetter(GroupBasedAttributeEnchantmentEffect::range) + EnchantmentLevelBasedValue.CODEC.fieldOf("range").forGetter(GroupBasedAttributeEnchantmentEffect::range), + TagKey.codec(RegistryKeys.ENCHANTMENT).fieldOf("valid_teammate_enchantment_key").forGetter(GroupBasedAttributeEnchantmentEffect::validTeamMateEnchantmentKey) ).apply(instance, GroupBasedAttributeEnchantmentEffect::new)); @Override @@ -32,7 +37,7 @@ public record GroupBasedAttributeEnchantmentEffect ( public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity user, Vec3d pos) { Living.getOrEmpty(user).ifPresent(living -> { int collectiveLevels = living.findAllEntitiesInRange(range.getValue(level), e -> e instanceof LivingEntity) - .mapToInt(e -> EnchantmentUtil.getLevel(UEnchantments.HERDS, (LivingEntity)e)) + .mapToInt(e -> EnchantmentUtil.getLevel((LivingEntity)e, validTeamMateEnchantmentKey)) .reduce(Integer::sum) .orElse(0);