mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Update some enchantment stuff and update more items code
This commit is contained in:
parent
668dd13db7
commit
ab25ab7556
20 changed files with 257 additions and 176 deletions
|
@ -24,9 +24,13 @@ import com.minelittlepony.unicopia.util.RegistryUtils;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
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.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
|
@ -41,6 +45,8 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
|
|
||||||
public static final Registry<SpellType<?>> REGISTRY = RegistryUtils.createSimple(Unicopia.id("spells"));
|
public static final Registry<SpellType<?>> REGISTRY = RegistryUtils.createSimple(Unicopia.id("spells"));
|
||||||
public static final RegistryKey<? extends Registry<SpellType<?>>> REGISTRY_KEY = REGISTRY.getKey();
|
public static final RegistryKey<? extends Registry<SpellType<?>>> REGISTRY_KEY = REGISTRY.getKey();
|
||||||
|
public static final Codec<SpellType<?>> CODEC = REGISTRY.getCodec();
|
||||||
|
public static final PacketCodec<RegistryByteBuf, SpellType<?>> PACKET_CODEC = PacketCodecs.registryValue(REGISTRY_KEY);
|
||||||
|
|
||||||
private static final DynamicCommandExceptionType UNKNOWN_SPELL_TYPE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("spell_type.unknown", id));
|
private static final DynamicCommandExceptionType UNKNOWN_SPELL_TYPE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("spell_type.unknown", id));
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Optional;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.item.WeatherJarItem;
|
import com.minelittlepony.unicopia.item.WeatherJarItem;
|
||||||
|
import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil;
|
||||||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||||
import com.mojang.serialization.MapCodec;
|
import com.mojang.serialization.MapCodec;
|
||||||
|
|
||||||
|
@ -14,14 +15,12 @@ import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.block.TransparentBlock;
|
import net.minecraft.block.TransparentBlock;
|
||||||
import net.minecraft.block.Waterloggable;
|
import net.minecraft.block.Waterloggable;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.enchantment.Enchantments;
|
import net.minecraft.enchantment.Enchantments;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.fluid.FluidState;
|
import net.minecraft.fluid.FluidState;
|
||||||
import net.minecraft.fluid.Fluids;
|
import net.minecraft.fluid.Fluids;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.registry.RegistryKeys;
|
|
||||||
import net.minecraft.state.StateManager;
|
import net.minecraft.state.StateManager;
|
||||||
import net.minecraft.state.property.BooleanProperty;
|
import net.minecraft.state.property.BooleanProperty;
|
||||||
import net.minecraft.state.property.Properties;
|
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) {
|
public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||||
super.afterBreak(world, player, pos, state, blockEntity, tool);
|
super.afterBreak(world, player, pos, state, blockEntity, tool);
|
||||||
// TODO: Enchantment tag
|
// 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) {
|
if (asItem() instanceof WeatherJarItem jar) {
|
||||||
jar.releaseContents(world, pos);
|
jar.releaseContents(world, pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.network.codec.PacketCodec;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
@ -22,7 +23,6 @@ import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.StringIdentifiable;
|
import net.minecraft.util.StringIdentifiable;
|
||||||
import net.minecraft.util.function.ValueLists;
|
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
@ -37,7 +37,6 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.IntFunction;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
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.BasketItem;
|
||||||
import com.minelittlepony.unicopia.item.HotAirBalloonItem;
|
import com.minelittlepony.unicopia.item.HotAirBalloonItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
import com.minelittlepony.unicopia.item.component.UDataComponentTypes;
|
||||||
import com.minelittlepony.unicopia.server.world.WeatherConditions;
|
import com.minelittlepony.unicopia.server.world.WeatherConditions;
|
||||||
|
import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils;
|
||||||
import com.terraformersmc.terraform.boat.api.TerraformBoatType;
|
import com.terraformersmc.terraform.boat.api.TerraformBoatType;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
public class AirBalloonEntity extends MobEntity implements EntityCollisions.ComplexCollidable, MultiBoundingBoxEntity, MagicImmune, EquineContext {
|
public class AirBalloonEntity extends MobEntity implements EntityCollisions.ComplexCollidable, MultiBoundingBoxEntity, MagicImmune, EquineContext {
|
||||||
private static final TrackedData<Boolean> ASCENDING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
private static final TrackedData<Boolean> ASCENDING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
private static final TrackedData<Integer> BOOSTING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
private static final TrackedData<Integer> BOOSTING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||||
|
@ -375,7 +378,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
||||||
if (!player.isSneaky()) {
|
if (!player.isSneaky()) {
|
||||||
getWorld().emitGameEvent(player, GameEvent.EQUIP, getBlockPos());
|
getWorld().emitGameEvent(player, GameEvent.EQUIP, getBlockPos());
|
||||||
}
|
}
|
||||||
setDesign(HotAirBalloonItem.getDesign(getWorld(), stack));
|
setDesign(AirBalloonEntity.BalloonDesign.of(getWorld(), stack));
|
||||||
if (hasBurner() && hasBalloon()) {
|
if (hasBurner() && hasBalloon()) {
|
||||||
UCriteria.CONSTRUCT_BALLOON.trigger(player);
|
UCriteria.CONSTRUCT_BALLOON.trigger(player);
|
||||||
}
|
}
|
||||||
|
@ -792,8 +795,9 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
||||||
STORM,
|
STORM,
|
||||||
TALE;
|
TALE;
|
||||||
|
|
||||||
|
private static final BalloonDesign[] VALUES = values();
|
||||||
public static final EnumCodec<BalloonDesign> CODEC = StringIdentifiable.createCodec(BalloonDesign::values);
|
public static final EnumCodec<BalloonDesign> CODEC = StringIdentifiable.createCodec(BalloonDesign::values);
|
||||||
private static final IntFunction<BalloonDesign> BY_ID = ValueLists.<BalloonDesign>createIdToValueFunction(Enum::ordinal, values(), ValueLists.OutOfBoundsHandling.ZERO);
|
public static final PacketCodec<ByteBuf, BalloonDesign> PACKET_CODEC = PacketCodecUtils.ofEnum(BalloonDesign.class);
|
||||||
|
|
||||||
private final String name = name().toLowerCase(Locale.ROOT);
|
private final String name = name().toLowerCase(Locale.ROOT);
|
||||||
|
|
||||||
|
@ -802,8 +806,16 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
||||||
return name;
|
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) {
|
public static BalloonDesign getType(int type) {
|
||||||
return BY_ID.apply(type);
|
return VALUES[Math.abs(type) % VALUES.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BalloonDesign getType(String name) {
|
public static BalloonDesign getType(String name) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ public interface ChameleonItem {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
default ItemStack getAppearanceStack(ItemStack stack) {
|
static ItemStack getAppearanceStack(ItemStack stack) {
|
||||||
Item appearance = getAppearance(stack);
|
Item appearance = getAppearance(stack);
|
||||||
if (appearance != Items.AIR) {
|
if (appearance != Items.AIR) {
|
||||||
return createAppearanceStack(stack, appearance);
|
return createAppearanceStack(stack, appearance);
|
||||||
|
@ -20,7 +20,7 @@ public interface ChameleonItem {
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
default ItemStack createAppearanceStack(ItemStack stack, Item appearance) {
|
static ItemStack createAppearanceStack(ItemStack stack, Item appearance) {
|
||||||
ItemStack newAppearance = appearance.getDefaultStack();
|
ItemStack newAppearance = appearance.getDefaultStack();
|
||||||
if (stack.hasNbt()) {
|
if (stack.hasNbt()) {
|
||||||
newAppearance.setNbt(stack.getNbt().copy());
|
newAppearance.setNbt(stack.getNbt().copy());
|
||||||
|
@ -30,11 +30,11 @@ public interface ChameleonItem {
|
||||||
return newAppearance;
|
return newAppearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean hasAppearance(ItemStack stack) {
|
static boolean hasAppearance(ItemStack stack) {
|
||||||
return getAppearance(stack) != Items.AIR;
|
return getAppearance(stack) != Items.AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
default Item getAppearance(ItemStack stack) {
|
static Item getAppearance(ItemStack stack) {
|
||||||
if (stack.hasNbt() && stack.getNbt().contains("appearance")) {
|
if (stack.hasNbt() && stack.getNbt().contains("appearance")) {
|
||||||
return Registries.ITEM.get(new Identifier(stack.getNbt().getString("appearance")));
|
return Registries.ITEM.get(new Identifier(stack.getNbt().getString("appearance")));
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public interface ChameleonItem {
|
||||||
return Items.AIR;
|
return Items.AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
default ItemStack setAppearance(ItemStack stack, ItemStack appearance) {
|
static ItemStack setAppearance(ItemStack stack, ItemStack appearance) {
|
||||||
ItemStack result = stack.copy();
|
ItemStack result = stack.copy();
|
||||||
|
|
||||||
if (appearance.hasNbt()) {
|
if (appearance.hasNbt()) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -72,8 +73,8 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art
|
||||||
}
|
}
|
||||||
|
|
||||||
if (world instanceof ServerWorld serverWorld) {
|
if (world instanceof ServerWorld serverWorld) {
|
||||||
|
Consumer<FloatingArtefactEntity> consumer = EntityType.copier(serverWorld, context.getStack(), context.getPlayer());
|
||||||
FloatingArtefactEntity entity = UEntities.FLOATING_ARTEFACT.create(serverWorld, context.getStack().getNbt(), null, blockPos, SpawnReason.SPAWN_EGG, false, true);
|
FloatingArtefactEntity entity = UEntities.FLOATING_ARTEFACT.create(serverWorld, consumer, blockPos, SpawnReason.SPAWN_EGG, false, true);
|
||||||
|
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
return ActionResult.FAIL;
|
return ActionResult.FAIL;
|
||||||
|
|
|
@ -12,13 +12,14 @@ import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
import com.minelittlepony.unicopia.util.InventoryUtil;
|
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.enchantment.Enchantment;
|
import net.minecraft.component.DataComponentTypes;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.InventoryOwner;
|
import net.minecraft.entity.InventoryOwner;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.registry.tag.EnchantmentTags;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CuringJokeItem extends BlockItem {
|
public class CuringJokeItem extends BlockItem {
|
||||||
|
@ -84,15 +85,14 @@ public class CuringJokeItem extends BlockItem {
|
||||||
|
|
||||||
static boolean uncurseItem(LivingEntity user) {
|
static boolean uncurseItem(LivingEntity user) {
|
||||||
return getInventory(user)
|
return getInventory(user)
|
||||||
.filter(s -> EnchantmentHelper.get(s).keySet().stream().anyMatch(Enchantment::isCursed))
|
|
||||||
.findAny()
|
|
||||||
.filter(s -> {
|
.filter(s -> {
|
||||||
var enchantments = EnchantmentHelper.get(s);
|
var enchantments = s.get(DataComponentTypes.ENCHANTMENTS);
|
||||||
return enchantments.keySet().stream().filter(Enchantment::isCursed).findAny().filter(e -> {
|
return enchantments != null && enchantments.getEnchantments().stream().anyMatch(entry -> entry.isIn(EnchantmentTags.CURSE));
|
||||||
enchantments.remove(e);
|
})
|
||||||
EnchantmentHelper.set(enchantments, s);
|
.findAny()
|
||||||
return true;
|
.map(s -> {
|
||||||
}).isPresent();
|
EnchantmentHelper.apply(s, builder -> builder.remove(entry -> entry.isIn(EnchantmentTags.CURSE)));
|
||||||
|
return s;
|
||||||
}).isPresent();
|
}).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
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.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemConvertible;
|
import net.minecraft.item.ItemConvertible;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
|
||||||
public interface EnchantableItem extends ItemConvertible {
|
public interface EnchantableItem extends ItemConvertible {
|
||||||
|
@ -63,7 +63,7 @@ public interface EnchantableItem extends ItemConvertible {
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isEnchanted(ItemStack stack) {
|
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) {
|
static ItemStack enchant(ItemStack stack, SpellType<?> type) {
|
||||||
|
@ -74,21 +74,23 @@ public interface EnchantableItem extends ItemConvertible {
|
||||||
if (type.isEmpty()) {
|
if (type.isEmpty()) {
|
||||||
return unenchant(stack);
|
return unenchant(stack);
|
||||||
}
|
}
|
||||||
stack.getOrCreateNbt().putString("spell", type.getId().toString());
|
stack.set(UDataComponentTypes.STORED_SPELL, type);
|
||||||
return type.getTraits().applyTo(stack);
|
return type.getTraits().applyTo(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ItemStack unenchant(ItemStack stack) {
|
static ItemStack unenchant(ItemStack stack) {
|
||||||
stack.removeSubNbt("spell");
|
stack.remove(UDataComponentTypes.STORED_SPELL);
|
||||||
stack.removeSubNbt("spell_traits");
|
stack.remove(UDataComponentTypes.SPELL_TRAITS);
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Optional<SpellType<?>> getSpellKeyOrEmpty(ItemStack stack) {
|
static Optional<SpellType<?>> 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 <T extends Spell> SpellType<T> getSpellKey(ItemStack stack) {
|
static <T extends Spell> SpellType<T> getSpellKey(ItemStack stack) {
|
||||||
return SpellType.getKey(isEnchanted(stack) ? new Identifier(stack.getNbt().getString("spell")) : SpellType.EMPTY_ID);
|
return (SpellType<T>)stack.getOrDefault(UDataComponentTypes.STORED_SPELL, SpellType.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
||||||
|
@ -226,7 +224,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDischarge(ItemStack stack) {
|
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);
|
EnchantableItem.unenchant(stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ import com.minelittlepony.unicopia.block.FancyBedBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockEntityProvider;
|
import net.minecraft.block.BlockEntityProvider;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
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.BedItem;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
|
||||||
import net.minecraft.nbt.NbtElement;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class FancyBedItem extends BedItem implements Supplier<BlockEntity> {
|
public class FancyBedItem extends BedItem implements Supplier<BlockEntity> {
|
||||||
|
@ -29,12 +29,13 @@ public class FancyBedItem extends BedItem implements Supplier<BlockEntity> {
|
||||||
return renderEntity.get();
|
return renderEntity.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static FancyBedBlock.SheetPattern getPattern(ItemStack stack) {
|
public static FancyBedBlock.SheetPattern getPattern(ItemStack stack) {
|
||||||
@Nullable
|
@Nullable
|
||||||
NbtCompound blockEntityNbt = getBlockEntityNbt(stack);
|
NbtComponent blockEntityNbt = stack.getOrDefault(DataComponentTypes.BLOCK_ENTITY_DATA, NbtComponent.DEFAULT);
|
||||||
if (blockEntityNbt == null || !blockEntityNbt.contains("pattern", NbtElement.STRING_TYPE)) {
|
if (blockEntityNbt == null || !blockEntityNbt.contains("pattern")) {
|
||||||
return FancyBedBlock.SheetPattern.NONE;
|
return FancyBedBlock.SheetPattern.NONE;
|
||||||
}
|
}
|
||||||
return FancyBedBlock.SheetPattern.byId(blockEntityNbt.getString("pattern"));
|
return FancyBedBlock.SheetPattern.byId(blockEntityNbt.getNbt().getString("pattern"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.entity.Living;
|
|
||||||
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
||||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
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.Block;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.enchantment.Enchantments;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.entity.FlyingItemEntity;
|
import net.minecraft.entity.FlyingItemEntity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.attribute.EntityAttributeInstance;
|
import net.minecraft.entity.ProjectileDeflection;
|
||||||
import net.minecraft.entity.attribute.EntityAttributes;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.hit.EntityHitResult;
|
import net.minecraft.util.hit.EntityHitResult;
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.world.WorldEvents;
|
import net.minecraft.world.WorldEvents;
|
||||||
|
|
||||||
public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.HitListener, ChameleonItem {
|
public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.HitListener, ChameleonItem {
|
||||||
|
@ -39,7 +34,7 @@ public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Text getName(ItemStack stack) {
|
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
|
@Override
|
||||||
|
@ -55,71 +50,38 @@ public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack stack = getAppearanceStack(((FlyingItemEntity)projectile).getStack());
|
ItemStack stack = ChameleonItem.getAppearanceStack(((FlyingItemEntity)projectile).getStack());
|
||||||
|
|
||||||
boolean onFire = false;
|
boolean onFire = false;
|
||||||
|
|
||||||
float prevHealth = 0.0F;
|
if (projectile.getWorld() instanceof ServerWorld world) {
|
||||||
int fire = EnchantmentHelper.getLevel(Enchantments.FIRE_ASPECT, stack);
|
DamageSource damageSource = entity.getDamageSources().thrown(projectile, projectile.getOwner());
|
||||||
|
|
||||||
if (entity instanceof LivingEntity) {
|
float damage = EnchantmentHelper.getDamage(world, stack, entity, damageSource, projectile.getThrowDamage());
|
||||||
prevHealth = ((LivingEntity)entity).getHealth();
|
|
||||||
|
|
||||||
if (fire > 0 && !entity.isOnFire()) {
|
if (projectile.getOwner() instanceof LivingEntity owner) {
|
||||||
onFire = true;
|
owner.onAttacking(entity);
|
||||||
entity.setOnFireFor(1);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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 -> {});
|
if (entity instanceof LivingEntity living) {
|
||||||
|
projectile.knockback(living, damageSource, stack);
|
||||||
stack.getAttributeModifiers(EquipmentSlot.MAINHAND).get(EntityAttributes.GENERIC_ATTACK_DAMAGE).forEach(modifier -> {
|
EnchantmentHelper.onTargetDamaged(world, living, damageSource, stack);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
entity.addVelocity(
|
if (onFire) {
|
||||||
-MathHelper.sin(projectile.getYaw() * toRadians) * knockback / 2F, 0.1D,
|
entity.setOnFire(false);
|
||||||
MathHelper.cos(projectile.getYaw() * toRadians) * knockback / 2F
|
}
|
||||||
);
|
projectile.deflect(ProjectileDeflection.SIMPLE, entity, projectile.getOwner(), false);
|
||||||
}
|
projectile.setVelocity(projectile.getVelocity().multiply(0.2));
|
||||||
} else {
|
|
||||||
if (onFire) {
|
|
||||||
entity.setOnFire(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImpact(MagicProjectileEntity projectile) {
|
public void onImpact(MagicProjectileEntity projectile) {
|
||||||
ItemStack stack = getAppearanceStack(projectile.getStack());
|
ItemStack stack = ChameleonItem.getAppearanceStack(projectile.getStack());
|
||||||
|
|
||||||
if (stack.isOf(UItems.BUTTERFLY)) {
|
if (stack.isOf(UItems.BUTTERFLY)) {
|
||||||
ButterflyEntity butterfly = UEntities.BUTTERFLY.create(projectile.getWorld());
|
ButterflyEntity butterfly = UEntities.BUTTERFLY.create(projectile.getWorld());
|
||||||
|
@ -136,6 +98,6 @@ public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack withContents(ItemStack contents) {
|
public ItemStack withContents(ItemStack contents) {
|
||||||
return setAppearance(getDefaultStack(), contents);
|
return ChameleonItem.setAppearance(getDefaultStack(), contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,14 @@ import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
|
import net.minecraft.enchantment.Enchantments;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.HoeItem;
|
import net.minecraft.item.HoeItem;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.ToolMaterials;
|
import net.minecraft.item.ToolMaterials;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.registry.tag.BlockTags;
|
import net.minecraft.registry.tag.BlockTags;
|
||||||
import net.minecraft.registry.tag.ItemTags;
|
import net.minecraft.registry.tag.ItemTags;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
@ -51,11 +54,11 @@ public class ForageableItem extends Item {
|
||||||
world.playSound(player, pos, state.getSoundGroup().getHitSound(), SoundCategory.BLOCKS);
|
world.playSound(player, pos, state.getSoundGroup().getHitSound(), SoundCategory.BLOCKS);
|
||||||
InteractionManager.getInstance().addBlockBreakingParticles(pos, hitResult.getSide());
|
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) {
|
for (ForageableItem item : REGISTRY) {
|
||||||
if ((result = item.onTryForage(world, pos, state, stack, player, miningLevel)).isAccepted()) {
|
if ((result = item.onTryForage(world, pos, state, stack, player, foragingChance)).isAccepted()) {
|
||||||
stack.damage(1, player, p -> p.sendToolBreakStatus(hand));
|
stack.damage(1, player, LivingEntity.getSlotForHand(hand));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,21 +76,39 @@ public class ForageableItem extends Item {
|
||||||
REGISTRY.add(this);
|
REGISTRY.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult onTryForage(World world, BlockPos pos, BlockState state, ItemStack stack, PlayerEntity player, int miningLevel) {
|
public ActionResult onTryForage(World world, BlockPos pos, BlockState state, ItemStack stack, PlayerEntity player, float spawnChance) {
|
||||||
if (state.isOf(targetBlock.get())) {
|
if (!state.isOf(targetBlock.get())) {
|
||||||
int spawnChance = (int)((1F - MathHelper.clamp(miningLevel / (float)ToolMaterials.NETHERITE.getMiningLevel(), 0, 1)) * 32);
|
return ActionResult.PASS;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
|
||||||
import com.minelittlepony.unicopia.entity.AmuletSelectors;
|
import com.minelittlepony.unicopia.entity.AmuletSelectors;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
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.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
@ -23,7 +25,6 @@ import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Item.TooltipContext;
|
|
||||||
import net.minecraft.item.tooltip.TooltipType;
|
import net.minecraft.item.tooltip.TooltipType;
|
||||||
import net.minecraft.stat.Stats;
|
import net.minecraft.stat.Stats;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
@ -47,10 +48,7 @@ public class FriendshipBraceletItem extends WearableItem {
|
||||||
)) {
|
)) {
|
||||||
player.setCurrentHand(hand);
|
player.setCurrentHand(hand);
|
||||||
|
|
||||||
ItemStack result = stack.copy();
|
ItemStack result = Issuer.set(stack.copyWithCount(1), player);
|
||||||
result.setCount(1);
|
|
||||||
result.getOrCreateNbt().putString("issuer", player.getName().getString());
|
|
||||||
result.getOrCreateNbt().putUuid("issuer_id", player.getUuid());
|
|
||||||
|
|
||||||
if (!player.getAbilities().creativeMode) {
|
if (!player.getAbilities().creativeMode) {
|
||||||
stack.decrement(1);
|
stack.decrement(1);
|
||||||
|
@ -75,8 +73,8 @@ public class FriendshipBraceletItem extends WearableItem {
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> lines, TooltipType type) {
|
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> lines, TooltipType type) {
|
||||||
super.appendTooltip(stack, context, lines, type);
|
super.appendTooltip(stack, context, lines, type);
|
||||||
if (isSigned(stack)) {
|
if (Issuer.isSigned(stack)) {
|
||||||
lines.add(Text.translatable("item.unicopia.friendship_bracelet.issuer", getSignatorName(stack)));
|
stack.get(UDataComponentTypes.ISSUER).appendTooltip(context, lines::add, type);
|
||||||
}
|
}
|
||||||
if (GlowableItem.isGlowing(stack)) {
|
if (GlowableItem.isGlowing(stack)) {
|
||||||
lines.add(Text.translatable("item.unicopia.friendship_bracelet.glowing").formatted(Formatting.ITALIC, Formatting.GRAY));
|
lines.add(Text.translatable("item.unicopia.friendship_bracelet.glowing").formatted(Formatting.ITALIC, Formatting.GRAY));
|
||||||
|
@ -85,49 +83,42 @@ public class FriendshipBraceletItem extends WearableItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EquipmentSlot getSlotType(ItemStack stack) {
|
public EquipmentSlot getSlotType(ItemStack stack) {
|
||||||
return isSigned(stack) ? EquipmentSlot.CHEST : super.getSlotType(stack);
|
return Issuer.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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getSignatorName(ItemStack stack) {
|
public static String getSignatorName(ItemStack stack) {
|
||||||
return isSigned(stack) ? stack.getNbt().getString("issuer") : null;
|
return Issuer.getSignatorName(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static UUID getSignatorId(ItemStack stack) {
|
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) {
|
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) {
|
public static boolean isSignedBy(ItemStack stack, PlayerEntity player) {
|
||||||
return stack.getItem() instanceof FriendshipBraceletItem
|
return Issuer.isSignedBy(stack, player);
|
||||||
&& ((FriendshipBraceletItem)stack.getItem()).checkSignature(stack, player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static boolean isSignedBy(ItemStack stack, UUID player) {
|
public static boolean isSignedBy(ItemStack stack, UUID player) {
|
||||||
return stack.getItem() instanceof FriendshipBraceletItem
|
return Issuer.isSignedBy(stack, player);
|
||||||
&& ((FriendshipBraceletItem)stack.getItem()).checkSignature(stack, player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isComrade(Owned<?> caster, Entity entity) {
|
public static boolean isComrade(Owned<?> caster, Entity entity) {
|
||||||
return entity instanceof LivingEntity l && caster.getMasterId()
|
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();
|
.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isComrade(UUID signator, Entity entity) {
|
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<Pony> getPartyMembers(Caster<?> caster, double radius) {
|
public static Stream<Pony> getPartyMembers(Caster<?> caster, double radius) {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 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 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 SPECTRAL_CLOCK = register("spectral_clock", new Item(new Item.Settings()), ItemGroups.TOOLS);
|
||||||
|
|
||||||
Item WHITE_BED_SHEETS = register(CloudBedBlock.SheetPattern.WHITE);
|
Item WHITE_BED_SHEETS = register(CloudBedBlock.SheetPattern.WHITE);
|
||||||
|
|
|
@ -37,7 +37,7 @@ import net.minecraft.world.event.GameEvent;
|
||||||
|
|
||||||
public class ZapAppleItem extends Item implements ChameleonItem, MultiItem {
|
public class ZapAppleItem extends Item implements ChameleonItem, MultiItem {
|
||||||
public ZapAppleItem(Settings settings) {
|
public ZapAppleItem(Settings settings) {
|
||||||
super(settings);
|
super(settings.rarity(Rarity.RARE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,20 +105,18 @@ public class ZapAppleItem extends Item implements ChameleonItem, MultiItem {
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(world -> RegistryUtils.valuesForTag(world, UConventionalTags.Items.APPLES))
|
.flatMap(world -> RegistryUtils.valuesForTag(world, UConventionalTags.Items.APPLES))
|
||||||
.filter(a -> a != this).map(item -> {
|
.filter(a -> a != this).map(item -> {
|
||||||
ItemStack stack = new ItemStack(this);
|
return ChameleonItem.setAppearance(getDefaultStack(), item.getDefaultStack());
|
||||||
stack.getOrCreateNbt().putString("appearance", Registries.ITEM.getId(item).toString());
|
|
||||||
return stack;
|
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Text getName(ItemStack stack) {
|
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
|
@Override
|
||||||
public Rarity getRarity(ItemStack stack) {
|
public Rarity getRarity(ItemStack stack) {
|
||||||
if (hasAppearance(stack)) {
|
if (ChameleonItem.hasAppearance(stack)) {
|
||||||
return Rarity.EPIC;
|
return Rarity.EPIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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<Issuer> 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<ByteBuf, Issuer> 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<Text> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,10 @@ package com.minelittlepony.unicopia.item.component;
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
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.ability.magic.spell.trait.SpellTraits;
|
||||||
import com.minelittlepony.unicopia.container.SpellbookState;
|
import com.minelittlepony.unicopia.container.SpellbookState;
|
||||||
|
import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity;
|
||||||
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
|
||||||
|
@ -14,10 +16,13 @@ import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
|
|
||||||
public interface UDataComponentTypes {
|
public interface UDataComponentTypes {
|
||||||
|
ComponentType<SpellType<?>> STORED_SPELL = register("stored_spell", builder -> builder.codec(SpellType.CODEC).packetCodec(SpellType.PACKET_CODEC));
|
||||||
ComponentType<SpellTraits> SPELL_TRAITS = register("spell_traits", builder -> builder.codec(SpellTraits.CODEC).packetCodec(SpellTraits.PACKET_CODEC).cache());
|
ComponentType<SpellTraits> SPELL_TRAITS = register("spell_traits", builder -> builder.codec(SpellTraits.CODEC).packetCodec(SpellTraits.PACKET_CODEC).cache());
|
||||||
ComponentType<SpellbookState> SPELLBOOK_STATE = register("spellbook_state", builder -> builder.codec(SpellbookState.CODEC).packetCodec(SpellbookState.PACKET_CODEC).cache());
|
ComponentType<SpellbookState> SPELLBOOK_STATE = register("spellbook_state", builder -> builder.codec(SpellbookState.CODEC).packetCodec(SpellbookState.PACKET_CODEC).cache());
|
||||||
ComponentType<Boolean> GLOWING = register("glowing", builder -> builder.codec(Codec.BOOL).packetCodec(PacketCodecs.BOOL));
|
ComponentType<Boolean> GLOWING = register("glowing", builder -> builder.codec(Codec.BOOL).packetCodec(PacketCodecs.BOOL));
|
||||||
ComponentType<ButterflyEntity.Variant> BUTTERFLY_VARIANT = register("butterfly_variant", builder -> builder.codec(ButterflyEntity.Variant.CODEC).packetCodec(ButterflyEntity.Variant.PACKET_CODEC));
|
ComponentType<ButterflyEntity.Variant> BUTTERFLY_VARIANT = register("butterfly_variant", builder -> builder.codec(ButterflyEntity.Variant.CODEC).packetCodec(ButterflyEntity.Variant.PACKET_CODEC));
|
||||||
|
ComponentType<AirBalloonEntity.BalloonDesign> BALLOON_DESIGN = register("balloon_design", builder -> builder.codec(AirBalloonEntity.BalloonDesign.CODEC).packetCodec(AirBalloonEntity.BalloonDesign.PACKET_CODEC));
|
||||||
|
ComponentType<Issuer> ISSUER = register("issuer", builder -> builder.codec(Issuer.CODEC).packetCodec(Issuer.PACKET_CODEC).cache());
|
||||||
|
|
||||||
private static <T> ComponentType<T> register(String name, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
|
private static <T> ComponentType<T> register(String name, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
|
||||||
return Registry.register(Registries.DATA_COMPONENT_TYPE, Unicopia.id(name), builderOperator.apply(ComponentType.builder()).build());
|
return Registry.register(Registries.DATA_COMPONENT_TYPE, Unicopia.id(name), builderOperator.apply(ComponentType.builder()).build());
|
||||||
|
|
|
@ -7,13 +7,17 @@ import com.minelittlepony.unicopia.entity.Living;
|
||||||
import net.minecraft.component.type.ItemEnchantmentsComponent;
|
import net.minecraft.component.type.ItemEnchantmentsComponent;
|
||||||
import net.minecraft.enchantment.Enchantment;
|
import net.minecraft.enchantment.Enchantment;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
|
import net.minecraft.enchantment.Enchantments;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.effect.StatusEffect;
|
import net.minecraft.entity.effect.StatusEffect;
|
||||||
import net.minecraft.entity.effect.StatusEffects;
|
import net.minecraft.entity.effect.StatusEffects;
|
||||||
import net.minecraft.item.ItemStack;
|
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.entry.RegistryEntry;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface EnchantmentUtil {
|
public interface EnchantmentUtil {
|
||||||
String HEART_BOUND_CONSUMED_FLAG = "unicopia:heart_bound_consumed";
|
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);
|
return (int)MathHelper.clamp(baseline + luckAmplifier + dolphinsGraceAmplifier - unluckAmplifier - badOmenAmplifier, -10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
static int getLevel(World world, RegistryKey<Enchantment> 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> 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<StatusEffect> effect) {
|
static int getEffectAmplifier(LivingEntity entity, RegistryEntry<StatusEffect> effect) {
|
||||||
if (!entity.hasStatusEffect(effect)) {
|
return entity.hasStatusEffect(effect) ? entity.getStatusEffect(effect).getAmplifier() : 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return entity.getStatusEffect(effect).getAmplifier();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ abstract class MixinItemModels {
|
||||||
index = 1)
|
index = 1)
|
||||||
private ItemStack modifyStack(ItemStack stack) {
|
private ItemStack modifyStack(ItemStack stack) {
|
||||||
if (stack.getItem() instanceof ChameleonItem && ((ChameleonItem)stack.getItem()).isFullyDisguised()) {
|
if (stack.getItem() instanceof ChameleonItem && ((ChameleonItem)stack.getItem()).isFullyDisguised()) {
|
||||||
return ((ChameleonItem)stack.getItem()).getAppearanceStack(stack);
|
return ChameleonItem.getAppearanceStack(stack);
|
||||||
}
|
}
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,14 @@ import com.minelittlepony.unicopia.WeaklyOwned;
|
||||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
|
||||||
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.FallingBlockEntity;
|
import net.minecraft.entity.FallingBlockEntity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
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.DataTracker;
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||||
|
@ -28,9 +32,11 @@ import net.minecraft.nbt.NbtElement;
|
||||||
import net.minecraft.particle.ItemStackParticleEffect;
|
import net.minecraft.particle.ItemStackParticleEffect;
|
||||||
import net.minecraft.particle.ParticleEffect;
|
import net.minecraft.particle.ParticleEffect;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.hit.EntityHitResult;
|
import net.minecraft.util.hit.EntityHitResult;
|
||||||
import net.minecraft.util.hit.HitResult;
|
import net.minecraft.util.hit.HitResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
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 <T extends ProjectileDelegate> void forEachDelegates(Consumer<T> consumer, Function<Object, T> predicate) {
|
protected <T extends ProjectileDelegate> void forEachDelegates(Consumer<T> consumer, Function<Object, T> predicate) {
|
||||||
try {
|
try {
|
||||||
Optional.ofNullable(predicate.apply(getStack().getItem())).ifPresent(consumer);
|
Optional.ofNullable(predicate.apply(getStack().getItem())).ifPresent(consumer);
|
||||||
|
|
Loading…
Reference in a new issue