fix something bug
and add "void attachInit(T entity)" in ICapabilitySync version 0.0.2
This commit is contained in:
parent
d496ad72c2
commit
d5756d6e09
|
|
@ -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.0.1
|
mod_version=1.20.1-0.0.2
|
||||||
mod_group_id=com.linearpast
|
mod_group_id=com.linearpast
|
||||||
mod_authors=LostInLinearPast
|
mod_authors=LostInLinearPast
|
||||||
mod_description=A lib.
|
mod_description=A lib.
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class CapabilityUtils {
|
||||||
* @param handler 网络包的handle
|
* @param handler 网络包的handle
|
||||||
*/
|
*/
|
||||||
public static <T extends ICapabilityPacket<?>> void registerPlayerCapabilityWithNetwork(
|
public static <T extends ICapabilityPacket<?>> void registerPlayerCapabilityWithNetwork(
|
||||||
ResourceLocation key, PlayerCapabilityRegistry.CapabilityRecord<? extends ICapabilitySync> capabilityRecord,
|
ResourceLocation key, PlayerCapabilityRegistry.CapabilityRecord<? extends ICapabilitySync<Player>> capabilityRecord,
|
||||||
CapabilityChannel channelRegister,
|
CapabilityChannel channelRegister,
|
||||||
int cid,
|
int cid,
|
||||||
Class<T> clazz,
|
Class<T> clazz,
|
||||||
|
|
@ -59,7 +59,7 @@ public class CapabilityUtils {
|
||||||
* @param handler 网络包的handle
|
* @param handler 网络包的handle
|
||||||
*/
|
*/
|
||||||
public static <T extends ICapabilityPacket<?>> void registerEntityCapabilityWithNetwork(
|
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,
|
CapabilityChannel channelRegister,
|
||||||
int cid,
|
int cid,
|
||||||
Class<T> clazz,
|
Class<T> clazz,
|
||||||
|
|
@ -77,7 +77,7 @@ public class CapabilityUtils {
|
||||||
* @param key capability的唯一name
|
* @param key capability的唯一name
|
||||||
* @param capabilityRecord 使用record存储了应该注册的capability的各项数据,参阅:{@link PlayerCapabilityRegistry.CapabilityRecord}
|
* @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);
|
PlayerCapabilityRegistry.registerCapability(key, capabilityRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ public class CapabilityUtils {
|
||||||
* @param key capability的唯一name
|
* @param key capability的唯一name
|
||||||
* @param capabilityRecord 使用record存储了应该注册的capability的各项数据,参阅:{@link PlayerCapabilityRegistry.CapabilityRecord}
|
* @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);
|
EntityCapabilityRegistry.registerCapability(key, capabilityRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,48 +119,72 @@ public class CapabilityUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请通过该方法获取玩家的capability
|
* 请通过该方法获取capability
|
||||||
* @param player 目标玩家
|
* @param entity 目标实体,类型 {@code <E extends Entity>}
|
||||||
* @param key capability key
|
* @param key capability的唯一名
|
||||||
* @param clazz 应返回的capability类型
|
* @param clazz 应返回的capability类型,若为null则会返回 {@code ICapabilitySync<E>}
|
||||||
* @return 返回对应的capability
|
* @return 返回对应的capability
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends ICapabilitySync> T getPlayerCapability(Player player, ResourceLocation key, Class<T> clazz) {
|
public static <E extends Entity, T extends ICapabilitySync<E>> T getEntityCapability(E entity, ResourceLocation key, @Nullable 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;
|
|
||||||
try {
|
try {
|
||||||
|
ICapabilitySync<?> capabilitySync = entity.getCapability(
|
||||||
|
EntityCapabilityRegistry.getCapabilityMap().get(key).capability()
|
||||||
|
).resolve().orElse(null);
|
||||||
|
if(clazz == null) return (T) capabilitySync;
|
||||||
if(clazz.isInstance(capabilitySync))
|
if(clazz.isInstance(capabilitySync))
|
||||||
return clazz.cast(capabilitySync);
|
return clazz.cast(capabilitySync);
|
||||||
else return null;
|
else return null;
|
||||||
}catch(ClassCastException e){
|
}catch(Exception e){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请通过该方法获取实体的capability
|
* 请通过该方法获取capability
|
||||||
* @param entity 目标实体
|
* @param entity 目标实体,类型 {@code <E extends Entity>}
|
||||||
* @param key capability key
|
* @param key capability的唯一名
|
||||||
* @param clazz 应返回的capability类型
|
* @param clazz 应返回的capability类型,若为null则会返回 {@code ICapabilitySync<E>}
|
||||||
* @return 返回对应的capability
|
* @return 返回对应的capability
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends ICapabilitySync> T getEntityCapability(Entity entity, ResourceLocation key, Class<T> clazz) {
|
public static <E extends Player, T extends ICapabilitySync<E>> T getPlayerCapability(E entity, ResourceLocation key, @Nullable 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;
|
|
||||||
try {
|
try {
|
||||||
|
ICapabilitySync<?> capabilitySync = entity.getCapability(
|
||||||
|
PlayerCapabilityRegistry.getCapabilityMap().get(key).capability()
|
||||||
|
).resolve().orElse(null);
|
||||||
|
if(clazz == null) return (T) capabilitySync;
|
||||||
if(clazz.isInstance(capabilitySync))
|
if(clazz.isInstance(capabilitySync))
|
||||||
return clazz.cast(capabilitySync);
|
return clazz.cast(capabilitySync);
|
||||||
else return null;
|
else return null;
|
||||||
}catch(ClassCastException e){
|
}catch(Exception e){
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.common.util.INBTSerializable;
|
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);
|
void setDirty(boolean dirty);
|
||||||
boolean isDirty();
|
boolean isDirty();
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ public interface ICapabilitySync extends INBTSerializable<CompoundTag> {
|
||||||
* @param oldData 旧数据
|
* @param oldData 旧数据
|
||||||
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
|
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
|
||||||
*/
|
*/
|
||||||
default void copyFrom(ICapabilitySync oldData, boolean listenDone) {
|
default void copyFrom(ICapabilitySync<?> oldData, boolean listenDone) {
|
||||||
this.setDirty(oldData.isDirty());
|
this.setDirty(oldData.isDirty());
|
||||||
if(listenDone) onCopyDone();
|
if(listenDone) onCopyDone();
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +53,12 @@ public interface ICapabilitySync extends INBTSerializable<CompoundTag> {
|
||||||
* 一般情况下,你应该extends SimpleCapabilityPacket然后重写该方法返回你的子类
|
* 一般情况下,你应该extends SimpleCapabilityPacket然后重写该方法返回你的子类
|
||||||
* @return 网络包类SimpleCapabilityPacket
|
* @return 网络包类SimpleCapabilityPacket
|
||||||
*/
|
*/
|
||||||
SimpleCapabilityPacket<? extends Entity> getDefaultPacket();
|
SimpleCapabilityPacket<T> getDefaultPacket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当玩家登录 / 实体加入世界时的cao初始化时会调用 <br>
|
||||||
|
* 必须实现,但可为空方法
|
||||||
|
* @param entity 目标
|
||||||
|
*/
|
||||||
|
void attachInit(T entity);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class EntityCapabilityHandler {
|
||||||
EntityCapabilityRegistry.getCapabilityMap().forEach((key, record) -> {
|
EntityCapabilityRegistry.getCapabilityMap().forEach((key, record) -> {
|
||||||
if(record.target().isInstance(entity)) {
|
if(record.target().isInstance(entity)) {
|
||||||
try {
|
try {
|
||||||
ICapabilitySync capabilitySync = (ICapabilitySync) record.aClass().getDeclaredConstructor().newInstance();
|
ICapabilitySync<?> capabilitySync = (ICapabilitySync<?>) record.aClass().getDeclaredConstructor().newInstance();
|
||||||
event.addCapability(key, new EntityCapabilityProvider<>(key, capabilitySync));
|
event.addCapability(key, new EntityCapabilityProvider<>(key, capabilitySync));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to instantiate capability sync class {}. Your capability register is wrong.", record.aClass(), e);
|
log.error("Failed to instantiate capability sync class {}. Your capability register is wrong.", record.aClass(), e);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.linearpast.sccore.capability.data.ICapabilitySync;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.common.capabilities.AutoRegisterCapability;
|
import net.minecraftforge.common.capabilities.AutoRegisterCapability;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
||||||
|
|
@ -16,7 +17,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
* @param <C> 继承 {@link ICapabilitySync}
|
* @param <C> 继承 {@link ICapabilitySync}
|
||||||
*/
|
*/
|
||||||
@AutoRegisterCapability
|
@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 C instance;
|
||||||
private final ResourceLocation resourceLocation;
|
private final ResourceLocation resourceLocation;
|
||||||
public EntityCapabilityProvider(ResourceLocation resourceLocation, C instance) {
|
public EntityCapabilityProvider(ResourceLocation resourceLocation, C instance) {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public class EntityCapabilityRegistry {
|
||||||
* @param interfaceClass instance类对应的实例对应的接口类,比如ICapabilitySync.class
|
* @param interfaceClass instance类对应的实例对应的接口类,比如ICapabilitySync.class
|
||||||
* @param target capability附加的目标类型
|
* @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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public class EntityCapabilityRemainder {
|
||||||
public static void onEntityBeTracked(PlayerEvent.StartTracking event) {
|
public static void onEntityBeTracked(PlayerEvent.StartTracking event) {
|
||||||
if (event.getEntity() instanceof ServerPlayer attacker) {
|
if (event.getEntity() instanceof ServerPlayer attacker) {
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
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;
|
if(data == null) return;
|
||||||
data.sendToClient(attacker);
|
data.sendToClient(attacker);
|
||||||
});
|
});
|
||||||
|
|
@ -38,7 +38,7 @@ public class EntityCapabilityRemainder {
|
||||||
if(!entity.level().isClientSide){
|
if(!entity.level().isClientSide){
|
||||||
if (entity.tickCount % 20 == 0) {
|
if (entity.tickCount % 20 == 0) {
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
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 == null) return;
|
||||||
if(data.isDirty()) {
|
if(data.isDirty()) {
|
||||||
data.setDirty(false);
|
data.setDirty(false);
|
||||||
|
|
@ -57,11 +57,12 @@ public class EntityCapabilityRemainder {
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
if(entity.level().isClientSide) return;
|
if(entity.level().isClientSide) return;
|
||||||
EntityCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
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 == null) return;
|
||||||
if(data instanceof SimpleEntityCapabilitySync capabilitySync){
|
if(data instanceof SimpleEntityCapabilitySync<?> capabilitySync){
|
||||||
capabilitySync.setId(entity.getId());
|
capabilitySync.setId(entity.getId());
|
||||||
}
|
}
|
||||||
|
data.attachInit(entity);
|
||||||
data.setDirty(false);
|
data.setDirty(false);
|
||||||
data.sendToClient();
|
data.sendToClient();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.data.entity;
|
||||||
|
|
||||||
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实现时建议手动添加:<br>
|
* 实现时建议手动添加:<br>
|
||||||
|
|
@ -21,7 +22,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class SimpleEntityCapabilitySync implements ICapabilitySync {
|
public abstract class SimpleEntityCapabilitySync<T extends Entity> implements ICapabilitySync<T> {
|
||||||
public static final String Id = "Id";
|
public static final String Id = "Id";
|
||||||
|
|
||||||
private boolean dirty;
|
private boolean dirty;
|
||||||
|
|
@ -57,8 +58,8 @@ public abstract class SimpleEntityCapabilitySync implements ICapabilitySync {
|
||||||
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
|
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void copyFrom(ICapabilitySync oldData, boolean listenDone) {
|
public void copyFrom(ICapabilitySync<?> oldData, boolean listenDone) {
|
||||||
SimpleEntityCapabilitySync data = (SimpleEntityCapabilitySync) oldData;
|
SimpleEntityCapabilitySync<?> data = (SimpleEntityCapabilitySync<?>) oldData;
|
||||||
this.setId(data.getId());
|
this.setId(data.getId());
|
||||||
copyFrom(data);
|
copyFrom(data);
|
||||||
ICapabilitySync.super.copyFrom(oldData, listenDone);
|
ICapabilitySync.super.copyFrom(oldData, listenDone);
|
||||||
|
|
@ -68,7 +69,7 @@ public abstract class SimpleEntityCapabilitySync implements ICapabilitySync {
|
||||||
* 触发数据复制时会执行的方法
|
* 触发数据复制时会执行的方法
|
||||||
* @param oldData 从这个数据中复制到当前实例
|
* @param oldData 从这个数据中复制到当前实例
|
||||||
*/
|
*/
|
||||||
public abstract void copyFrom(ICapabilitySync oldData);
|
public abstract void copyFrom(ICapabilitySync<?> oldData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化为tag <br>
|
* 序列化为tag <br>
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public class PlayerCapabilityHandler {
|
||||||
if(event.getObject() instanceof Player) {
|
if(event.getObject() instanceof Player) {
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, record) -> {
|
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, record) -> {
|
||||||
try {
|
try {
|
||||||
ICapabilitySync capabilitySync = (ICapabilitySync) record.aClass().getDeclaredConstructor().newInstance();
|
ICapabilitySync<?> capabilitySync = (ICapabilitySync<?>) record.aClass().getDeclaredConstructor().newInstance();
|
||||||
event.addCapability(key, new PlayerCapabilityProvider<>(key, capabilitySync));
|
event.addCapability(key, new PlayerCapabilityProvider<>(key, capabilitySync));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to instantiate capability sync class {}. Your capability register is wrong.", record.aClass(), e);
|
log.error("Failed to instantiate capability sync class {}. Your capability register is wrong.", record.aClass(), e);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@AutoRegisterCapability
|
@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 C instance;
|
||||||
private final ResourceLocation resourceLocation;
|
private final ResourceLocation resourceLocation;
|
||||||
public PlayerCapabilityProvider(ResourceLocation resourceLocation, C instance) {
|
public PlayerCapabilityProvider(ResourceLocation resourceLocation, C instance) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.data.player;
|
||||||
|
|
||||||
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -40,5 +41,5 @@ public class PlayerCapabilityRegistry {
|
||||||
* @param capability 一般情况下不需要初始化它,默认:CapabilityManager.get(new CapabilityToken<>(){})
|
* @param capability 一般情况下不需要初始化它,默认:CapabilityManager.get(new CapabilityToken<>(){})
|
||||||
* @param interfaceClass instance实例对应的接口类,比如ICapabilitySync.class
|
* @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) { }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ public class PlayerCapabilityRemainder {
|
||||||
Player original = event.getOriginal();
|
Player original = event.getOriginal();
|
||||||
original.reviveCaps();
|
original.reviveCaps();
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
||||||
ICapabilitySync originData = CapabilityUtils.getPlayerCapability(original, key, ICapabilitySync.class);
|
ICapabilitySync<?> originData = CapabilityUtils.getCapability(original, key);
|
||||||
ICapabilitySync newData = CapabilityUtils.getPlayerCapability(newPlayer, key, ICapabilitySync.class);
|
ICapabilitySync<?> newData = CapabilityUtils.getCapability(newPlayer, key);
|
||||||
if(originData != null && newData != null) {
|
if(originData != null && newData != null) {
|
||||||
newData.copyFrom(originData, true);
|
newData.copyFrom(originData, true);
|
||||||
newData.sendToClient();
|
newData.sendToClient();
|
||||||
|
|
@ -43,7 +43,7 @@ public class PlayerCapabilityRemainder {
|
||||||
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
|
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
|
||||||
if(event.getEntity() instanceof ServerPlayer newPlayer){
|
if(event.getEntity() instanceof ServerPlayer newPlayer){
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
||||||
ICapabilitySync data = CapabilityUtils.getPlayerCapability(newPlayer, key, ICapabilitySync.class);
|
ICapabilitySync<?> data = CapabilityUtils.getCapability(newPlayer, key);
|
||||||
if(data == null) return;
|
if(data == null) return;
|
||||||
data.sendToClient(newPlayer);
|
data.sendToClient(newPlayer);
|
||||||
});
|
});
|
||||||
|
|
@ -59,7 +59,7 @@ public class PlayerCapabilityRemainder {
|
||||||
public static void onEntityBeTracked(PlayerEvent.StartTracking event) {
|
public static void onEntityBeTracked(PlayerEvent.StartTracking event) {
|
||||||
if (event.getTarget() instanceof Player target && event.getEntity() instanceof ServerPlayer attacker) {
|
if (event.getTarget() instanceof Player target && event.getEntity() instanceof ServerPlayer attacker) {
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
||||||
ICapabilitySync data = CapabilityUtils.getPlayerCapability(target, key, ICapabilitySync.class);
|
ICapabilitySync<?> data = CapabilityUtils.getCapability(target, key);
|
||||||
if(data == null) return;
|
if(data == null) return;
|
||||||
data.sendToClient(attacker);
|
data.sendToClient(attacker);
|
||||||
});
|
});
|
||||||
|
|
@ -74,7 +74,7 @@ public class PlayerCapabilityRemainder {
|
||||||
public static void capabilitySync(TickEvent.PlayerTickEvent event) {
|
public static void capabilitySync(TickEvent.PlayerTickEvent event) {
|
||||||
if(!event.player.level().isClientSide){
|
if(!event.player.level().isClientSide){
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
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 == null) return;
|
||||||
if(data.isDirty()) {
|
if(data.isDirty()) {
|
||||||
data.setDirty(false);
|
data.setDirty(false);
|
||||||
|
|
@ -94,11 +94,12 @@ public class PlayerCapabilityRemainder {
|
||||||
Player player = event.getEntity();
|
Player player = event.getEntity();
|
||||||
if(!(player instanceof ServerPlayer serverPlayer)) return;
|
if(!(player instanceof ServerPlayer serverPlayer)) return;
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
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 == null) return;
|
||||||
if(data instanceof SimplePlayerCapabilitySync capabilitySync) {
|
if(data instanceof SimplePlayerCapabilitySync capabilitySync) {
|
||||||
capabilitySync.setOwnerUUID(serverPlayer.getUUID());
|
capabilitySync.setOwnerUUID(serverPlayer.getUUID());
|
||||||
}
|
}
|
||||||
|
data.attachInit(serverPlayer);
|
||||||
data.setDirty(false);
|
data.setDirty(false);
|
||||||
data.sendToClient();
|
data.sendToClient();
|
||||||
});
|
});
|
||||||
|
|
@ -106,7 +107,7 @@ public class PlayerCapabilityRemainder {
|
||||||
serverPlayers -> serverPlayers.forEach(p -> {
|
serverPlayers -> serverPlayers.forEach(p -> {
|
||||||
if(!p.getUUID().equals(serverPlayer.getUUID())) {
|
if(!p.getUUID().equals(serverPlayer.getUUID())) {
|
||||||
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
PlayerCapabilityRegistry.getCapabilityMap().forEach((key, value) -> {
|
||||||
ICapabilitySync data = CapabilityUtils.getPlayerCapability(player, key, ICapabilitySync.class);
|
ICapabilitySync<?> data = CapabilityUtils.getCapability(player, key);
|
||||||
if(data == null) return;
|
if(data == null) return;
|
||||||
data.sendToClient(serverPlayer);
|
data.sendToClient(serverPlayer);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.data.player;
|
||||||
|
|
||||||
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -23,7 +24,7 @@ import java.util.UUID;
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class SimplePlayerCapabilitySync implements ICapabilitySync {
|
public abstract class SimplePlayerCapabilitySync implements ICapabilitySync<Player> {
|
||||||
public static final String OwnerUUID = "OwnerUUID";
|
public static final String OwnerUUID = "OwnerUUID";
|
||||||
|
|
||||||
private boolean dirty;
|
private boolean dirty;
|
||||||
|
|
@ -55,9 +56,10 @@ public abstract class SimplePlayerCapabilitySync implements ICapabilitySync {
|
||||||
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
|
* @param listenDone 最后是否执行完成方法 {@link ICapabilitySync#onCopyDone()}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void copyFrom(ICapabilitySync oldData, boolean listenDone) {
|
public void copyFrom(ICapabilitySync<?> oldData, boolean listenDone) {
|
||||||
SimplePlayerCapabilitySync data = (SimplePlayerCapabilitySync) oldData;
|
SimplePlayerCapabilitySync data = (SimplePlayerCapabilitySync) oldData;
|
||||||
this.setOwnerUUID(data.getOwnerUUID());
|
this.setOwnerUUID(data.getOwnerUUID());
|
||||||
|
copyFrom(data);
|
||||||
ICapabilitySync.super.copyFrom(oldData, listenDone);
|
ICapabilitySync.super.copyFrom(oldData, listenDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +67,7 @@ public abstract class SimplePlayerCapabilitySync implements ICapabilitySync {
|
||||||
* 触发数据复制时会执行的方法
|
* 触发数据复制时会执行的方法
|
||||||
* @param oldData 从这个数据中复制到当前实例
|
* @param oldData 从这个数据中复制到当前实例
|
||||||
*/
|
*/
|
||||||
public abstract void copyFrom(ICapabilitySync oldData);
|
public abstract void copyFrom(ICapabilitySync<?> oldData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化为tag <br>
|
* 序列化为tag <br>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.linearpast.sccore.capability.network;
|
||||||
|
|
||||||
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
||||||
import com.linearpast.sccore.capability.data.entity.SimpleEntityCapabilitySync;
|
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.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
@ -33,7 +34,14 @@ public abstract class SimpleCapabilityPacket<T extends Entity> implements ICapab
|
||||||
ClientLevel level = instance.level;
|
ClientLevel level = instance.level;
|
||||||
if (level == null) return;
|
if (level == null) return;
|
||||||
CompoundTag nbt = getData();
|
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 {
|
try {
|
||||||
ICapabilitySync data = getCapability((T) entity);
|
ICapabilitySync data = getCapability((T) entity);
|
||||||
syncData(nbt, data);
|
syncData(nbt, data);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
|
||||||
public class ModCaps {
|
public class ModCaps {
|
||||||
/**
|
/**
|
||||||
* 注册capability的示例<br>
|
* 注册实体capability的示例<br>
|
||||||
|
* 请参阅 {@link CapabilityUtils}
|
||||||
*/
|
*/
|
||||||
public static void register(){
|
public static void register(){
|
||||||
//如果你想将网络包注册到你自己的mod中,createChannel(INSTANCE)
|
//如果你想将网络包注册到你自己的mod中,createChannel(INSTANCE)
|
||||||
|
|
@ -23,6 +24,7 @@ public class ModCaps {
|
||||||
//不可与其他网络包重复的任意整数
|
//不可与其他网络包重复的任意整数
|
||||||
int cid = Channel.getCid();
|
int cid = Channel.getCid();
|
||||||
//注册实体cap和它的网络包
|
//注册实体cap和它的网络包
|
||||||
|
//若注册玩家的请用registerPlayerCapabilityWithNetwork
|
||||||
CapabilityUtils.registerEntityCapabilityWithNetwork(
|
CapabilityUtils.registerEntityCapabilityWithNetwork(
|
||||||
//一个resourceLocation,任意命名,不重复即可
|
//一个resourceLocation,任意命名,不重复即可
|
||||||
SheepDataCapability.key,
|
SheepDataCapability.key,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
package com.linearpast.sccore.example.cap;
|
package com.linearpast.sccore.example.cap;
|
||||||
|
|
||||||
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
import com.linearpast.sccore.capability.data.ICapabilitySync;
|
||||||
|
import net.minecraft.world.entity.animal.Sheep;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口继承ICapabilitySync是必需的,但是接口是非必需的(你可以在注册时直接使用cap类本身) <br>
|
* 接口继承ICapabilitySync是必需的,但是接口是非必需的(你可以在注册时直接使用cap类本身) <br>
|
||||||
* 用于共享一些可能会用到的cap的公共方法
|
* 用于共享一些可能会用到的cap的公共方法
|
||||||
*/
|
*/
|
||||||
public interface ISheepData extends ICapabilitySync {
|
public interface ISheepData extends ICapabilitySync<Sheep> {
|
||||||
Integer getValue();
|
Integer getValue();
|
||||||
void setValue(Integer value);
|
void setValue(Integer value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import java.util.Optional;
|
||||||
* 继承SimpleEntityCapabilitySync意味着自动托管一个id的同步 <br>
|
* 继承SimpleEntityCapabilitySync意味着自动托管一个id的同步 <br>
|
||||||
* 实现的IsheepData仅含有属性value的getter和setter <br>
|
* 实现的IsheepData仅含有属性value的getter和setter <br>
|
||||||
*/
|
*/
|
||||||
public class SheepDataCapability extends SimpleEntityCapabilitySync implements ISheepData {
|
public class SheepDataCapability extends SimpleEntityCapabilitySync<Sheep> implements ISheepData {
|
||||||
//代表cap的key,注册、获取时都需要它
|
//代表cap的key,注册、获取时都需要它
|
||||||
public static final ResourceLocation key = new ResourceLocation(SnowyCrescentCore.MODID, "sheep_data");
|
public static final ResourceLocation key = new ResourceLocation(SnowyCrescentCore.MODID, "sheep_data");
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ public class SheepDataCapability extends SimpleEntityCapabilitySync implements I
|
||||||
|
|
||||||
//从旧实例中复制数据到新实例的方法
|
//从旧实例中复制数据到新实例的方法
|
||||||
@Override
|
@Override
|
||||||
public void copyFrom(ICapabilitySync oldData) {
|
public void copyFrom(ICapabilitySync<?> oldData) {
|
||||||
SheepDataCapability data = (SheepDataCapability) oldData;
|
SheepDataCapability data = (SheepDataCapability) oldData;
|
||||||
this.value = data.getValue();
|
this.value = data.getValue();
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ public class SheepDataCapability extends SimpleEntityCapabilitySync implements I
|
||||||
|
|
||||||
//仅用在网络包内部的getCap
|
//仅用在网络包内部的getCap
|
||||||
@Override
|
@Override
|
||||||
public @Nullable ICapabilitySync getCapability(Sheep entity) {
|
public @Nullable SheepDataCapability getCapability(Sheep entity) {
|
||||||
return SheepDataCapability.getCapability(entity).orElse(null);
|
return SheepDataCapability.getCapability(entity).orElse(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +93,13 @@ public class SheepDataCapability extends SimpleEntityCapabilitySync implements I
|
||||||
return new SheepCapabilityPacket(serializeNBT());
|
return new SheepCapabilityPacket(serializeNBT());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//该方法会在cap初始化时调用,比如玩家登录
|
||||||
|
//该例中,当羊加入level时会调用该方法以初始化cap
|
||||||
|
@Override
|
||||||
|
public void attachInit(Sheep entity) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//在其他地方需要用到cap的时候调用这个
|
//在其他地方需要用到cap的时候调用这个
|
||||||
//目的是为了简化cap utils的方法
|
//目的是为了简化cap utils的方法
|
||||||
public static Optional<SheepDataCapability> getCapability(Sheep sheep){
|
public static Optional<SheepDataCapability> getCapability(Sheep sheep){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user