fix something bug

and add "void attachInit(T entity)" in ICapabilitySync
version 0.0.2
This commit is contained in:
LostInLinearPast 2025-10-18 17:43:22 +08:00
parent d496ad72c2
commit d5756d6e09
17 changed files with 115 additions and 60 deletions

View File

@ -12,7 +12,7 @@ mapping_version=2023.09.03-1.20.1
mod_id=sccore
mod_name=SnowyCrescentCore
mod_license=GNU AGPL 3.0
mod_version=1.20.1-0.0.1
mod_version=1.20.1-0.0.2
mod_group_id=com.linearpast
mod_authors=LostInLinearPast
mod_description=A lib.

View File

@ -35,7 +35,7 @@ public class CapabilityUtils {
* @param handler 网络包的handle
*/
public static <T extends ICapabilityPacket<?>> void registerPlayerCapabilityWithNetwork(
ResourceLocation key, PlayerCapabilityRegistry.CapabilityRecord<? extends ICapabilitySync> capabilityRecord,
ResourceLocation key, PlayerCapabilityRegistry.CapabilityRecord<? extends ICapabilitySync<Player>> capabilityRecord,
CapabilityChannel channelRegister,
int cid,
Class<T> clazz,
@ -59,7 +59,7 @@ public class CapabilityUtils {
* @param handler 网络包的handle
*/
public static <T extends ICapabilityPacket<?>> void registerEntityCapabilityWithNetwork(
ResourceLocation key, EntityCapabilityRegistry.CapabilityRecord<? extends ICapabilitySync> capabilityRecord,
ResourceLocation key, EntityCapabilityRegistry.CapabilityRecord<? extends ICapabilitySync<? extends Entity>> capabilityRecord,
CapabilityChannel channelRegister,
int cid,
Class<T> clazz,
@ -77,7 +77,7 @@ public class CapabilityUtils {
* @param key capability的唯一name
* @param capabilityRecord 使用record存储了应该注册的capability的各项数据参阅{@link PlayerCapabilityRegistry.CapabilityRecord}
*/
public static <T extends ICapabilitySync> void registerPlayerCapability(ResourceLocation key, PlayerCapabilityRegistry.CapabilityRecord<T> capabilityRecord){
public static <T extends ICapabilitySync<Player>> void registerPlayerCapability(ResourceLocation key, PlayerCapabilityRegistry.CapabilityRecord<T> capabilityRecord){
PlayerCapabilityRegistry.registerCapability(key, capabilityRecord);
}
@ -87,7 +87,7 @@ public class CapabilityUtils {
* @param key capability的唯一name
* @param capabilityRecord 使用record存储了应该注册的capability的各项数据参阅{@link PlayerCapabilityRegistry.CapabilityRecord}
*/
public static <T extends ICapabilitySync> void registerEntityCapability(ResourceLocation key, EntityCapabilityRegistry.CapabilityRecord<T> capabilityRecord){
public static <T extends ICapabilitySync<Entity>> void registerEntityCapability(ResourceLocation key, EntityCapabilityRegistry.CapabilityRecord<T> capabilityRecord){
EntityCapabilityRegistry.registerCapability(key, capabilityRecord);
}
@ -119,48 +119,72 @@ public class CapabilityUtils {
}
/**
* 请通过该方法获取玩家的capability
* @param player 目标玩家
* @param key capability key
* @param clazz 应返回的capability类型
* 请通过该方法获取capability
* @param entity 目标实体类型 {@code <E extends Entity>}
* @param key capability的唯一名
* @param clazz 应返回的capability类型若为null则会返回 {@code ICapabilitySync<E>}
* @return 返回对应的capability
*/
@SuppressWarnings("unchecked")
@Nullable
public static <T extends ICapabilitySync> T getPlayerCapability(Player player, ResourceLocation key, Class<T> clazz) {
if(player == null) return null;
ICapabilitySync capabilitySync = player.getCapability(
PlayerCapabilityRegistry.getCapabilityMap().get(key).capability()
).resolve().orElse(null);
if(capabilitySync == null) return null;
public static <E extends Entity, T extends ICapabilitySync<E>> T getEntityCapability(E entity, ResourceLocation key, @Nullable Class<T> clazz) {
try {
ICapabilitySync<?> capabilitySync = entity.getCapability(
EntityCapabilityRegistry.getCapabilityMap().get(key).capability()
).resolve().orElse(null);
if(clazz == null) return (T) capabilitySync;
if(clazz.isInstance(capabilitySync))
return clazz.cast(capabilitySync);
else return null;
}catch(ClassCastException e){
}catch(Exception e){
return null;
}
}
/**
* 请通过该方法获取实体的capability
* @param entity 目标实体
* @param key capability key
* @param clazz 应返回的capability类型
* 请通过该方法获取capability
* @param entity 目标实体类型 {@code <E extends Entity>}
* @param key capability的唯一名
* @param clazz 应返回的capability类型若为null则会返回 {@code ICapabilitySync<E>}
* @return 返回对应的capability
*/
@SuppressWarnings("unchecked")
@Nullable
public static <T extends ICapabilitySync> T getEntityCapability(Entity entity, ResourceLocation key, Class<T> clazz) {
if(entity == null) return null;
ICapabilitySync capabilitySync = entity.getCapability(
EntityCapabilityRegistry.getCapabilityMap().get(key).capability()
).resolve().orElse(null);
if(capabilitySync == null) return null;
public static <E extends Player, T extends ICapabilitySync<E>> T getPlayerCapability(E entity, ResourceLocation key, @Nullable Class<T> clazz) {
try {
ICapabilitySync<?> capabilitySync = entity.getCapability(
PlayerCapabilityRegistry.getCapabilityMap().get(key).capability()
).resolve().orElse(null);
if(clazz == null) return (T) capabilitySync;
if(clazz.isInstance(capabilitySync))
return clazz.cast(capabilitySync);
else return null;
}catch(ClassCastException e){
}catch(Exception e){
return null;
}
}
/**
* 获取一个未转换类型的Cap
* @param entity 目标
* @param key cap的唯一名
* @return 未转换类型的cap
*/
@Nullable
public static ICapabilitySync<?> getCapability(Entity entity, ResourceLocation key) {
if(entity == null) return null;
try {
if(entity instanceof Player) {
return entity.getCapability(
PlayerCapabilityRegistry.getCapabilityMap().get(key).capability()
).resolve().orElse(null);
}
return entity.getCapability(
EntityCapabilityRegistry.getCapabilityMap().get(key).capability()
).resolve().orElse(null);
}catch(Exception e){
return null;
}
}
}

View File

@ -7,7 +7,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.common.util.INBTSerializable;
public interface ICapabilitySync extends INBTSerializable<CompoundTag> {
public interface ICapabilitySync<T extends Entity> extends INBTSerializable<CompoundTag> {
void setDirty(boolean dirty);
boolean isDirty();
@ -19,7 +19,7 @@ public interface ICapabilitySync extends INBTSerializable<CompoundTag> {
* @param oldData 旧数据
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
*/
default void copyFrom(ICapabilitySync oldData, boolean listenDone) {
default void copyFrom(ICapabilitySync<?> oldData, boolean listenDone) {
this.setDirty(oldData.isDirty());
if(listenDone) onCopyDone();
}
@ -53,6 +53,12 @@ public interface ICapabilitySync extends INBTSerializable<CompoundTag> {
* 一般情况下你应该extends SimpleCapabilityPacket然后重写该方法返回你的子类
* @return 网络包类SimpleCapabilityPacket
*/
SimpleCapabilityPacket<? extends Entity> getDefaultPacket();
SimpleCapabilityPacket<T> getDefaultPacket();
/**
* 当玩家登录 / 实体加入世界时的cao初始化时会调用 <br>
* 必须实现但可为空方法
* @param entity 目标
*/
void attachInit(T entity);
}

View File

@ -45,7 +45,7 @@ public class EntityCapabilityHandler {
EntityCapabilityRegistry.getCapabilityMap().forEach((key, record) -> {
if(record.target().isInstance(entity)) {
try {
ICapabilitySync capabilitySync = (ICapabilitySync) record.aClass().getDeclaredConstructor().newInstance();
ICapabilitySync<?> capabilitySync = (ICapabilitySync<?>) record.aClass().getDeclaredConstructor().newInstance();
event.addCapability(key, new EntityCapabilityProvider<>(key, capabilitySync));
} catch (Exception e) {
log.error("Failed to instantiate capability sync class {}. Your capability register is wrong.", record.aClass(), e);

View File

@ -4,6 +4,7 @@ import com.linearpast.sccore.capability.data.ICapabilitySync;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.common.capabilities.AutoRegisterCapability;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
@ -16,7 +17,7 @@ import org.jetbrains.annotations.Nullable;
* @param <C> 继承 {@link ICapabilitySync}
*/
@AutoRegisterCapability
public class EntityCapabilityProvider<C extends ICapabilitySync> implements ICapabilitySerializable<CompoundTag> {
public class EntityCapabilityProvider<C extends ICapabilitySync<? extends Entity>> implements ICapabilitySerializable<CompoundTag> {
private final C instance;
private final ResourceLocation resourceLocation;
public EntityCapabilityProvider(ResourceLocation resourceLocation, C instance) {

View File

@ -46,7 +46,7 @@ public class EntityCapabilityRegistry {
* @param interfaceClass instance类对应的实例对应的接口类比如ICapabilitySync.class
* @param target capability附加的目标类型
*/
public record CapabilityRecord<T extends ICapabilitySync>(Class<?> aClass, Capability<T> capability, Class<T> interfaceClass, Class<? extends Entity> target) {
public record CapabilityRecord<T extends ICapabilitySync<? extends Entity>>(Class<?> aClass, Capability<T> capability, Class<T> interfaceClass, Class<? extends Entity> target) {
}
}

View File

@ -20,7 +20,7 @@ public class EntityCapabilityRemainder {
public static void onEntityBeTracked(PlayerEvent.StartTracking event) {
if (event.getEntity() instanceof ServerPlayer attacker) {
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getEntityCapability(event.getTarget(), key, ICapabilitySync.class);
ICapabilitySync<?> data = CapabilityUtils.getCapability(event.getTarget(), key);
if(data == null) return;
data.sendToClient(attacker);
});
@ -38,7 +38,7 @@ public class EntityCapabilityRemainder {
if(!entity.level().isClientSide){
if (entity.tickCount % 20 == 0) {
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getEntityCapability(entity, key, ICapabilitySync.class);
ICapabilitySync<?> data = CapabilityUtils.getCapability(entity, key);
if(data == null) return;
if(data.isDirty()) {
data.setDirty(false);
@ -57,11 +57,12 @@ public class EntityCapabilityRemainder {
Entity entity = event.getEntity();
if(entity.level().isClientSide) return;
EntityCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getEntityCapability(entity, key, ICapabilitySync.class);
ICapabilitySync<Entity> data = CapabilityUtils.getEntityCapability(entity, key, null);
if(data == null) return;
if(data instanceof SimpleEntityCapabilitySync capabilitySync){
if(data instanceof SimpleEntityCapabilitySync<?> capabilitySync){
capabilitySync.setId(entity.getId());
}
data.attachInit(entity);
data.setDirty(false);
data.sendToClient();
});

View File

@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.data.entity;
import com.linearpast.sccore.capability.data.ICapabilitySync;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
/**
* 实现时建议手动添加<br>
@ -21,7 +22,7 @@ import net.minecraft.nbt.CompoundTag;
* </pre>
*
*/
public abstract class SimpleEntityCapabilitySync implements ICapabilitySync {
public abstract class SimpleEntityCapabilitySync<T extends Entity> implements ICapabilitySync<T> {
public static final String Id = "Id";
private boolean dirty;
@ -57,8 +58,8 @@ public abstract class SimpleEntityCapabilitySync implements ICapabilitySync {
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
*/
@Override
public void copyFrom(ICapabilitySync oldData, boolean listenDone) {
SimpleEntityCapabilitySync data = (SimpleEntityCapabilitySync) oldData;
public void copyFrom(ICapabilitySync<?> oldData, boolean listenDone) {
SimpleEntityCapabilitySync<?> data = (SimpleEntityCapabilitySync<?>) oldData;
this.setId(data.getId());
copyFrom(data);
ICapabilitySync.super.copyFrom(oldData, listenDone);
@ -68,7 +69,7 @@ public abstract class SimpleEntityCapabilitySync implements ICapabilitySync {
* 触发数据复制时会执行的方法
* @param oldData 从这个数据中复制到当前实例
*/
public abstract void copyFrom(ICapabilitySync oldData);
public abstract void copyFrom(ICapabilitySync<?> oldData);
/**
* 序列化为tag <br>

View File

@ -46,7 +46,7 @@ public class PlayerCapabilityHandler {
if(event.getObject() instanceof Player) {
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, record) -> {
try {
ICapabilitySync capabilitySync = (ICapabilitySync) record.aClass().getDeclaredConstructor().newInstance();
ICapabilitySync<?> capabilitySync = (ICapabilitySync<?>) record.aClass().getDeclaredConstructor().newInstance();
event.addCapability(key, new PlayerCapabilityProvider<>(key, capabilitySync));
} catch (Exception e) {
log.error("Failed to instantiate capability sync class {}. Your capability register is wrong.", record.aClass(), e);

View File

@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@AutoRegisterCapability
public class PlayerCapabilityProvider<C extends ICapabilitySync> implements ICapabilitySerializable<CompoundTag> {
public class PlayerCapabilityProvider<C extends ICapabilitySync<?>> implements ICapabilitySerializable<CompoundTag> {
private final C instance;
private final ResourceLocation resourceLocation;
public PlayerCapabilityProvider(ResourceLocation resourceLocation, C instance) {

View File

@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.data.player;
import com.linearpast.sccore.capability.data.ICapabilitySync;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.capabilities.Capability;
import java.util.HashMap;
@ -40,5 +41,5 @@ public class PlayerCapabilityRegistry {
* @param capability 一般情况下不需要初始化它默认CapabilityManager.get(new CapabilityToken<>(){})
* @param interfaceClass instance实例对应的接口类比如ICapabilitySync.class
*/
public record CapabilityRecord<T extends ICapabilitySync>(Class<?> aClass, Capability<T> capability, Class<T> interfaceClass) { }
public record CapabilityRecord<T extends ICapabilitySync<? extends Player>>(Class<?> aClass, Capability<T> capability, Class<T> interfaceClass) { }
}

View File

@ -25,8 +25,8 @@ public class PlayerCapabilityRemainder {
Player original = event.getOriginal();
original.reviveCaps();
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync originData = CapabilityUtils.getPlayerCapability(original, key, ICapabilitySync.class);
ICapabilitySync newData = CapabilityUtils.getPlayerCapability(newPlayer, key, ICapabilitySync.class);
ICapabilitySync<?> originData = CapabilityUtils.getCapability(original, key);
ICapabilitySync<?> newData = CapabilityUtils.getCapability(newPlayer, key);
if(originData != null && newData != null) {
newData.copyFrom(originData, true);
newData.sendToClient();
@ -43,7 +43,7 @@ public class PlayerCapabilityRemainder {
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
if(event.getEntity() instanceof ServerPlayer newPlayer){
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getPlayerCapability(newPlayer, key, ICapabilitySync.class);
ICapabilitySync<?> data = CapabilityUtils.getCapability(newPlayer, key);
if(data == null) return;
data.sendToClient(newPlayer);
});
@ -59,7 +59,7 @@ public class PlayerCapabilityRemainder {
public static void onEntityBeTracked(PlayerEvent.StartTracking event) {
if (event.getTarget() instanceof Player target && event.getEntity() instanceof ServerPlayer attacker) {
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getPlayerCapability(target, key, ICapabilitySync.class);
ICapabilitySync<?> data = CapabilityUtils.getCapability(target, key);
if(data == null) return;
data.sendToClient(attacker);
});
@ -74,7 +74,7 @@ public class PlayerCapabilityRemainder {
public static void capabilitySync(TickEvent.PlayerTickEvent event) {
if(!event.player.level().isClientSide){
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getPlayerCapability(event.player, key, ICapabilitySync.class);
ICapabilitySync<?> data = CapabilityUtils.getCapability(event.player, key);
if(data == null) return;
if(data.isDirty()) {
data.setDirty(false);
@ -94,11 +94,12 @@ public class PlayerCapabilityRemainder {
Player player = event.getEntity();
if(!(player instanceof ServerPlayer serverPlayer)) return;
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getPlayerCapability(player, key, ICapabilitySync.class);
ICapabilitySync<Player> data = CapabilityUtils.getPlayerCapability(player, key, null);
if(data == null) return;
if(data instanceof SimplePlayerCapabilitySync capabilitySync) {
capabilitySync.setOwnerUUID(serverPlayer.getUUID());
}
data.attachInit(serverPlayer);
data.setDirty(false);
data.sendToClient();
});
@ -106,7 +107,7 @@ public class PlayerCapabilityRemainder {
serverPlayers -> serverPlayers.forEach(p -> {
if(!p.getUUID().equals(serverPlayer.getUUID())) {
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
ICapabilitySync data = CapabilityUtils.getPlayerCapability(player, key, ICapabilitySync.class);
ICapabilitySync<?> data = CapabilityUtils.getCapability(player, key);
if(data == null) return;
data.sendToClient(serverPlayer);
});

View File

@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.data.player;
import com.linearpast.sccore.capability.data.ICapabilitySync;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import java.util.UUID;
@ -23,7 +24,7 @@ import java.util.UUID;
* </pre>
*
*/
public abstract class SimplePlayerCapabilitySync implements ICapabilitySync {
public abstract class SimplePlayerCapabilitySync implements ICapabilitySync<Player> {
public static final String OwnerUUID = "OwnerUUID";
private boolean dirty;
@ -55,9 +56,10 @@ public abstract class SimplePlayerCapabilitySync implements ICapabilitySync {
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
*/
@Override
public void copyFrom(ICapabilitySync oldData, boolean listenDone) {
public void copyFrom(ICapabilitySync<?> oldData, boolean listenDone) {
SimplePlayerCapabilitySync data = (SimplePlayerCapabilitySync) oldData;
this.setOwnerUUID(data.getOwnerUUID());
copyFrom(data);
ICapabilitySync.super.copyFrom(oldData, listenDone);
}
@ -65,7 +67,7 @@ public abstract class SimplePlayerCapabilitySync implements ICapabilitySync {
* 触发数据复制时会执行的方法
* @param oldData 从这个数据中复制到当前实例
*/
public abstract void copyFrom(ICapabilitySync oldData);
public abstract void copyFrom(ICapabilitySync<?> oldData);
/**
* 序列化为tag <br>

View File

@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.network;
import com.linearpast.sccore.capability.data.ICapabilitySync;
import com.linearpast.sccore.capability.data.entity.SimpleEntityCapabilitySync;
import com.linearpast.sccore.capability.data.player.SimplePlayerCapabilitySync;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.nbt.CompoundTag;
@ -33,7 +34,14 @@ public abstract class SimpleCapabilityPacket<T extends Entity> implements ICapab
ClientLevel level = instance.level;
if (level == null) return;
CompoundTag nbt = getData();
Entity entity = level.getEntity(nbt.getInt(SimpleEntityCapabilitySync.Id));
Entity entity = null;
if(nbt.contains(SimpleEntityCapabilitySync.Id)){
entity = level.getEntity(nbt.getInt(SimpleEntityCapabilitySync.Id));
}
if(nbt.contains(SimplePlayerCapabilitySync.OwnerUUID)){
entity = level.getPlayerByUUID(nbt.getUUID(SimplePlayerCapabilitySync.OwnerUUID));
}
if(entity == null) return;
try {
ICapabilitySync data = getCapability((T) entity);
syncData(nbt, data);

View File

@ -14,7 +14,8 @@ import net.minecraftforge.eventbus.api.IEventBus;
public class ModCaps {
/**
* 注册capability的示例<br>
* 注册实体capability的示例<br>
* 请参阅 {@link CapabilityUtils}
*/
public static void register(){
//如果你想将网络包注册到你自己的mod中createChannel(INSTANCE)
@ -23,6 +24,7 @@ public class ModCaps {
//不可与其他网络包重复的任意整数
int cid = Channel.getCid();
//注册实体cap和它的网络包
//若注册玩家的请用registerPlayerCapabilityWithNetwork
CapabilityUtils.registerEntityCapabilityWithNetwork(
//一个resourceLocation任意命名不重复即可
SheepDataCapability.key,

View File

@ -1,12 +1,13 @@
package com.linearpast.sccore.example.cap;
import com.linearpast.sccore.capability.data.ICapabilitySync;
import net.minecraft.world.entity.animal.Sheep;
/**
* 接口继承ICapabilitySync是必需的但是接口是非必需的你可以在注册时直接使用cap类本身 <br>
* 用于共享一些可能会用到的cap的公共方法
*/
public interface ISheepData extends ICapabilitySync {
public interface ISheepData extends ICapabilitySync<Sheep> {
Integer getValue();
void setValue(Integer value);
}

View File

@ -18,7 +18,7 @@ import java.util.Optional;
* 继承SimpleEntityCapabilitySync意味着自动托管一个id的同步 <br>
* 实现的IsheepData仅含有属性value的getter和setter <br>
*/
public class SheepDataCapability extends SimpleEntityCapabilitySync implements ISheepData {
public class SheepDataCapability extends SimpleEntityCapabilitySync<Sheep> implements ISheepData {
//代表cap的key注册获取时都需要它
public static final ResourceLocation key = new ResourceLocation(SnowyCrescentCore.MODID, "sheep_data");
@ -59,7 +59,7 @@ public class SheepDataCapability extends SimpleEntityCapabilitySync implements I
//从旧实例中复制数据到新实例的方法
@Override
public void copyFrom(ICapabilitySync oldData) {
public void copyFrom(ICapabilitySync<?> oldData) {
SheepDataCapability data = (SheepDataCapability) oldData;
this.value = data.getValue();
}
@ -82,7 +82,7 @@ public class SheepDataCapability extends SimpleEntityCapabilitySync implements I
//仅用在网络包内部的getCap
@Override
public @Nullable ICapabilitySync getCapability(Sheep entity) {
public @Nullable SheepDataCapability getCapability(Sheep entity) {
return SheepDataCapability.getCapability(entity).orElse(null);
}
}
@ -93,6 +93,13 @@ public class SheepDataCapability extends SimpleEntityCapabilitySync implements I
return new SheepCapabilityPacket(serializeNBT());
}
//该方法会在cap初始化时调用比如玩家登录
//该例中当羊加入level时会调用该方法以初始化cap
@Override
public void attachInit(Sheep entity) {
}
//在其他地方需要用到cap的时候调用这个
//目的是为了简化cap utils的方法
public static Optional<SheepDataCapability> getCapability(Sheep sheep){