From ab25ab75560456e7ce71a7d549fa41e68187c11d Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 30 Sep 2024 17:00:29 +0100 Subject: [PATCH] Update some enchantment stuff and update more items code --- .../ability/magic/spell/effect/SpellType.java | 6 ++ .../unicopia/block/JarBlock.java | 5 +- .../unicopia/entity/mob/AirBalloonEntity.java | 22 ++++-- .../unicopia/item/ChameleonItem.java | 10 +-- .../unicopia/item/CrystalHeartItem.java | 5 +- .../unicopia/item/CuringJokeItem.java | 18 ++--- .../unicopia/item/EnchantableItem.java | 16 ++-- .../unicopia/item/EnchantedStaffItem.java | 4 +- .../unicopia/item/FancyBedItem.java | 11 +-- .../unicopia/item/FilledJarItem.java | 78 +++++-------------- .../unicopia/item/ForageableItem.java | 57 +++++++++----- .../unicopia/item/FriendshipBraceletItem.java | 41 ++++------ .../unicopia/item/HotAirBalloonItem.java | 24 ------ .../minelittlepony/unicopia/item/UItems.java | 2 +- .../unicopia/item/ZapAppleItem.java | 10 +-- .../unicopia/item/component/Issuer.java | 77 ++++++++++++++++++ .../item/component/UDataComponentTypes.java | 5 ++ .../item/enchantment/EnchantmentUtil.java | 23 +++++- .../mixin/client/MixinItemModels.java | 2 +- .../projectile/MagicProjectileEntity.java | 17 ++++ 20 files changed, 257 insertions(+), 176 deletions(-) delete mode 100644 src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java create mode 100644 src/main/java/com/minelittlepony/unicopia/item/component/Issuer.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java index 7937120a..50b8db4b 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java @@ -24,9 +24,13 @@ import com.minelittlepony.unicopia.util.RegistryUtils; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.serialization.Codec; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Util; @@ -41,6 +45,8 @@ public final class SpellType implements Affine, SpellPredicate< public static final Registry> REGISTRY = RegistryUtils.createSimple(Unicopia.id("spells")); public static final RegistryKey>> REGISTRY_KEY = REGISTRY.getKey(); + public static final Codec> CODEC = REGISTRY.getCodec(); + public static final PacketCodec> PACKET_CODEC = PacketCodecs.registryValue(REGISTRY_KEY); private static final DynamicCommandExceptionType UNKNOWN_SPELL_TYPE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("spell_type.unknown", id)); diff --git a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java index db3aabe2..90c0c119 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java @@ -5,6 +5,7 @@ import java.util.Optional; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.item.WeatherJarItem; +import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.mojang.serialization.MapCodec; @@ -14,14 +15,12 @@ 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.EnchantmentHelper; import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.FluidState; import net.minecraft.fluid.Fluids; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKeys; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.Properties; @@ -104,7 +103,7 @@ public class JarBlock extends TransparentBlock implements Waterloggable { 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 (EnchantmentHelper.getLevel(world.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(Enchantments.SILK_TOUCH).get(), tool) == 0 && !player.shouldCancelInteraction()) { + if (EnchantmentUtil.getLevel(world, Enchantments.SILK_TOUCH, tool) == 0 && !player.shouldCancelInteraction()) { if (asItem() instanceof WeatherJarItem jar) { jar.releaseContents(world, pos); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java index 8e1b89ac..943ef645 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java @@ -14,6 +14,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.codec.PacketCodec; import net.minecraft.particle.ParticleTypes; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.registry.RegistryKey; @@ -22,7 +23,6 @@ import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.function.ValueLists; import net.minecraft.util.math.*; import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; @@ -37,7 +37,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.function.Function; -import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -56,9 +55,13 @@ import com.minelittlepony.unicopia.entity.collision.MultiBox; import com.minelittlepony.unicopia.item.BasketItem; import com.minelittlepony.unicopia.item.HotAirBalloonItem; import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.component.UDataComponentTypes; import com.minelittlepony.unicopia.server.world.WeatherConditions; +import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils; import com.terraformersmc.terraform.boat.api.TerraformBoatType; +import io.netty.buffer.ByteBuf; + public class AirBalloonEntity extends MobEntity implements EntityCollisions.ComplexCollidable, MultiBoundingBoxEntity, MagicImmune, EquineContext { private static final TrackedData ASCENDING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.BOOLEAN); private static final TrackedData BOOSTING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); @@ -375,7 +378,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (!player.isSneaky()) { getWorld().emitGameEvent(player, GameEvent.EQUIP, getBlockPos()); } - setDesign(HotAirBalloonItem.getDesign(getWorld(), stack)); + setDesign(AirBalloonEntity.BalloonDesign.of(getWorld(), stack)); if (hasBurner() && hasBalloon()) { UCriteria.CONSTRUCT_BALLOON.trigger(player); } @@ -792,8 +795,9 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp STORM, TALE; + private static final BalloonDesign[] VALUES = values(); public static final EnumCodec CODEC = StringIdentifiable.createCodec(BalloonDesign::values); - private static final IntFunction BY_ID = ValueLists.createIdToValueFunction(Enum::ordinal, values(), ValueLists.OutOfBoundsHandling.ZERO); + public static final PacketCodec PACKET_CODEC = PacketCodecUtils.ofEnum(BalloonDesign.class); private final String name = name().toLowerCase(Locale.ROOT); @@ -802,8 +806,16 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp return name; } + public static AirBalloonEntity.BalloonDesign of(World world, ItemStack stack) { + AirBalloonEntity.BalloonDesign design = stack.getOrDefault(UDataComponentTypes.BALLOON_DESIGN, NONE); + if (design == NONE) { + return VALUES[1 + world.getRandom().nextInt(VALUES.length - 1)]; + } + return design; + } + public static BalloonDesign getType(int type) { - return BY_ID.apply(type); + return VALUES[Math.abs(type) % VALUES.length]; } public static BalloonDesign getType(String name) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/ChameleonItem.java b/src/main/java/com/minelittlepony/unicopia/item/ChameleonItem.java index f510d78b..acd87977 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ChameleonItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ChameleonItem.java @@ -12,7 +12,7 @@ public interface ChameleonItem { return true; } - default ItemStack getAppearanceStack(ItemStack stack) { + static ItemStack getAppearanceStack(ItemStack stack) { Item appearance = getAppearance(stack); if (appearance != Items.AIR) { return createAppearanceStack(stack, appearance); @@ -20,7 +20,7 @@ public interface ChameleonItem { return stack; } - default ItemStack createAppearanceStack(ItemStack stack, Item appearance) { + static ItemStack createAppearanceStack(ItemStack stack, Item appearance) { ItemStack newAppearance = appearance.getDefaultStack(); if (stack.hasNbt()) { newAppearance.setNbt(stack.getNbt().copy()); @@ -30,11 +30,11 @@ public interface ChameleonItem { return newAppearance; } - default boolean hasAppearance(ItemStack stack) { + static boolean hasAppearance(ItemStack stack) { return getAppearance(stack) != Items.AIR; } - default Item getAppearance(ItemStack stack) { + static Item getAppearance(ItemStack stack) { if (stack.hasNbt() && stack.getNbt().contains("appearance")) { return Registries.ITEM.get(new Identifier(stack.getNbt().getString("appearance"))); } @@ -42,7 +42,7 @@ public interface ChameleonItem { return Items.AIR; } - default ItemStack setAppearance(ItemStack stack, ItemStack appearance) { + static ItemStack setAppearance(ItemStack stack, ItemStack appearance) { ItemStack result = stack.copy(); if (appearance.hasNbt()) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java index 530f02fe..4e6d857e 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia.item; import java.util.*; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; @@ -72,8 +73,8 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art } if (world instanceof ServerWorld serverWorld) { - - FloatingArtefactEntity entity = UEntities.FLOATING_ARTEFACT.create(serverWorld, context.getStack().getNbt(), null, blockPos, SpawnReason.SPAWN_EGG, false, true); + Consumer consumer = EntityType.copier(serverWorld, context.getStack(), context.getPlayer()); + FloatingArtefactEntity entity = UEntities.FLOATING_ARTEFACT.create(serverWorld, consumer, blockPos, SpawnReason.SPAWN_EGG, false, true); if (entity == null) { return ActionResult.FAIL; diff --git a/src/main/java/com/minelittlepony/unicopia/item/CuringJokeItem.java b/src/main/java/com/minelittlepony/unicopia/item/CuringJokeItem.java index 29635b1b..8e162a4f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/CuringJokeItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/CuringJokeItem.java @@ -12,13 +12,14 @@ import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.util.InventoryUtil; import net.minecraft.block.Block; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.component.DataComponentTypes; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.InventoryOwner; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; +import net.minecraft.registry.tag.EnchantmentTags; import net.minecraft.world.World; public class CuringJokeItem extends BlockItem { @@ -84,15 +85,14 @@ public class CuringJokeItem extends BlockItem { static boolean uncurseItem(LivingEntity user) { return getInventory(user) - .filter(s -> EnchantmentHelper.get(s).keySet().stream().anyMatch(Enchantment::isCursed)) - .findAny() .filter(s -> { - var enchantments = EnchantmentHelper.get(s); - return enchantments.keySet().stream().filter(Enchantment::isCursed).findAny().filter(e -> { - enchantments.remove(e); - EnchantmentHelper.set(enchantments, s); - return true; - }).isPresent(); + var enchantments = s.get(DataComponentTypes.ENCHANTMENTS); + return enchantments != null && enchantments.getEnchantments().stream().anyMatch(entry -> entry.isIn(EnchantmentTags.CURSE)); + }) + .findAny() + .map(s -> { + EnchantmentHelper.apply(s, builder -> builder.remove(entry -> entry.isIn(EnchantmentTags.CURSE))); + return s; }).isPresent(); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java b/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java index 97927b1b..3183cbde 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java @@ -10,12 +10,12 @@ import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.item.component.UDataComponentTypes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; -import net.minecraft.util.Identifier; import net.minecraft.util.TypedActionResult; public interface EnchantableItem extends ItemConvertible { @@ -63,7 +63,7 @@ public interface EnchantableItem extends ItemConvertible { } static boolean isEnchanted(ItemStack stack) { - return !stack.isEmpty() && stack.hasNbt() && stack.getNbt().contains("spell"); + return !getSpellKey(stack).isEmpty(); } static ItemStack enchant(ItemStack stack, SpellType type) { @@ -74,21 +74,23 @@ public interface EnchantableItem extends ItemConvertible { if (type.isEmpty()) { return unenchant(stack); } - stack.getOrCreateNbt().putString("spell", type.getId().toString()); + stack.set(UDataComponentTypes.STORED_SPELL, type); return type.getTraits().applyTo(stack); } static ItemStack unenchant(ItemStack stack) { - stack.removeSubNbt("spell"); - stack.removeSubNbt("spell_traits"); + stack.remove(UDataComponentTypes.STORED_SPELL); + stack.remove(UDataComponentTypes.SPELL_TRAITS); return stack; } static Optional> getSpellKeyOrEmpty(ItemStack stack) { - return isEnchanted(stack) ? SpellType.REGISTRY.getOrEmpty(new Identifier(stack.getNbt().getString("spell"))) : Optional.empty(); + SpellType type = getSpellKey(stack); + return type.isEmpty() ? Optional.empty() : Optional.of(type); } + @SuppressWarnings("unchecked") static SpellType getSpellKey(ItemStack stack) { - return SpellType.getKey(isEnchanted(stack) ? new Identifier(stack.getNbt().getString("spell")) : SpellType.EMPTY_ID); + return (SpellType)stack.getOrDefault(UDataComponentTypes.STORED_SPELL, SpellType.empty()); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java b/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java index 3dbc3dd6..99a7558b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java @@ -5,8 +5,6 @@ import java.util.List; import java.util.Map; import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; - import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod; @@ -226,7 +224,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch @Override public void onDischarge(ItemStack stack) { - if ((stack.hasNbt() && stack.getNbt().contains("energy") ? stack.getNbt().getFloat("energy") : 0) == 0) { + if (ChargeableItem.getEnergy(stack) == 0) { EnchantableItem.unenchant(stack); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java b/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java index c9f2f404..4d34fea5 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java @@ -9,10 +9,10 @@ import com.minelittlepony.unicopia.block.FancyBedBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.NbtComponent; import net.minecraft.item.BedItem; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; import net.minecraft.util.math.BlockPos; public class FancyBedItem extends BedItem implements Supplier { @@ -29,12 +29,13 @@ public class FancyBedItem extends BedItem implements Supplier { return renderEntity.get(); } + @SuppressWarnings("deprecation") public static FancyBedBlock.SheetPattern getPattern(ItemStack stack) { @Nullable - NbtCompound blockEntityNbt = getBlockEntityNbt(stack); - if (blockEntityNbt == null || !blockEntityNbt.contains("pattern", NbtElement.STRING_TYPE)) { + NbtComponent blockEntityNbt = stack.getOrDefault(DataComponentTypes.BLOCK_ENTITY_DATA, NbtComponent.DEFAULT); + if (blockEntityNbt == null || !blockEntityNbt.contains("pattern")) { return FancyBedBlock.SheetPattern.NONE; } - return FancyBedBlock.SheetPattern.byId(blockEntityNbt.getString("pattern")); + return FancyBedBlock.SheetPattern.byId(blockEntityNbt.getNbt().getString("pattern")); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java b/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java index f29188da..38272c3b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.item; import com.minelittlepony.unicopia.USounds; -import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.mob.ButterflyEntity; import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; @@ -10,21 +9,17 @@ import com.minelittlepony.unicopia.projectile.ProjectileDelegate; import net.minecraft.block.Block; import net.minecraft.block.Blocks; 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.LivingEntity; -import net.minecraft.entity.attribute.EntityAttributeInstance; -import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.ProjectileDeflection; +import net.minecraft.entity.damage.DamageSource; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.particle.ParticleTypes; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvent; import net.minecraft.text.Text; import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.math.MathHelper; import net.minecraft.world.WorldEvents; public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.HitListener, ChameleonItem { @@ -39,7 +34,7 @@ public class FilledJarItem extends ProjectileItem implements ProjectileDelegate. @Override public Text getName(ItemStack stack) { - return hasAppearance(stack) ? Text.translatable(getTranslationKey(stack), getAppearanceStack(stack).getName()) : UItems.EMPTY_JAR.getName(UItems.EMPTY_JAR.getDefaultStack()); + return ChameleonItem.hasAppearance(stack) ? Text.translatable(getTranslationKey(stack), ChameleonItem.getAppearanceStack(stack).getName()) : UItems.EMPTY_JAR.getName(UItems.EMPTY_JAR.getDefaultStack()); } @Override @@ -55,71 +50,38 @@ public class FilledJarItem extends ProjectileItem implements ProjectileDelegate. return; } - ItemStack stack = getAppearanceStack(((FlyingItemEntity)projectile).getStack()); + ItemStack stack = ChameleonItem.getAppearanceStack(((FlyingItemEntity)projectile).getStack()); boolean onFire = false; - float prevHealth = 0.0F; - int fire = EnchantmentHelper.getLevel(Enchantments.FIRE_ASPECT, stack); + if (projectile.getWorld() instanceof ServerWorld world) { + DamageSource damageSource = entity.getDamageSources().thrown(projectile, projectile.getOwner()); - if (entity instanceof LivingEntity) { - prevHealth = ((LivingEntity)entity).getHealth(); + float damage = EnchantmentHelper.getDamage(world, stack, entity, damageSource, projectile.getThrowDamage()); - if (fire > 0 && !entity.isOnFire()) { - onFire = true; - entity.setOnFireFor(1); + if (projectile.getOwner() instanceof LivingEntity owner) { + owner.onAttacking(entity); } - } - float damage = EnchantmentHelper.getAttackDamage(stack, entity instanceof LivingEntity ? ((LivingEntity)entity).getGroup() : EntityGroup.DEFAULT); + if (entity.damage(damageSource, damage)) { - EntityAttributeInstance instance = new EntityAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE, i -> {}); - - stack.getAttributeModifiers(EquipmentSlot.MAINHAND).get(EntityAttributes.GENERIC_ATTACK_DAMAGE).forEach(modifier -> { - instance.addTemporaryModifier(modifier); - }); - - damage += instance.getValue(); - - if (entity.damage(entity.getDamageSources().thrown(projectile, projectile.getOwner()), damage)) { - - int knockback = EnchantmentHelper.getLevel(Enchantments.KNOCKBACK, stack); - - final float toRadians = (float)Math.PI / 180F; - - if (entity instanceof LivingEntity living) { - living.takeKnockback( - knockback / 2F, - MathHelper.sin(projectile.getYaw() * toRadians), - -MathHelper.cos(projectile.getYaw() * toRadians) - ); - Living.updateVelocity(living); - - if (fire > 0) { - entity.setOnFireFor(fire * 4); - } - - float healthDiff = prevHealth - ((LivingEntity)entity).getHealth(); - - if (projectile.getWorld() instanceof ServerWorld && healthDiff > 2) { - ((ServerWorld)projectile.getWorld()).spawnParticles(ParticleTypes.DAMAGE_INDICATOR, entity.getX(), entity.getBodyY(0.5D), entity.getZ(), (int)(healthDiff / 2F), 0.1, 0, 0.1, 0.2); + if (entity instanceof LivingEntity living) { + projectile.knockback(living, damageSource, stack); + EnchantmentHelper.onTargetDamaged(world, living, damageSource, stack); } } else { - entity.addVelocity( - -MathHelper.sin(projectile.getYaw() * toRadians) * knockback / 2F, 0.1D, - MathHelper.cos(projectile.getYaw() * toRadians) * knockback / 2F - ); - } - } else { - if (onFire) { - entity.setOnFire(false); + if (onFire) { + entity.setOnFire(false); + } + projectile.deflect(ProjectileDeflection.SIMPLE, entity, projectile.getOwner(), false); + projectile.setVelocity(projectile.getVelocity().multiply(0.2)); } } } @Override public void onImpact(MagicProjectileEntity projectile) { - ItemStack stack = getAppearanceStack(projectile.getStack()); + ItemStack stack = ChameleonItem.getAppearanceStack(projectile.getStack()); if (stack.isOf(UItems.BUTTERFLY)) { ButterflyEntity butterfly = UEntities.BUTTERFLY.create(projectile.getWorld()); @@ -136,6 +98,6 @@ public class FilledJarItem extends ProjectileItem implements ProjectileDelegate. } public ItemStack withContents(ItemStack contents) { - return setAppearance(getDefaultStack(), contents); + return ChameleonItem.setAppearance(getDefaultStack(), contents); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java b/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java index 4688a264..ce15fbe4 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java @@ -12,11 +12,14 @@ import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.HoeItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ToolMaterials; +import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.ItemTags; import net.minecraft.sound.SoundCategory; @@ -51,11 +54,11 @@ public class ForageableItem extends Item { world.playSound(player, pos, state.getSoundGroup().getHitSound(), SoundCategory.BLOCKS); InteractionManager.getInstance().addBlockBreakingParticles(pos, hitResult.getSide()); - int miningLevel = (stack.getItem() instanceof HoeItem hoe ? hoe.getMaterial().getMiningLevel() : 59); + float foragingChance = getForagingChance(stack); for (ForageableItem item : REGISTRY) { - if ((result = item.onTryForage(world, pos, state, stack, player, miningLevel)).isAccepted()) { - stack.damage(1, player, p -> p.sendToolBreakStatus(hand)); + if ((result = item.onTryForage(world, pos, state, stack, player, foragingChance)).isAccepted()) { + stack.damage(1, player, LivingEntity.getSlotForHand(hand)); return result; } } @@ -73,21 +76,39 @@ public class ForageableItem extends Item { REGISTRY.add(this); } - public ActionResult onTryForage(World world, BlockPos pos, BlockState state, ItemStack stack, PlayerEntity player, int miningLevel) { - if (state.isOf(targetBlock.get())) { - int spawnChance = (int)((1F - MathHelper.clamp(miningLevel / (float)ToolMaterials.NETHERITE.getMiningLevel(), 0, 1)) * 32); - spawnChance -= EnchantmentUtil.getLuck(1, player); - - if (spawnChance <= 0 || world.random.nextInt(spawnChance) == 0) { - Block.dropStack(world, pos, new ItemStack(this, 1 + EnchantmentHelper.getLooting(player))); - world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state)); - if (BlockDestructionManager.of(world).damageBlock(pos, world.getRandom().nextBetween(3, 7)) >= BlockDestructionManager.MAX_DAMAGE) { - world.breakBlock(pos, true); - } - return ActionResult.SUCCESS; - } - return ActionResult.FAIL; + public ActionResult onTryForage(World world, BlockPos pos, BlockState state, ItemStack stack, PlayerEntity player, float spawnChance) { + if (!state.isOf(targetBlock.get())) { + return ActionResult.PASS; } - return ActionResult.PASS; + + spawnChance -= EnchantmentUtil.getLuck(1, player); + + if (spawnChance <= 0 || world.random.nextInt((int)(spawnChance * 32)) == 0) { + Block.dropStack(world, pos, new ItemStack(this, 1 + EnchantmentHelper.getEquipmentLevel(player.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(Enchantments.LOOTING).get(), player))); + world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state)); + if (BlockDestructionManager.of(world).damageBlock(pos, world.getRandom().nextBetween(3, 7)) >= BlockDestructionManager.MAX_DAMAGE) { + world.breakBlock(pos, true); + } + return ActionResult.SUCCESS; + } + return ActionResult.FAIL; + } + + static float getForagingChance(ItemStack stack) { + if (!(stack.getItem() instanceof HoeItem hoe)) { + return 0.25F; + } + + float spawnChance = hoe.getMaterial() instanceof ToolMaterials m ? switch(m) { + case WOOD -> 0.25F; + case STONE -> 0.3F; + case IRON -> 0.4F; + case GOLD -> 0.6F; + case DIAMOND -> 0.7F; + case NETHERITE -> 0.8F; + default -> 0.25F; + } : MathHelper.clamp(hoe.getMaterial().getMiningSpeedMultiplier(), 0, 1); + + return 1F - spawnChance; } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java b/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java index 039080f3..4fa8a2f7 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java @@ -14,6 +14,8 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.entity.AmuletSelectors; import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.item.component.Issuer; +import com.minelittlepony.unicopia.item.component.UDataComponentTypes; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -23,7 +25,6 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.Item.TooltipContext; import net.minecraft.item.tooltip.TooltipType; import net.minecraft.stat.Stats; import net.minecraft.text.Text; @@ -47,10 +48,7 @@ public class FriendshipBraceletItem extends WearableItem { )) { player.setCurrentHand(hand); - ItemStack result = stack.copy(); - result.setCount(1); - result.getOrCreateNbt().putString("issuer", player.getName().getString()); - result.getOrCreateNbt().putUuid("issuer_id", player.getUuid()); + ItemStack result = Issuer.set(stack.copyWithCount(1), player); if (!player.getAbilities().creativeMode) { stack.decrement(1); @@ -75,8 +73,8 @@ public class FriendshipBraceletItem extends WearableItem { @Environment(EnvType.CLIENT) public void appendTooltip(ItemStack stack, TooltipContext context, List lines, TooltipType type) { super.appendTooltip(stack, context, lines, type); - if (isSigned(stack)) { - lines.add(Text.translatable("item.unicopia.friendship_bracelet.issuer", getSignatorName(stack))); + if (Issuer.isSigned(stack)) { + stack.get(UDataComponentTypes.ISSUER).appendTooltip(context, lines::add, type); } if (GlowableItem.isGlowing(stack)) { lines.add(Text.translatable("item.unicopia.friendship_bracelet.glowing").formatted(Formatting.ITALIC, Formatting.GRAY)); @@ -85,49 +83,42 @@ public class FriendshipBraceletItem extends WearableItem { @Override public EquipmentSlot getSlotType(ItemStack stack) { - return isSigned(stack) ? EquipmentSlot.CHEST : super.getSlotType(stack); - } - - private boolean checkSignature(ItemStack stack, PlayerEntity player) { - return checkSignature(stack, player.getUuid()); - } - - private boolean checkSignature(ItemStack stack, UUID player) { - return player.equals(getSignatorId(stack)); + return Issuer.isSigned(stack) ? EquipmentSlot.CHEST : super.getSlotType(stack); } @Nullable public static String getSignatorName(ItemStack stack) { - return isSigned(stack) ? stack.getNbt().getString("issuer") : null; + return Issuer.getSignatorName(stack); } @Nullable public static UUID getSignatorId(ItemStack stack) { - return isSigned(stack) ? stack.getNbt().getUuid("issuer_id") : null; + return Issuer.getSignatorId(stack); } + @Deprecated public static boolean isSigned(ItemStack stack) { - return stack.hasNbt() && stack.getNbt().contains("issuer_id"); + return Issuer.isSigned(stack); } + @Deprecated public static boolean isSignedBy(ItemStack stack, PlayerEntity player) { - return stack.getItem() instanceof FriendshipBraceletItem - && ((FriendshipBraceletItem)stack.getItem()).checkSignature(stack, player); + return Issuer.isSignedBy(stack, player); } + @Deprecated public static boolean isSignedBy(ItemStack stack, UUID player) { - return stack.getItem() instanceof FriendshipBraceletItem - && ((FriendshipBraceletItem)stack.getItem()).checkSignature(stack, player); + return Issuer.isSignedBy(stack, player); } public static boolean isComrade(Owned caster, Entity entity) { return entity instanceof LivingEntity l && caster.getMasterId() - .filter(id -> getWornBangles(l).anyMatch(stack -> isSignedBy(stack.stack(), id))) + .filter(id -> getWornBangles(l).anyMatch(stack -> Issuer.isSignedBy(stack.stack(), id))) .isPresent(); } public static boolean isComrade(UUID signator, Entity entity) { - return entity instanceof LivingEntity l && getWornBangles(l, stack -> isSignedBy(stack, signator)).findAny().isPresent(); + return entity instanceof LivingEntity l && getWornBangles(l, stack -> Issuer.isSignedBy(stack, signator)).findAny().isPresent(); } public static Stream getPartyMembers(Caster caster, double radius) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java b/src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java deleted file mode 100644 index 99a63895..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.minelittlepony.unicopia.item; - -import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; - -public class HotAirBalloonItem extends Item { - - public HotAirBalloonItem(Settings settings) { - super(settings); - } - - public static AirBalloonEntity.BalloonDesign getDesign(World world, ItemStack stack) { - String design; - if (stack.hasNbt() && !(design = stack.getNbt().getString("design")).isEmpty()) { - return AirBalloonEntity.BalloonDesign.getType(design); - } - - int ordinal = 1 + world.getRandom().nextInt(AirBalloonEntity.BalloonDesign.values().length - 1); - return AirBalloonEntity.BalloonDesign.getType(ordinal); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 199feeb9..8899241f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -177,7 +177,7 @@ public interface UItems { Item BAMBOO_BASKET = register("bamboo_basket", new BasketItem(AirBalloonEntity.BasketType.of(BoatEntity.Type.BAMBOO), new Item.Settings().maxCount(1)), ItemGroups.TOOLS); Item PALM_BASKET = register("palm_basket", new BasketItem(AirBalloonEntity.BasketType.of(UWoodTypes.PALM_BOAT_TYPE), new Item.Settings().maxCount(1)), ItemGroups.TOOLS); - Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS); + Item GIANT_BALLOON = register("giant_balloon", new Item(new Item.Settings().maxCount(1).component(UDataComponentTypes.BALLOON_DESIGN, AirBalloonEntity.BalloonDesign.NONE)), ItemGroups.TOOLS); Item SPECTRAL_CLOCK = register("spectral_clock", new Item(new Item.Settings()), ItemGroups.TOOLS); Item WHITE_BED_SHEETS = register(CloudBedBlock.SheetPattern.WHITE); diff --git a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java index 39f1f874..b18982cb 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java @@ -37,7 +37,7 @@ import net.minecraft.world.event.GameEvent; public class ZapAppleItem extends Item implements ChameleonItem, MultiItem { public ZapAppleItem(Settings settings) { - super(settings); + super(settings.rarity(Rarity.RARE)); } @Override @@ -105,20 +105,18 @@ public class ZapAppleItem extends Item implements ChameleonItem, MultiItem { .stream() .flatMap(world -> RegistryUtils.valuesForTag(world, UConventionalTags.Items.APPLES)) .filter(a -> a != this).map(item -> { - ItemStack stack = new ItemStack(this); - stack.getOrCreateNbt().putString("appearance", Registries.ITEM.getId(item).toString()); - return stack; + return ChameleonItem.setAppearance(getDefaultStack(), item.getDefaultStack()); }).toList(); } @Override public Text getName(ItemStack stack) { - return hasAppearance(stack) ? getAppearanceStack(stack).getName() : super.getName(stack); + return ChameleonItem.hasAppearance(stack) ? ChameleonItem.getAppearanceStack(stack).getName() : super.getName(stack); } @Override public Rarity getRarity(ItemStack stack) { - if (hasAppearance(stack)) { + if (ChameleonItem.hasAppearance(stack)) { return Rarity.EPIC; } diff --git a/src/main/java/com/minelittlepony/unicopia/item/component/Issuer.java b/src/main/java/com/minelittlepony/unicopia/item/component/Issuer.java new file mode 100644 index 00000000..dea427c6 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/component/Issuer.java @@ -0,0 +1,77 @@ +package com.minelittlepony.unicopia.item.component; + +import java.util.UUID; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item.TooltipContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipAppender; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.text.Text; +import net.minecraft.util.Uuids; + +public record Issuer(String name, UUID id) implements TooltipAppender { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.STRING.fieldOf("name").forGetter(Issuer::name), + Uuids.CODEC.fieldOf("id").forGetter(Issuer::id) + ).apply(instance, Issuer::new)); + public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( + PacketCodecs.STRING, Issuer::name, + Uuids.PACKET_CODEC, Issuer::id, + Issuer::new + ); + + public static ItemStack set(ItemStack stack, Entity signer) { + stack.set(UDataComponentTypes.ISSUER, new Issuer(signer.getDisplayName().getString(), signer.getUuid())); + return stack; + } + + @Override + public void appendTooltip(TooltipContext context, Consumer tooltip, TooltipType type) { + tooltip.accept(Text.translatable("item.unicopia.friendship_bracelet.issuer", name())); + } + + public boolean isSignedBy(PlayerEntity player) { + return isSignedBy(player.getUuid()); + } + + public boolean isSignedBy(UUID player) { + return player.equals(id()); + } + + @Nullable + public static String getSignatorName(ItemStack stack) { + Issuer issuer = stack.get(UDataComponentTypes.ISSUER); + return issuer == null ? null : issuer.name(); + } + + @Nullable + public static UUID getSignatorId(ItemStack stack) { + Issuer issuer = stack.get(UDataComponentTypes.ISSUER); + return issuer == null ? null : issuer.id(); + } + + public static boolean isSigned(ItemStack stack) { + return stack.contains(UDataComponentTypes.ISSUER); + } + + public static boolean isSignedBy(ItemStack stack, PlayerEntity player) { + Issuer issuer = stack.get(UDataComponentTypes.ISSUER); + return issuer != null && issuer.isSignedBy(player); + } + + public static boolean isSignedBy(ItemStack stack, UUID player) { + Issuer issuer = stack.get(UDataComponentTypes.ISSUER); + return issuer != null && issuer.isSignedBy(player); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java b/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java index 7f3b172f..4364e893 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java +++ b/src/main/java/com/minelittlepony/unicopia/item/component/UDataComponentTypes.java @@ -3,8 +3,10 @@ package com.minelittlepony.unicopia.item.component; import java.util.function.UnaryOperator; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.container.SpellbookState; +import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; import com.minelittlepony.unicopia.entity.mob.ButterflyEntity; import com.mojang.serialization.Codec; @@ -14,10 +16,13 @@ import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; public interface UDataComponentTypes { + ComponentType> STORED_SPELL = register("stored_spell", builder -> builder.codec(SpellType.CODEC).packetCodec(SpellType.PACKET_CODEC)); ComponentType SPELL_TRAITS = register("spell_traits", builder -> builder.codec(SpellTraits.CODEC).packetCodec(SpellTraits.PACKET_CODEC).cache()); ComponentType SPELLBOOK_STATE = register("spellbook_state", builder -> builder.codec(SpellbookState.CODEC).packetCodec(SpellbookState.PACKET_CODEC).cache()); ComponentType GLOWING = register("glowing", builder -> builder.codec(Codec.BOOL).packetCodec(PacketCodecs.BOOL)); ComponentType BUTTERFLY_VARIANT = register("butterfly_variant", builder -> builder.codec(ButterflyEntity.Variant.CODEC).packetCodec(ButterflyEntity.Variant.PACKET_CODEC)); + ComponentType BALLOON_DESIGN = register("balloon_design", builder -> builder.codec(AirBalloonEntity.BalloonDesign.CODEC).packetCodec(AirBalloonEntity.BalloonDesign.PACKET_CODEC)); + ComponentType ISSUER = register("issuer", builder -> builder.codec(Issuer.CODEC).packetCodec(Issuer.PACKET_CODEC).cache()); private static ComponentType register(String name, UnaryOperator> builderOperator) { return Registry.register(Registries.DATA_COMPONENT_TYPE, Unicopia.id(name), builderOperator.apply(ComponentType.builder()).build()); 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 78748e06..d3066d64 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/EnchantmentUtil.java @@ -7,13 +7,17 @@ import com.minelittlepony.unicopia.entity.Living; import net.minecraft.component.type.ItemEnchantmentsComponent; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.item.ItemStack; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; 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"; @@ -48,10 +52,21 @@ public interface EnchantmentUtil { return (int)MathHelper.clamp(baseline + luckAmplifier + dolphinsGraceAmplifier - unluckAmplifier - badOmenAmplifier, -10, 10); } + @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); + } + + @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); + } + static int getEffectAmplifier(LivingEntity entity, RegistryEntry effect) { - if (!entity.hasStatusEffect(effect)) { - return 0; - } - return entity.getStatusEffect(effect).getAmplifier(); + return entity.hasStatusEffect(effect) ? entity.getStatusEffect(effect).getAmplifier() : 0; } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemModels.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemModels.java index 663151b1..f98366bf 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemModels.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemModels.java @@ -15,7 +15,7 @@ abstract class MixinItemModels { index = 1) private ItemStack modifyStack(ItemStack stack) { if (stack.getItem() instanceof ChameleonItem && ((ChameleonItem)stack.getItem()).isFullyDisguised()) { - return ((ChameleonItem)stack.getItem()).getAppearanceStack(stack); + return ChameleonItem.getAppearanceStack(stack); } return stack; } diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java index a264aabe..4ca1fa1f 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java @@ -12,10 +12,14 @@ import com.minelittlepony.unicopia.WeaklyOwned; import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.item.UItems; + +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedDataHandlerRegistry; @@ -28,9 +32,11 @@ import net.minecraft.nbt.NbtElement; import net.minecraft.particle.ItemStackParticleEffect; import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; /** @@ -223,6 +229,17 @@ public class MagicProjectileEntity extends ThrownItemEntity implements WeaklyOwn } } + public void knockback(LivingEntity target, DamageSource source, ItemStack weapon) { + double d = weapon != null && getWorld() instanceof ServerWorld serverWorld ? EnchantmentHelper.modifyKnockback(serverWorld, weapon, target, source, 0) : 0; + if (d > 0) { + double e = Math.max(0, 1 - target.getAttributeValue(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE)); + Vec3d vec3d = this.getVelocity().multiply(1, 0, 1).normalize().multiply(d * 0.6 * e); + if (vec3d.lengthSquared() > 0) { + target.addVelocity(vec3d.x, 0.1, vec3d.z); + } + } + } + protected void forEachDelegates(Consumer consumer, Function predicate) { try { Optional.ofNullable(predicate.apply(getStack().getItem())).ifPresent(consumer);