diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 11e798a6..8dbd7789 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -65,6 +65,7 @@ import net.minecraft.client.world.ClientWorld; import net.minecraft.component.type.DyedColorComponent; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.Fluids; import net.minecraft.item.*; import net.minecraft.particle.ParticleEffect; @@ -168,6 +169,16 @@ public interface URenderers { return (float)lastAngle; } }); + ModelPredicateProviderRegistry.register(UItems.BAITED_FISHING_ROD, Identifier.ofVanilla("cast"), (stack, world, entity, seed) -> { + if (entity == null) { + return 0; + } else { + boolean main = entity.getMainHandStack() == stack; + boolean offhand = entity.getOffHandStack() == stack && !(entity.getMainHandStack().getItem() instanceof FishingRodItem); + + return (main || offhand) && entity instanceof PlayerEntity p && p.fishHook != null ? 1 : 0; + } + }); ColorProviderRegistry.BLOCK.register(URenderers::getTintedBlockColor, TintedBlock.REGISTRY.stream().toArray(Block[]::new)); ColorProviderRegistry.ITEM.register((stack, i) -> getTintedBlockColor(Block.getBlockFromItem(stack.getItem()).getDefaultState(), null, null, i), TintedBlock.REGISTRY.stream().map(Block::asItem).filter(i -> i != Items.AIR).toArray(Item[]::new)); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java index 5d4b9269..3387e93d 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java @@ -151,6 +151,8 @@ public class UModelProvider extends FabricModelProvider { .upload(UItems.GEMSTONE, itemModelGenerator); // fishing rod - ItemModels.register(itemModelGenerator, Models.HANDHELD_ROD, UItems.BAITED_FISHING_ROD); + ModelOverrides.of(Models.HANDHELD_ROD) + .addOverride(ModelIds.getItemSubModelId(Items.FISHING_ROD, "_cast"), "cast", 1) + .upload(UItems.BAITED_FISHING_ROD, itemModelGenerator); } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/FishingRod.java b/src/main/java/com/minelittlepony/unicopia/entity/FishingRod.java new file mode 100644 index 00000000..23faffc4 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/FishingRod.java @@ -0,0 +1,5 @@ +package com.minelittlepony.unicopia.entity; + +public interface FishingRod { + +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java b/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java index 78c15574..57f317e8 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java @@ -1,9 +1,12 @@ package com.minelittlepony.unicopia.item; +import javax.annotation.Nullable; + import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.FishingBobberEntity; import net.minecraft.item.FishingRodItem; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.server.world.ServerWorld; @@ -19,6 +22,8 @@ public class BaitedFishingRodItem extends FishingRodItem { @Override public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + @Nullable + FishingBobberEntity oldFishHook = user.fishHook; TypedActionResult result = super.use(world, user, hand); if (!world.isClient) { if (user.fishHook != null) { @@ -26,14 +31,25 @@ public class BaitedFishingRodItem extends FishingRodItem { ItemStack stack = user.getStackInHand(hand); int lure = (int)((EnchantmentHelper.getFishingTimeReduction((ServerWorld)world, stack, user) + 1) * 20F); int luck = (EnchantmentHelper.getFishingLuckBonus((ServerWorld)world, stack, user) + 1) * 2; - world.spawnEntity(new FishingBobberEntity(user, world, luck, lure)); + FishingBobberEntity bobber = new FishingBobberEntity(user, world, luck, lure); + ((BaitedFishingBobber)bobber).setRodType(this); + world.spawnEntity(bobber); } - if (result.getValue().isOf(this)) { + if (oldFishHook != null + && oldFishHook.getHookedEntity() == null + && oldFishHook.getDataTracker().get(FishingBobberEntity.CAUGHT_FISH) + && result.getValue().isOf(this)) { ItemStack stack = result.getValue().withItem(Items.FISHING_ROD); return TypedActionResult.success(stack, world.isClient()); } } return result; } + + public interface BaitedFishingBobber { + Item getRodType(); + + void setRodType(Item rodType); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinFishingBobberEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinFishingBobberEntity.java new file mode 100644 index 00000000..0ade835b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinFishingBobberEntity.java @@ -0,0 +1,62 @@ +package com.minelittlepony.unicopia.mixin; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.minelittlepony.unicopia.item.BaitedFishingRodItem; +import com.minelittlepony.unicopia.util.serialization.NbtSerialisable; + +import net.minecraft.entity.projectile.FishingBobberEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.registry.Registries; + +@Mixin(FishingBobberEntity.class) +abstract class MixinFishingBobberEntity extends ProjectileEntity implements BaitedFishingRodItem.BaitedFishingBobber { + private MixinFishingBobberEntity() { super(null, null); } + + @Nullable + private Item rodType; + + @Nullable + @Override + public Item getRodType() { + return rodType; + } + + @Override + public void setRodType(Item rodType) { + this.rodType = rodType; + } + + @ModifyExpressionValue(method = "removeIfInvalid", at = { + @At(value = "INVOKE", target = "net/minecraft/entity/player/PlayerEntity.getMainHandStack()Lnet/minecraft/item/ItemStack;"), + @At(value = "INVOKE", target = "net/minecraft/entity/player/PlayerEntity.getOffHandStack()Lnet/minecraft/item/ItemStack;") + }, expect = 2) + private ItemStack replaceFishingRodItem(ItemStack initialStack) { + if (rodType != null) { + return initialStack.isOf(rodType) ? Items.FISHING_ROD.getDefaultStack() : ItemStack.EMPTY; + } + return initialStack; + } + + @Inject(method = "writeCustomDataToNbt", at = @At("HEAD")) + private void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo info) { + nbt.putString("rodType", Registries.ITEM.getId(rodType == null ? Items.FISHING_ROD : rodType).toString()); + } + + @Inject(method = "readCustomDataFromNbt", at = @At("HEAD")) + private void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo info) { + rodType = nbt.contains("rodType", NbtElement.STRING_TYPE) + ? NbtSerialisable.decode(Registries.ITEM.getCodec(), nbt.get("rodType"), getRegistryManager()).orElse(null) + : null; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinFishingBobberEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinFishingBobberEntityRenderer.java new file mode 100644 index 00000000..6517cd2b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinFishingBobberEntityRenderer.java @@ -0,0 +1,28 @@ +package com.minelittlepony.unicopia.mixin.client; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.minelittlepony.unicopia.item.BaitedFishingRodItem; +import net.minecraft.client.render.entity.FishingBobberEntityRenderer; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +@Mixin(FishingBobberEntityRenderer.class) +abstract class MixinFishingBobberEntityRenderer { + @ModifyExpressionValue(method = "getHandPos", at = { + @At(value = "INVOKE", target = "net/minecraft/entity/player/PlayerEntity.getMainHandStack()Lnet/minecraft/item/ItemStack;") + }, expect = 2) + private ItemStack replaceFishingRodItem(ItemStack initialStack, PlayerEntity player, float f, float tickDelta) { + if (player.fishHook instanceof BaitedFishingRodItem.BaitedFishingBobber bobber) { + Item rodType = bobber.getRodType(); + if (rodType != null) { + return initialStack.isOf(rodType) ? Items.FISHING_ROD.getDefaultStack() : initialStack; + } + } + return initialStack; + } +} diff --git a/src/main/resources/unicopia.aw b/src/main/resources/unicopia.aw index d7cc3822..c2eb581c 100644 --- a/src/main/resources/unicopia.aw +++ b/src/main/resources/unicopia.aw @@ -21,3 +21,5 @@ accessible field net/minecraft/datafixer/fix/AttributeIdFix mutable field net/minecraft/datafixer/fix/AttributeIdFix UUID_TO_ID Ljava/util/Map; accessible field net/minecraft/datafixer/fix/AttributeIdFix NAME_TO_ID Ljava/util/Map; mutable field net/minecraft/datafixer/fix/AttributeIdFix NAME_TO_ID Ljava/util/Map; + +accessible field net/minecraft/entity/projectile/FishingBobberEntity CAUGHT_FISH Lnet/minecraft/entity/data/TrackedData; \ No newline at end of file diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 6f636732..3dfd23a1 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -22,6 +22,7 @@ "MixinEnchantment", "MixinEnchantmentHelper", "MixinFallLocation", + "MixinFishingBobberEntity", "MixinEntity", "MixinEntityBucketItem", "MixinEntityView", @@ -94,6 +95,7 @@ "client.MixinClientWorld", "client.MixinClientPlayNetworkHandler", "client.MixinEntityRenderDispatcher", + "client.MixinFishingBobberEntityRenderer", "client.MixinGameRenderer", "client.MixinHeldItemRenderer", "client.MixinInGameHud",