Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PageTurning animation on spellbook [1.19] #1106

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,54 @@

import com.hollingsworth.arsnouveau.api.spell.ISpellCaster;
import com.hollingsworth.arsnouveau.api.util.CasterUtil;
import com.hollingsworth.arsnouveau.common.items.SpellBook;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.network.PacketDistributor;
import software.bernie.geckolib3.network.GeckoLibNetwork;
import software.bernie.geckolib3.util.GeckoLibUtil;

public interface ISpellHotkeyListener {

default void onNextKeyPressed(ItemStack stack, ServerPlayer player) {
ISpellCaster iSpellCaster = CasterUtil.getCaster(stack);
iSpellCaster.setNextSlot();
if (stack.getItem() instanceof SpellBook book && player.level instanceof ServerLevel level) {

final int id = GeckoLibUtil.guaranteeIDForStack(stack, level);
final PacketDistributor.PacketTarget target = PacketDistributor.TRACKING_ENTITY_AND_SELF
.with(() -> player);
GeckoLibNetwork.syncAnimation(target, book, id, 1);

}
}

default void onPreviousKeyPressed(ItemStack stack, ServerPlayer player) {
ISpellCaster iSpellCaster = CasterUtil.getCaster(stack);
iSpellCaster.setPreviousSlot();
if (stack.getItem() instanceof SpellBook book && player.level instanceof ServerLevel level) {

final int id = GeckoLibUtil.guaranteeIDForStack(stack, level);
final PacketDistributor.PacketTarget target = PacketDistributor.TRACKING_ENTITY_AND_SELF
.with(() -> player);
GeckoLibNetwork.syncAnimation(target, book, id, 0);

}
}

default void onQuickCast(ItemStack stack, ServerPlayer player, InteractionHand hand, int slot){
default void onQuickCast(ItemStack stack, ServerPlayer player, InteractionHand hand, int slot) {
ISpellCaster iSpellCaster = CasterUtil.getCaster(stack);
iSpellCaster.castSpell(player.level, player, hand, null, iSpellCaster.getSpell(slot));
}

//TODO: 1.20 Remove this and have onQuickCast return a boolean
@Deprecated(forRemoval = true)
default boolean canQuickCast(){
default boolean canQuickCast() {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ public ResourceLocation getTextureResource(SpellBook object) {

@Override
public ResourceLocation getAnimationResource(SpellBook animatable) {
return new ResourceLocation(ArsNouveau.MODID, "animations/empty.json");
return new ResourceLocation(ArsNouveau.MODID, "animations/spellbook.animations.json");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.util.Color;
import software.bernie.geckolib3.geo.render.built.GeoModel;
Expand All @@ -29,39 +27,40 @@ public SpellBookRenderer() {

@Override
public void renderByItem(ItemStack itemStack, ItemTransforms.TransformType transformType, PoseStack stack, MultiBufferSource bufferIn, int combinedLightIn, int p_239207_6_) {
if (transformType == ItemTransforms.TransformType.GUI) {
stack.pushPose();
MultiBufferSource.BufferSource irendertypebuffer$impl = Minecraft.getInstance().renderBuffers().bufferSource();
Lighting.setupForFlatItems();
render(itemStack.getItem(), stack, bufferIn, 15728880, itemStack, transformType);
irendertypebuffer$impl.endBatch();
RenderSystem.enableDepthTest();
Lighting.setupFor3DItems();
stack.popPose();
} else {
render(itemStack.getItem(), stack, bufferIn, combinedLightIn, itemStack, transformType);
}
if (itemStack.getItem() instanceof SpellBook spellBook)
if (transformType == ItemTransforms.TransformType.GUI) {
stack.pushPose();
MultiBufferSource.BufferSource irendertypebuffer$impl = Minecraft.getInstance().renderBuffers().bufferSource();
Lighting.setupForFlatItems();
render(spellBook, stack, bufferIn, 15728880, itemStack, transformType);
irendertypebuffer$impl.endBatch();
RenderSystem.enableDepthTest();
Lighting.setupFor3DItems();
stack.popPose();
} else {
render(spellBook, stack, bufferIn, combinedLightIn, itemStack, transformType);
}
}

public void render(Item animatable, PoseStack stack, MultiBufferSource bufferIn, int packedLightIn, ItemStack itemStack, ItemTransforms.TransformType transformType) {
public void render(SpellBook animatable, PoseStack stack, MultiBufferSource bufferIn, int packedLightIn, ItemStack itemStack, ItemTransforms.TransformType transformType) {
this.currentItemStack = itemStack;
GeoModel model = modelProvider instanceof TransformAnimatedModel transformAnimatedModel ? modelProvider.getModel(transformAnimatedModel.getModelResource((IAnimatable) animatable, transformType)) : modelProvider.getModel(modelProvider.getModelResource((SpellBook) animatable));
AnimationEvent<?> itemEvent = new AnimationEvent<>((IAnimatable) animatable, 0, 0, Minecraft.getInstance().getFrameTime(), false, Collections.singletonList(itemStack));
modelProvider.setCustomAnimations((SpellBook) animatable, this.getInstanceId((SpellBook) animatable), itemEvent);
GeoModel model = modelProvider instanceof TransformAnimatedModel<SpellBook> transformAnimatedModel ? modelProvider.getModel(transformAnimatedModel.getModelResource(animatable, transformType)) : modelProvider.getModel(modelProvider.getModelResource(animatable));
AnimationEvent<?> itemEvent = new AnimationEvent<>(animatable, 0, 0, Minecraft.getInstance().getFrameTime(), false, Collections.singletonList(itemStack));
modelProvider.setCustomAnimations(animatable, this.getInstanceId(animatable), itemEvent);
stack.pushPose();
stack.translate(0, 0.01f, 0);
stack.translate(0.5, 0.5, 0.5);
RenderSystem.setShaderTexture(0, getTextureLocation((SpellBook) animatable));
Color renderColor = getRenderColor((SpellBook) animatable, 0, stack, bufferIn, null, packedLightIn);
RenderType renderType = getRenderType((SpellBook) animatable, 0, stack, bufferIn, null, packedLightIn, getTextureLocation((SpellBook) animatable));
render(model, (SpellBook) animatable, 0, renderType, stack, bufferIn, null, packedLightIn, OverlayTexture.NO_OVERLAY, renderColor.getRed() / 255f, renderColor.getGreen() / 255f, renderColor.getBlue() / 255f, (float) renderColor.getAlpha() / 255);
RenderSystem.setShaderTexture(0, getTextureLocation(animatable));
Color renderColor = getRenderColor(animatable, 0, stack, bufferIn, null, packedLightIn);
RenderType renderType = getRenderType(animatable, 0, stack, bufferIn, null, packedLightIn, getTextureLocation(animatable));
render(model, animatable, 0, renderType, stack, bufferIn, null, packedLightIn, OverlayTexture.NO_OVERLAY, renderColor.getRed() / 255f, renderColor.getGreen() / 255f, renderColor.getBlue() / 255f, (float) renderColor.getAlpha() / 255);
stack.popPose();
}

/*
* Needed to fetch the current itemstack in the renderer from a mixin
*/
public ItemStack currentItemStack(){
public ItemStack currentItemStack() {
return currentItemStack;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,53 @@
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.extensions.common.IClientItemExtensions;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib3.core.AnimationState;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
import software.bernie.geckolib3.core.builder.ILoopType;
import software.bernie.geckolib3.core.controller.AnimationController;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;
import software.bernie.geckolib3.network.GeckoLibNetwork;
import software.bernie.geckolib3.network.ISyncable;
import software.bernie.geckolib3.util.GeckoLibUtil;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class SpellBook extends ModItem implements IAnimatable, ICasterTool, IDyeable, IRadialProvider {
public class SpellBook extends ModItem implements IAnimatable, ISyncable, ICasterTool, IDyeable, IRadialProvider {

public SpellTier tier;

@Override
public String getSyncKey() {
return ISyncable.super.getSyncKey() + '_' + tier.value;
}

@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return !oldStack.sameItem(newStack);
}

AnimationFactory factory = GeckoLibUtil.createFactory(this);

public SpellBook(SpellTier tier) {
super(new Item.Properties().stacksTo(1).tab(ArsNouveau.itemGroup));
this.tier = tier;
this(new Item.Properties().stacksTo(1).tab(ArsNouveau.itemGroup), tier);
}

public SpellBook(Properties properties, SpellTier tier) {
super(properties);
this.tier = tier;
GeckoLibNetwork.registerSyncable(this);
}

@Override
Expand All @@ -74,7 +91,7 @@ public boolean canBeDepleted() {
@Override
public InteractionResultHolder<ItemStack> use(Level worldIn, Player playerIn, InteractionHand handIn) {
ItemStack stack = playerIn.getItemInHand(handIn);
if(this != ItemsRegistry.CREATIVE_SPELLBOOK.get()) {
if (this != ItemsRegistry.CREATIVE_SPELLBOOK.get()) {
CapabilityRegistry.getMana(playerIn).ifPresent(iMana -> {
if (iMana.getBookTier() < this.tier.value) {
iMana.setBookTier(this.tier.value);
Expand All @@ -97,13 +114,6 @@ public int getUseDuration(ItemStack stack) {
return 72000;
}

/**
* returns the action that specifies what animation to play when the items is being used
*/
public UseAnim getUseAnimation(ItemStack stack) {
return UseAnim.BOW;
}

@Override
public boolean doesSneakBypassUse(ItemStack stack, LevelReader world, BlockPos pos, Player player) {
return true;
Expand All @@ -124,6 +134,18 @@ public SpellTier getTier() {

@Override
public void registerControllers(AnimationData data) {
data.addAnimationController(new AnimationController<>(this, "controller", 0, (a) -> PlayState.CONTINUE));
}

@Override
public void onAnimationSync(int id, int state) {
if (state == 0 || state == 1) {
final AnimationController<?> controller = GeckoLibUtil.getControllerForID(this.factory, id, "controller");
if (controller.getAnimationState() == AnimationState.Stopped) {
controller.markNeedsReload();
controller.setAnimation(new AnimationBuilder().addAnimation(state == 1 ? "flip_page_right" : "flip_page_left", ILoopType.EDefaultLoopTypes.PLAY_ONCE));
}
}
}

@Override
Expand Down Expand Up @@ -164,7 +186,7 @@ public BlockEntityWithoutLevelRenderer getCustomRenderer() {
@Override
public void onOpenBookMenuKeyPressed(ItemStack stack, Player player) {
InteractionHand hand = StackUtil.getBookHand(player);
if(hand == null){
if (hand == null) {
return;
}
Minecraft.getInstance().setScreen(new GuiSpellBook(hand));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void handle(Supplier<NetworkEvent.Context> ctx) {
ServerPlayer sender = ctx.get().getSender();
if (sender == null) return;

ItemStack stack = StackUtil.getHeldSpellbook(ctx.get().getSender());
ItemStack stack = StackUtil.getHeldSpellbook(sender);
if (stack.getItem() instanceof SpellBook) {
stack.setTag(tag);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"format_version": "1.8.0",
"animations": {
"flip_page_right": {
"animation_length": 0.52,
"bones": {
"right_page": {
"rotation": {
"0.0": {
"vector": [
0,
0,
0
]
},
"0.52": {
"vector": [
0,
140,
0
]
}
}
}
}
},
"flip_page_left": {
"animation_length": 0.52,
"bones": {
"left_page": {
"rotation": {
"0.0": [
0,
0,
0
],
"0.52": [
0,
-137.5,
0
]
}
}
}
}
},
"geckolib_format_version": 2
}
Loading