tweak the card take animation
This commit is contained in:
@@ -48,9 +48,11 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
private static final int CAPTURE_DURATION = 10;
|
||||
private static final int OVERVIEW_SWEEP_DURATION = 18;
|
||||
private static final int CLEAR_WAVE_DURATION = 10;
|
||||
private static final int REWARD_TAKE_DURATION = 14;
|
||||
|
||||
private final NonNullList<ItemStack> boardCards = NonNullList.withSize(SLOT_COUNT, ItemStack.EMPTY);
|
||||
private final NonNullList<ItemStack> rewardCards = NonNullList.withSize(REWARD_SLOT_COUNT, ItemStack.EMPTY);
|
||||
private final List<RewardTakeAnimation> rewardTakeAnimations = new ArrayList<>();
|
||||
private final int[] ownerSlots = new int[SLOT_COUNT];
|
||||
private final int[] slotAges = new int[SLOT_COUNT];
|
||||
private final ArrayDeque<AnimationStep> pendingAnimations = new ArrayDeque<>();
|
||||
@@ -88,6 +90,10 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<RewardTakeAnimation> rewardTakeAnimations() {
|
||||
return List.copyOf(rewardTakeAnimations);
|
||||
}
|
||||
|
||||
public int ownerAt(int slot) {
|
||||
return ownerSlots[slot];
|
||||
}
|
||||
@@ -253,6 +259,15 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
if (taken.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
int visibleIndex = visibleRewardIndex(slot);
|
||||
int rewardCountBeforeTake = rewardCardCount();
|
||||
if (visibleIndex >= 0 && rewardCountBeforeTake > 0) {
|
||||
BoardLocalSpace.SlotCenter center = BoardLocalSpace.rewardCenter(
|
||||
visibleIndex,
|
||||
getBlockState().getValue(DuelTableBlock.FACING),
|
||||
rewardCountBeforeTake);
|
||||
rewardTakeAnimations.add(new RewardTakeAnimation(taken.copyWithCount(1), center.x(), center.z(), 0, REWARD_TAKE_DURATION));
|
||||
}
|
||||
rewardCards.set(slot, ItemStack.EMPTY);
|
||||
refreshRewardInteractions();
|
||||
sync();
|
||||
@@ -263,6 +278,7 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
for (int index = 0; index < rewardCards.size(); index++) {
|
||||
rewardCards.set(index, ItemStack.EMPTY);
|
||||
}
|
||||
rewardTakeAnimations.clear();
|
||||
removeRewardInteractions();
|
||||
}
|
||||
|
||||
@@ -274,6 +290,7 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
rewardCards.set(slot, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
rewardTakeAnimations.clear();
|
||||
removeRewardInteractions();
|
||||
}
|
||||
|
||||
@@ -431,6 +448,21 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
blockEntity.slotAges[slot] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!blockEntity.rewardTakeAnimations.isEmpty()) {
|
||||
boolean changed = false;
|
||||
for (int index = blockEntity.rewardTakeAnimations.size() - 1; index >= 0; index--) {
|
||||
RewardTakeAnimation animation = blockEntity.rewardTakeAnimations.get(index);
|
||||
animation.age++;
|
||||
if (animation.age >= animation.duration) {
|
||||
blockEntity.rewardTakeAnimations.remove(index);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (!level.isClientSide && changed) {
|
||||
blockEntity.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -440,6 +472,7 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
CompoundTag rewardTag = new CompoundTag();
|
||||
ContainerHelper.saveAllItems(rewardTag, rewardCards, registries);
|
||||
tag.put("RewardCards", rewardTag);
|
||||
saveRewardTakeAnimations(tag, registries);
|
||||
tag.putIntArray("OwnerSlots", ownerSlots);
|
||||
tag.putIntArray("SlotAges", slotAges);
|
||||
saveAnimation(tag);
|
||||
@@ -460,6 +493,7 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
if (tag.contains("RewardCards", Tag.TAG_COMPOUND)) {
|
||||
ContainerHelper.loadAllItems(tag.getCompound("RewardCards"), rewardCards, registries);
|
||||
}
|
||||
loadRewardTakeAnimations(tag, registries);
|
||||
loadOwnerData(tag);
|
||||
loadAnimation(tag);
|
||||
loadTableAnimation(tag);
|
||||
@@ -472,6 +506,7 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
CompoundTag rewardTag = new CompoundTag();
|
||||
ContainerHelper.saveAllItems(rewardTag, rewardCards, registries);
|
||||
tag.put("RewardCards", rewardTag);
|
||||
saveRewardTakeAnimations(tag, registries);
|
||||
tag.putIntArray("OwnerSlots", ownerSlots);
|
||||
tag.putIntArray("SlotAges", slotAges);
|
||||
saveAnimation(tag);
|
||||
@@ -499,6 +534,7 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
if (tag.contains("RewardCards", Tag.TAG_COMPOUND)) {
|
||||
ContainerHelper.loadAllItems(tag.getCompound("RewardCards"), rewardCards, registries);
|
||||
}
|
||||
loadRewardTakeAnimations(tag, registries);
|
||||
loadOwnerData(tag);
|
||||
loadAnimation(tag);
|
||||
loadTableAnimation(tag);
|
||||
@@ -531,6 +567,44 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
secondParticipantId = tag.hasUUID("SecondParticipantId") ? tag.getUUID("SecondParticipantId") : null;
|
||||
}
|
||||
|
||||
private void saveRewardTakeAnimations(CompoundTag tag, HolderLookup.Provider registries) {
|
||||
CompoundTag animationsTag = new CompoundTag();
|
||||
for (int index = 0; index < rewardTakeAnimations.size(); index++) {
|
||||
RewardTakeAnimation animation = rewardTakeAnimations.get(index);
|
||||
CompoundTag animationTag = new CompoundTag();
|
||||
animationTag.put("Stack", animation.stack.saveOptional(registries));
|
||||
animationTag.putFloat("LocalX", animation.localX);
|
||||
animationTag.putFloat("LocalZ", animation.localZ);
|
||||
animationTag.putInt("Age", animation.age);
|
||||
animationTag.putInt("Duration", animation.duration);
|
||||
animationsTag.put("Animation" + index, animationTag);
|
||||
}
|
||||
animationsTag.putInt("Count", rewardTakeAnimations.size());
|
||||
tag.put("RewardTakeAnimations", animationsTag);
|
||||
}
|
||||
|
||||
private void loadRewardTakeAnimations(CompoundTag tag, HolderLookup.Provider registries) {
|
||||
rewardTakeAnimations.clear();
|
||||
if (!tag.contains("RewardTakeAnimations", Tag.TAG_COMPOUND)) {
|
||||
return;
|
||||
}
|
||||
CompoundTag animationsTag = tag.getCompound("RewardTakeAnimations");
|
||||
int count = animationsTag.getInt("Count");
|
||||
for (int index = 0; index < count; index++) {
|
||||
CompoundTag animationTag = animationsTag.getCompound("Animation" + index);
|
||||
ItemStack stack = ItemStack.parseOptional(registries, animationTag.getCompound("Stack"));
|
||||
if (stack.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
rewardTakeAnimations.add(new RewardTakeAnimation(
|
||||
stack,
|
||||
animationTag.getFloat("LocalX"),
|
||||
animationTag.getFloat("LocalZ"),
|
||||
animationTag.getInt("Age"),
|
||||
animationTag.getInt("Duration")));
|
||||
}
|
||||
}
|
||||
|
||||
private void saveAnimation(CompoundTag tag) {
|
||||
tag.putString("AnimationType", animationType.name());
|
||||
tag.putIntArray("AnimationSlots", animationSlots);
|
||||
@@ -672,4 +746,54 @@ public class DuelTableBlockEntity extends BlockEntity {
|
||||
|
||||
private record AnimationStep(AnimationType type, int[] slots, int targetOwner) {
|
||||
}
|
||||
|
||||
public static final class RewardTakeAnimation {
|
||||
private final ItemStack stack;
|
||||
private final float localX;
|
||||
private final float localZ;
|
||||
private int age;
|
||||
private final int duration;
|
||||
|
||||
private RewardTakeAnimation(ItemStack stack, float localX, float localZ, int age, int duration) {
|
||||
this.stack = stack;
|
||||
this.localX = localX;
|
||||
this.localZ = localZ;
|
||||
this.age = age;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public ItemStack stack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public float localX() {
|
||||
return localX;
|
||||
}
|
||||
|
||||
public float localZ() {
|
||||
return localZ;
|
||||
}
|
||||
|
||||
public int age() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public int duration() {
|
||||
return duration;
|
||||
}
|
||||
}
|
||||
|
||||
private int visibleRewardIndex(int slot) {
|
||||
int visibleIndex = 0;
|
||||
for (int index = 0; index < rewardCards.size(); index++) {
|
||||
if (rewardCards.get(index).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (index == slot) {
|
||||
return visibleIndex;
|
||||
}
|
||||
visibleIndex++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ public class DuelTableBlockEntityRenderer implements BlockEntityRenderer<DuelTab
|
||||
}
|
||||
|
||||
renderRewardCards(blockEntity, partialTick, poseStack, buffer);
|
||||
renderRewardTakeAnimations(blockEntity, partialTick, poseStack, buffer);
|
||||
renderRewardProxyDebug(blockEntity, poseStack, buffer);
|
||||
}
|
||||
|
||||
@@ -128,6 +129,33 @@ public class DuelTableBlockEntityRenderer implements BlockEntityRenderer<DuelTab
|
||||
return Math.floorMod(blockEntity.getBlockPos().hashCode() * 31 + slot * 17, 97);
|
||||
}
|
||||
|
||||
private static void renderRewardTakeAnimations(DuelTableBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource buffer) {
|
||||
var facing = blockEntity.getBlockState().getValue(DuelTableBlock.FACING);
|
||||
float forwardX = facing.getStepX() * 0.33F;
|
||||
float forwardZ = facing.getStepZ() * 0.33F;
|
||||
for (DuelTableBlockEntity.RewardTakeAnimation animation : blockEntity.rewardTakeAnimations()) {
|
||||
float progress = Math.clamp((animation.age() + partialTick) / animation.duration(), 0.0F, 1.0F);
|
||||
float riseProgress = Math.min(1.0F, progress / 0.45F);
|
||||
float arcProgress = progress <= 0.45F ? 0.0F : (progress - 0.45F) / 0.55F;
|
||||
|
||||
float x = animation.localX() + forwardX * arcProgress;
|
||||
float y = REWARD_CARD_Y
|
||||
+ riseProgress * 0.26F
|
||||
+ (float) Math.sin(arcProgress * Math.PI) * 0.08F
|
||||
- arcProgress * 0.26F;
|
||||
float z = animation.localZ() + forwardZ * arcProgress;
|
||||
float spin = progress * 720.0F;
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(x, y, z);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(facing.toYRot()));
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(spin));
|
||||
poseStack.scale(0.3F, 0.3F, 0.3F);
|
||||
TriadCardItemRenderer.renderCard(animation.stack(), poseStack, buffer, perspectivePalette(blockEntity, DuelTableBlockEntity.OWNER_SECOND));
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderRewardProxyDebug(DuelTableBlockEntity blockEntity, PoseStack poseStack, MultiBufferSource buffer) {
|
||||
if (Minecraft.getInstance().level == null) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user