澪伊01
我使用Forge的Capablity自定义了一个Capabiltity和一个CapabilityProvider并进行了注册,将其附加到玩家身上,然后在玩家死亡重生后将重生前的Capability同步到重生后的玩家实体上,但是这个同步操作无法成功,各部分代码如下:

PlayerThrist.java(自己构造的Capability)

public class PlayerThirst {
    private int thirst;
    private final int MIN_THIRST = 0;
    private final int MAX_THIRST = 10;


    public int getThirst() {
        return thirst;
    }

    public void addThirst(int add) {
        this.thirst = Math.min(this.thirst + add, this.MAX_THIRST);
    }

    public void subThirst(int sub) {
        this.thirst = Math.max(this.thirst - sub, this.MIN_THIRST);
    }

    public void copyFrom(PlayerThirst source) {
        this.thirst = source.thirst;
    }

    public void saveData(CompoundTag nbt) {
        nbt.putInt("thirst", this.thirst);
    }

    public void loadData(CompoundTag nbt) {
        this.thirst = nbt.getInt("thirst");
    }


}复制代码


PlayerThirstyProvider.java(自己构造的CapabilityProvider)
public class PlayerThirstProvider implements ICapabilityProvider, INBTSerializable {
    public static Capability PLAYER_THIRST = CapabilityManager.get(new CapabilityToken
    });
    private PlayerThirst thirst = null;
    private final LazyOptional thirstHandler = LazyOptional.of(this::createPlayerThirst);

    private PlayerThirst createPlayerThirst() {
        if (this.thirst == null) {
            this.thirst = new PlayerThirst();
        }
        return this.thirst;
    }


    @Override
    public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) {
        if (cap == PLAYER_THIRST) {
            return thirstHandler.cast();
        }
        return LazyOptional.empty();
    }

    @Override
    public CompoundTag serializeNBT() {
        CompoundTag nbt = new CompoundTag();
        createPlayerThirst().saveData(nbt);
        return nbt;
    }复制代码


ThirstyEvent.java(用于将PlayerThirsty添加到玩家上、同步死亡前的PlayerThirsty到重生后的玩家实体和注册能力)
@Mod.EventBusSubscriber
public class ThirstEvent {
    @SubscribeEvent
    public static void onAttachPlayer(AttachCapabilitiesEvent event) {
        if (event.getObject() instanceof Player player) {
            if (!event.getObject().getCapability(PlayerThirstProvider.PLAYER_THIRST).isPresent()) {
                event.addCapability(new ResourceLocation(Utils.MODID, "properties"), new PlayerThirstProvider());
            }
        }
    }

    @SubscribeEvent
    public static void onPlayerClone(PlayerEvent.Clone event) {
        if (event.isWasDeath()) {
            event.getEntity().sendSystemMessage(Component.literal("You dead!!"));
            event.getEntity().getCapability(PlayerThirstProvider.PLAYER_THIRST).ifPresent(newState -> {
                event.getEntity().sendSystemMessage(Component.literal("You dead!!2"));
                event.getOriginal().getCapability(PlayerThirstProvider.PLAYER_THIRST).ifPresent(oldState -> {
                    event.getEntity().sendSystemMessage(Component.literal("Data copy!"));
                    newState.copyFrom(oldState);
//                    event.getEntity().sendSystemMessage(Component.literal("You dead, but you are cloned!"));
                });
            });
        }复制代码


如果玩家死亡并且同步成功,玩家会在聊天框中收到"You dead!!" 、"You dead!!2" 和 "Data copy!" 三条信息,然而实际上玩家死亡重生后(使用/kill和从高空掉落摔死)只收到了前两条信息,这意味着event.getOriginal().getCapability(PlayerThirstProvider.PLAYER_THIRST).ifPresent(Lambda表达式) 没有执行其中的Lambda表达式,通过阅读源代码我发现如果event.getOriginal().getCapability(PlayerThirstProvider.PLAYER_THIRST).isPresent() 为false就会出现这种情况,我输出了后者发现确实是false,为什么我的代码会导致这种情况?

第一页 上一页 下一页 最后一页