version 0.1.9

This commit is contained in:
LostInLinearPast 2026-01-08 04:50:00 +08:00
parent 8ba15348ea
commit deda6a2e75
8 changed files with 80 additions and 10 deletions

View File

@ -12,7 +12,7 @@ mapping_version=2023.09.03-1.20.1
mod_id=sccore mod_id=sccore
mod_name=SnowyCrescentCore mod_name=SnowyCrescentCore
mod_license=GNU AGPL 3.0 mod_license=GNU AGPL 3.0
mod_version=1.20.1-0.1.8 mod_version=1.20.1-0.1.9
mod_group_id=com.linearpast mod_group_id=com.linearpast
mod_authors=LostInLinearPast mod_authors=LostInLinearPast
mod_description=A lib about capability and player animator. mod_description=A lib about capability and player animator.

View File

@ -6,6 +6,7 @@ import com.linearpast.sccore.animation.data.AnimationData;
import com.linearpast.sccore.animation.data.Ride; import com.linearpast.sccore.animation.data.Ride;
import com.linearpast.sccore.animation.register.AnimationEntities; import com.linearpast.sccore.animation.register.AnimationEntities;
import com.linearpast.sccore.animation.service.AnimationService; import com.linearpast.sccore.animation.service.AnimationService;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientGamePacketListener;
@ -103,7 +104,7 @@ public class AnimationRideEntity extends Entity {
} }
@Nullable @Nullable
public static AnimationRideEntity create(ServerPlayer pPlayer, ResourceLocation layer, AnimationData anim, boolean force) { public static AnimationRideEntity create(ServerPlayer pPlayer, ResourceLocation layer, AnimationData anim, boolean force, Vec3 pos) {
if(anim == null) return null; if(anim == null) return null;
if(anim.getRide() == null) return null; if(anim.getRide() == null) return null;
IAnimationCapability data = AnimationDataCapability.getCapability(pPlayer).orElse(null); IAnimationCapability data = AnimationDataCapability.getCapability(pPlayer).orElse(null);
@ -114,7 +115,6 @@ public class AnimationRideEntity extends Entity {
float yRot = anim.getRide().getYRot(); float yRot = anim.getRide().getYRot();
if(xRot == 0 && yRot == 0) seat.setRot(pPlayer.getXRot(), pPlayer.getYRot()); if(xRot == 0 && yRot == 0) seat.setRot(pPlayer.getXRot(), pPlayer.getYRot());
else seat.setRot(yRot, xRot); else seat.setRot(yRot, xRot);
Vec3 pos = pPlayer.position();
pos.add(anim.getRide().getOffset()); pos.add(anim.getRide().getOffset());
seat.setPos(pos.x, pos.y + 0.35f, pos.z); seat.setPos(pos.x, pos.y + 0.35f, pos.z);
pPlayer.level().addFreshEntity(seat); pPlayer.level().addFreshEntity(seat);
@ -122,6 +122,16 @@ public class AnimationRideEntity extends Entity {
return seat; return seat;
} }
@Nullable
public static AnimationRideEntity create(ServerPlayer pPlayer, ResourceLocation layer, AnimationData anim, boolean force) {
return create(pPlayer, layer, anim, force, pPlayer.position());
}
@Nullable
public static AnimationRideEntity create(ServerPlayer pPlayer, ResourceLocation layer, AnimationData anim, boolean force, BlockPos pos) {
return create(pPlayer, layer, anim, force, pos.getCenter());
}
@Override @Override
protected void positionRider(@NotNull Entity pPassenger, @NotNull MoveFunction pCallback) { protected void positionRider(@NotNull Entity pPassenger, @NotNull MoveFunction pCallback) {
super.positionRider(pPassenger, pCallback); super.positionRider(pPassenger, pCallback);

View File

@ -1,6 +1,6 @@
package com.linearpast.sccore.animation.event.client; package com.linearpast.sccore.animation.event.client;
import com.linearpast.sccore.animation.service.AnimationService; import com.linearpast.sccore.animation.AnimationApi;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
@ -19,7 +19,7 @@ public class ClientPlayerEvent {
Player player = event.player; Player player = event.player;
if(player.tickCount % 10 != 0) return; if(player.tickCount % 10 != 0) return;
if (!(player instanceof AbstractClientPlayer clientPlayer)) return; if (!(player instanceof AbstractClientPlayer clientPlayer)) return;
AnimationService.INSTANCE.refreshAnimation(clientPlayer); AnimationApi.getHelper(clientPlayer).refreshAnimation();
} }
} }

View File

@ -8,9 +8,11 @@ import com.linearpast.sccore.core.IModLazyRun;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -51,6 +53,17 @@ public class AnimationHelper {
() -> service.playAnimationWithRide(lazyRun.getClientPlayer(), layer, animation.getKey(), isForce) () -> service.playAnimationWithRide(lazyRun.getClientPlayer(), layer, animation.getKey(), isForce)
); );
} }
public ApiBack playAnimationWithRide(ResourceLocation layer, AnimationData animation, boolean isForce, Vec3 pos) {
IAnimationService<?, ?> service = AnimationApi.getServiceGetterHelper(animation.getKey()).getService();
if(service == null) return ApiBack.FAIL;
return lazyRun.testLoadedAndCall(
() -> service.playAnimationWithRide(lazyRun.getServerPlayer(), layer, animation, isForce, pos),
() -> ApiBack.UNSUPPORTED
);
}
public ApiBack playAnimationWithRide(ResourceLocation layer, AnimationData animation, boolean isForce, BlockPos pos) {
return playAnimationWithRide(layer, animation, isForce, pos.getCenter());
}
public void clearAnimation() { public void clearAnimation() {
for (IAnimationService<?, ?> service : AnimationApi.getServiceGetterHelper().getAllServices()) { for (IAnimationService<?, ?> service : AnimationApi.getServiceGetterHelper().getAllServices()) {

View File

@ -0,0 +1,30 @@
package com.linearpast.sccore.animation.network.toserver;
import com.linearpast.sccore.animation.AnimationApi;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
public record StopAnimationPacket(ResourceLocation layer) {
public StopAnimationPacket(FriendlyByteBuf buf) {
this(buf.readResourceLocation());
}
public void encode(FriendlyByteBuf buf) {
buf.writeResourceLocation(layer);
}
public void handle(Supplier<NetworkEvent.Context> supplier) {
NetworkEvent.Context context = supplier.get();
context.enqueueWork(() -> {
context.setPacketHandled(true);
ServerPlayer sender = context.getSender();
if(sender == null) return;
AnimationApi.getHelper(sender).removeAnimation(layer);
});
}
}

View File

@ -57,6 +57,11 @@ public class AnimationChannels {
.encoder(RequestAnimationPacket::encode) .encoder(RequestAnimationPacket::encode)
.consumerMainThread(RequestAnimationPacket::handle) .consumerMainThread(RequestAnimationPacket::handle)
.add(); .add();
ModChannel.INSTANCE.messageBuilder(StopAnimationPacket.class, cid(), NetworkDirection.PLAY_TO_SERVER)
.decoder(StopAnimationPacket::new)
.encoder(StopAnimationPacket::encode)
.consumerMainThread(StopAnimationPacket::handle)
.add();
} }
private static int cid() { private static int cid() {

View File

@ -21,12 +21,15 @@ import com.linearpast.sccore.core.ModCompatRun;
import com.linearpast.sccore.core.configs.ModConfigs; import com.linearpast.sccore.core.configs.ModConfigs;
import dev.kosmx.playerAnim.core.data.KeyframeAnimation; import dev.kosmx.playerAnim.core.data.KeyframeAnimation;
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry; import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
@ -251,6 +254,10 @@ public interface IAnimationService<D extends AnimationData, C extends ICapabilit
default ApiBack removeAnimation(@Nullable AbstractClientPlayer player, ResourceLocation layer) { default ApiBack removeAnimation(@Nullable AbstractClientPlayer player, ResourceLocation layer) {
return ANIMATION_RUNNER.testLoadedAndCall(() -> { return ANIMATION_RUNNER.testLoadedAndCall(() -> {
AnimationUtils.removeAnimation(player, layer); AnimationUtils.removeAnimation(player, layer);
LocalPlayer self = Minecraft.getInstance().player;
if(self != null && player != null && Objects.equals(self.getUUID(), player.getUUID())) {
ModChannel.INSTANCE.sendToServer(new StopAnimationPacket(layer));
}
return ApiBack.SUCCESS; return ApiBack.SUCCESS;
}); });
} }
@ -280,7 +287,7 @@ public interface IAnimationService<D extends AnimationData, C extends ICapabilit
return ApiBack.SUCCESS; return ApiBack.SUCCESS;
}); });
} }
default ApiBack playAnimationWithRide(@NotNull ServerPlayer player, ResourceLocation layer, AnimationData animation, boolean force) { default ApiBack playAnimationWithRide(@NotNull ServerPlayer player, ResourceLocation layer, AnimationData animation, boolean force, Vec3 pos) {
return ANIMATION_RUNNER.testLoadedAndCall(() -> { return ANIMATION_RUNNER.testLoadedAndCall(() -> {
ResourceLocation key = animation.getKey(); ResourceLocation key = animation.getKey();
if(!isAnimationLayerPresent(layer) || !isAnimationPresent(key)) if(!isAnimationLayerPresent(layer) || !isAnimationPresent(key))
@ -292,10 +299,13 @@ public interface IAnimationService<D extends AnimationData, C extends ICapabilit
boolean flag = player.getVehicle() != null; boolean flag = player.getVehicle() != null;
if(flag && force) player.stopRiding(); if(flag && force) player.stopRiding();
else if(flag) return ApiBack.UNSUPPORTED; else if(flag) return ApiBack.UNSUPPORTED;
boolean result = AnimationRideEntity.create(player, layer, animation, force) != null; boolean result = AnimationRideEntity.create(player, layer, animation, force, pos) != null;
return result ? ApiBack.SUCCESS : ApiBack.FAIL; return result ? ApiBack.SUCCESS : ApiBack.FAIL;
}); });
}; }
default ApiBack playAnimationWithRide(@NotNull ServerPlayer player, ResourceLocation layer, AnimationData animation, boolean force) {
return playAnimationWithRide(player, layer, animation, force, player.position());
}
/** /**
* <pre> * <pre>

View File

@ -81,16 +81,18 @@ public class AnimationUtils {
Set<ResourceLocation> resourceLocations = new HashSet<>(); Set<ResourceLocation> resourceLocations = new HashSet<>();
if(layer == null) resourceLocations.addAll(AnimationRegistry.getLayers().keySet()); if(layer == null) resourceLocations.addAll(AnimationRegistry.getLayers().keySet());
else resourceLocations.add(layer); else resourceLocations.add(layer);
boolean isNoneAnimation = true;
for (ResourceLocation location : resourceLocations) { for (ResourceLocation location : resourceLocations) {
ModifierLayer<IAnimation> animationModifierLayer = (ModifierLayer<IAnimation>) PlayerAnimationAccess ModifierLayer<IAnimation> animationModifierLayer = (ModifierLayer<IAnimation>) PlayerAnimationAccess
.getPlayerAssociatedData(player).get(location); .getPlayerAssociatedData(player).get(location);
if(animationModifierLayer == null) continue; if(animationModifierLayer == null) continue;
KeyframeAnimationPlayer animation = (KeyframeAnimationPlayer) animationModifierLayer.getAnimation(); KeyframeAnimationPlayer animation = (KeyframeAnimationPlayer) animationModifierLayer.getAnimation();
if(animation == null) return false; if(animation == null) continue;
int currentTick = animation.getCurrentTick(); int currentTick = animation.getCurrentTick();
int stopTick = animation.getStopTick(); int stopTick = animation.getStopTick();
return currentTick > stopTick; if(currentTick < stopTick) isNoneAnimation = false;
} }
return isNoneAnimation;
} catch (Exception ignored) {} } catch (Exception ignored) {}
return true; return true;
}); });