提供: Minecraft Modding Wiki
細 (→ExtendedPlayerPropertiesクラス) |
細 (→SampleModクラス) |
||
(2人の利用者による、間の7版が非表示) | |||
13行目: | 13行目: | ||
package com.example.examplemod; | package com.example.examplemod; | ||
− | import | + | import net.minecraftforge.fml.common.FMLCommonHandler; |
− | import | + | import net.minecraftforge.fml.common.Mod; |
− | import | + | import net.minecraftforge.fml.common.Mod.EventHandler; |
− | import | + | import net.minecraftforge.fml.common.event.FMLInitializationEvent; |
− | import | + | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; |
− | import | + | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; |
− | import | + | import net.minecraftforge.fml.common.gameevent.PlayerEvent; |
import net.minecraft.entity.player.EntityPlayer; | import net.minecraft.entity.player.EntityPlayer; | ||
import net.minecraft.entity.player.EntityPlayerMP; | import net.minecraft.entity.player.EntityPlayerMP; | ||
32行目: | 32行目: | ||
//1.8のforgeを指定 | //1.8のforgeを指定 | ||
− | @Mod(modid = "SampleMod", name = "SampleMod", version = "1.0", dependencies = "required-after:Forge@[11.14.0.1296,)", useMetadata = true) | + | @Mod(modid = "SampleMod", |
+ | name = "SampleMod", | ||
+ | version = "1.0", | ||
+ | dependencies = "required-after:Forge@[11.14.0.1296,)", | ||
+ | acceptedMinecraftVersions = "[1.8,1.8.9]", | ||
+ | useMetadata = true) | ||
public class SampleMod { | public class SampleMod { | ||
@SidedProxy(clientSide = "sampleMod.ClientProxy", serverSide = "sampleMod.CommonProxy") | @SidedProxy(clientSide = "sampleMod.ClientProxy", serverSide = "sampleMod.CommonProxy") | ||
public static CommonProxy proxy; | public static CommonProxy proxy; | ||
− | |||
− | |||
− | |||
@EventHandler | @EventHandler | ||
public void preInit(FMLPreInitializationEvent event) { | public void preInit(FMLPreInitializationEvent event) { | ||
47行目: | 49行目: | ||
@EventHandler | @EventHandler | ||
public void init(FMLInitializationEvent event) { | public void init(FMLInitializationEvent event) { | ||
+ | //二箇所に登録するので、先にインスタンスを生成しておく。 | ||
+ | SampleEntityPropertiesEventHandler sampleEntityPropertiesEventHandler = new SampleEntityPropertiesEventHandler(); | ||
//Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent | //Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent | ||
− | MinecraftForge.EVENT_BUS.register( | + | MinecraftForge.EVENT_BUS.register(sampleEntityPropertiesEventHandler); |
− | //FML | + | //FML Eventの登録。PlayerRespawnEvent |
− | FMLCommonHandler.instance().bus().register( | + | FMLCommonHandler.instance().bus().register(sampleEntityPropertiesEventHandler); |
} | } | ||
+ | } | ||
+ | </source> | ||
+ | ===SampleEntityPropertiesEventHanderクラス=== | ||
+ | <source lang = "java"> | ||
+ | package com.example.examplemod; | ||
+ | |||
+ | import net.minecraft.entity.player.EntityPlayer; | ||
+ | import net.minecraft.entity.player.EntityPlayerMP; | ||
+ | import net.minecraft.nbt.NBTTagCompound; | ||
+ | import net.minecraftforge.common.IExtendedEntityProperties; | ||
+ | import net.minecraftforge.event.entity.EntityEvent; | ||
+ | import net.minecraftforge.event.entity.EntityJoinWorldEvent; | ||
+ | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | ||
+ | import net.minecraftforge.fml.common.gameevent.PlayerEvent; | ||
+ | |||
+ | public class SampleEntityPropertiesEventHandler { | ||
+ | |||
+ | /*IExtendedEntityPropertiesを登録する処理を呼び出す*/ | ||
@SubscribeEvent | @SubscribeEvent | ||
− | |||
public void onEntityConstructing(EntityEvent.EntityConstructing event) { | public void onEntityConstructing(EntityEvent.EntityConstructing event) { | ||
if (event.entity instanceof EntityPlayer) { | if (event.entity instanceof EntityPlayer) { | ||
− | ExtendedPlayerProperties.register((EntityPlayer)event.entity | + | ExtendedPlayerProperties.register((EntityPlayer) event.entity); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
74行目: | 85行目: | ||
/*ワールドに入った時に呼ばれるイベント。ここでIExtendedEntityPropertiesを読み込む処理を呼び出す*/ | /*ワールドに入った時に呼ばれるイベント。ここでIExtendedEntityPropertiesを読み込む処理を呼び出す*/ | ||
public void onEntityJoinWorld(EntityJoinWorldEvent event) { | public void onEntityJoinWorld(EntityJoinWorldEvent event) { | ||
− | if (event. | + | if (event.world.isRemote && event.entity instanceof EntityPlayer) { |
EntityPlayer player = (EntityPlayer)event.entity; | EntityPlayer player = (EntityPlayer)event.entity; | ||
PacketHandler.INSTANCE.sendToServer(new MessagePlayerJoinInAnnouncement(player)); | PacketHandler.INSTANCE.sendToServer(new MessagePlayerJoinInAnnouncement(player)); | ||
81行目: | 92行目: | ||
@SubscribeEvent | @SubscribeEvent | ||
− | / | + | //Dimension移動時や、リスポーン時に呼ばれるイベント。古いインスタンスと新しいインスタンスの両方を参照できる。 |
− | public void | + | public void onClonePlayer(net.minecraftforge.event.entity.player.PlayerEvent.Clone event) { |
− | if ( | + | //死亡時に呼ばれてるかどうか |
− | + | if (event.wasDeath) { | |
+ | //古いカスタムデータ | ||
+ | IExtendedEntityProperties oldEntityProperties = event.original.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME); | ||
+ | //新しいカスタムデータ | ||
+ | IExtendedEntityProperties newEntityProperties = event.entityPlayer.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME); | ||
+ | NBTTagCompound playerData = new NBTTagCompound(); | ||
+ | //データの吸い出し | ||
+ | oldEntityProperties.saveNBTData(playerData); | ||
+ | //データの書き込み | ||
+ | newEntityProperties.loadNBTData(playerData); | ||
+ | |||
} | } | ||
} | } | ||
@SubscribeEvent | @SubscribeEvent | ||
− | /* | + | /*リスポーン時に呼ばれるイベント。Serverとの同期を取る*/ |
− | public void | + | public void respawnEvent(PlayerEvent.PlayerRespawnEvent event) { |
if (!event.player.worldObj.isRemote) { | if (!event.player.worldObj.isRemote) { | ||
PacketHandler.INSTANCE.sendTo(new MessagePlayerProperties(event.player), (EntityPlayerMP)event.player); | PacketHandler.INSTANCE.sendTo(new MessagePlayerProperties(event.player), (EntityPlayerMP)event.player); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
</source> | </source> | ||
− | |||
===ExtendedPlayerPropertiesクラス=== | ===ExtendedPlayerPropertiesクラス=== | ||
<source lang = "java"> | <source lang = "java"> | ||
135行目: | 145行目: | ||
private ItemStack[] sampleItemStacks = new ItemStack[10]; | private ItemStack[] sampleItemStacks = new ItemStack[10]; | ||
private NBTTagCompound sampleNBTTagCompound = new NBTTagCompound(); | private NBTTagCompound sampleNBTTagCompound = new NBTTagCompound(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
/*EntityPlayerにIExtendedEntityPropertiesを登録。登録文字列はMOD固有のものを割り当てること*/ | /*EntityPlayerにIExtendedEntityPropertiesを登録。登録文字列はMOD固有のものを割り当てること*/ | ||
273行目: | 277行目: | ||
</source> | </source> | ||
− | |||
===CommonProxyクラス=== | ===CommonProxyクラス=== | ||
− | <source lang = "java"> | + | <source lang = "java"> |
package com.example.examplemod; | package com.example.examplemod; | ||
292行目: | 295行目: | ||
===ClientProxyクラス=== | ===ClientProxyクラス=== | ||
− | <source lang = "java"> | + | <source lang = "java"> |
package com.example.examplemod; | package com.example.examplemod; | ||
314行目: | 317行目: | ||
</source> | </source> | ||
===PacketHandlerクラス=== | ===PacketHandlerクラス=== | ||
− | <source lang = "java"> | + | <source lang = "java"> |
package com.example.examplemod; | package com.example.examplemod; | ||
396行目: | 399行目: | ||
</source> | </source> | ||
− | ===MessagePlayerJoinInAnnouncementクラス= | + | ===MessagePlayerJoinInAnnouncementクラス=== |
<source lang = "java"> | <source lang = "java"> | ||
package com.example.examplemod; | package com.example.examplemod; | ||
412行目: | 415行目: | ||
public MessagePlayerJoinInAnnouncement(EntityPlayer player) { | public MessagePlayerJoinInAnnouncement(EntityPlayer player) { | ||
+ | //PlayerのUUIDを文字列で取得 | ||
this.uuid = player.getGameProfile().getId().toString(); | this.uuid = player.getGameProfile().getId().toString(); | ||
} | } | ||
430行目: | 434行目: | ||
} | } | ||
</source> | </source> | ||
− | ===MessagePlayerJoinInAnnouncementHandlerクラス= | + | ===MessagePlayerJoinInAnnouncementHandlerクラス=== |
<source lang = "java"> | <source lang = "java"> | ||
− | + | package com.example.examplemod; | |
import net.minecraft.entity.player.EntityPlayer; | import net.minecraft.entity.player.EntityPlayer; | ||
444行目: | 448行目: | ||
//UUIDの文字列を受け取る | //UUIDの文字列を受け取る | ||
String uuidString = message.getUuid(); | String uuidString = message.getUuid(); | ||
− | |||
− | |||
EntityPlayer player = ctx.getServerHandler().playerEntity; | EntityPlayer player = ctx.getServerHandler().playerEntity; | ||
− | if ( | + | //取得したPlayerが同一UUIDを持つか判定 |
− | // | + | if (player.getGameProfile().getId().toString().equals(uuidString)) { |
− | (player | + | //クライアント側にデータを送る |
+ | return new MessagePlayerProperties(player); | ||
} | } | ||
− | // | + | //UUIDが違っていた場合、同期処理を呼ばない |
− | return | + | return null; |
} | } | ||
} | } | ||
463行目: | 466行目: | ||
ExtendedPlayerProperties.get(playerインスタンス).getSampleInt()という形でデータを呼び出す。<br> | ExtendedPlayerProperties.get(playerインスタンス).getSampleInt()という形でデータを呼び出す。<br> | ||
ExtendedPlayerProperties.get(playerインスタンス).setSampleInt(sample)という形でデータを書き込む。<br> | ExtendedPlayerProperties.get(playerインスタンス).setSampleInt(sample)という形でデータを書き込む。<br> | ||
− | + | 死亡時等でカスタムデータが初期化されるので、CloneEventでデータを新しいインスタンスに移行し、EntityJoinWorldEventとRespawnEventで、クライアント側にデータを送って同期させている。 | |
− |
2015年12月30日 (水) 23:50時点における最新版
この記事は"Minecraft Forge Universal 11.14.0~"を前提MODとしています。 |
この記事は執筆中です。加筆してくださる人を募集しています。 |
目次
- 1 プレイヤーへのカスタムデータの追加
- 2 ソースコード
- 2.1 SampleModクラス
- 2.2 SampleEntityPropertiesEventHanderクラス
- 2.3 ExtendedPlayerPropertiesクラス
- 2.4 CommonProxyクラス
- 2.5 ClientProxyクラス
- 2.6 PacketHandlerクラス
- 2.7 MessagePlayerPropertiesクラス
- 2.8 MessagePlayerPropertiesHandlerクラス
- 2.9 MessagePlayerJoinInAnnouncementクラス
- 2.10 MessagePlayerJoinInAnnouncementHandlerクラス
- 3 解説
プレイヤーへのカスタムデータの追加[編集]
各プレイヤーにカスタムデータを追加する。 方法としては、EntityクラスのgetEntityDataメソッドの利用か、ForgeのIExtendedEntityPropertiesインターフェースの利用の二通りある。
このチュートリアルでは、IExtendedEntityPropertiesによる実装方法を解説する。
ソースコード[編集]
SampleModクラス[編集]
package com.example.examplemod; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent; import java.util.HashMap; import java.util.Map; //1.8のforgeを指定 @Mod(modid = "SampleMod", name = "SampleMod", version = "1.0", dependencies = "required-after:Forge@[11.14.0.1296,)", acceptedMinecraftVersions = "[1.8,1.8.9]", useMetadata = true) public class SampleMod { @SidedProxy(clientSide = "sampleMod.ClientProxy", serverSide = "sampleMod.CommonProxy") public static CommonProxy proxy; @EventHandler public void preInit(FMLPreInitializationEvent event) { //Messageの登録呼び出し PacketHandler.init(); } @EventHandler public void init(FMLInitializationEvent event) { //二箇所に登録するので、先にインスタンスを生成しておく。 SampleEntityPropertiesEventHandler sampleEntityPropertiesEventHandler = new SampleEntityPropertiesEventHandler(); //Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent MinecraftForge.EVENT_BUS.register(sampleEntityPropertiesEventHandler); //FML Eventの登録。PlayerRespawnEvent FMLCommonHandler.instance().bus().register(sampleEntityPropertiesEventHandler); } }
SampleEntityPropertiesEventHanderクラス[編集]
package com.example.examplemod; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.IExtendedEntityProperties; import net.minecraftforge.event.entity.EntityEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent; public class SampleEntityPropertiesEventHandler { /*IExtendedEntityPropertiesを登録する処理を呼び出す*/ @SubscribeEvent public void onEntityConstructing(EntityEvent.EntityConstructing event) { if (event.entity instanceof EntityPlayer) { ExtendedPlayerProperties.register((EntityPlayer) event.entity); } } @SubscribeEvent /*ワールドに入った時に呼ばれるイベント。ここでIExtendedEntityPropertiesを読み込む処理を呼び出す*/ public void onEntityJoinWorld(EntityJoinWorldEvent event) { if (event.world.isRemote && event.entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)event.entity; PacketHandler.INSTANCE.sendToServer(new MessagePlayerJoinInAnnouncement(player)); } } @SubscribeEvent //Dimension移動時や、リスポーン時に呼ばれるイベント。古いインスタンスと新しいインスタンスの両方を参照できる。 public void onClonePlayer(net.minecraftforge.event.entity.player.PlayerEvent.Clone event) { //死亡時に呼ばれてるかどうか if (event.wasDeath) { //古いカスタムデータ IExtendedEntityProperties oldEntityProperties = event.original.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME); //新しいカスタムデータ IExtendedEntityProperties newEntityProperties = event.entityPlayer.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME); NBTTagCompound playerData = new NBTTagCompound(); //データの吸い出し oldEntityProperties.saveNBTData(playerData); //データの書き込み newEntityProperties.loadNBTData(playerData); } } @SubscribeEvent /*リスポーン時に呼ばれるイベント。Serverとの同期を取る*/ public void respawnEvent(PlayerEvent.PlayerRespawnEvent event) { if (!event.player.worldObj.isRemote) { PacketHandler.INSTANCE.sendTo(new MessagePlayerProperties(event.player), (EntityPlayerMP)event.player); } } }
ExtendedPlayerPropertiesクラス[編集]
package com.example.examplemod; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; import net.minecraftforge.common.util.Constants; public class ExtendedPlayerProperties implements IExtendedEntityProperties { /* MOD固有の文字列。EntityPlayerに登録時に使用。 MOD内で複数のIExtendedEntityPropertiesを使う場合は、別の文字列をそれぞれ割り当てること。*/ public final static String EXT_PROP_NAME = "samplePlayerData"; private int sampleInt = 0; private double sampleDouble = 0.0D; private boolean sampleBoolean = false; private String sampleString = ""; private ItemStack sampleItemStack = new ItemStack(Items.apple); private ItemStack[] sampleItemStacks = new ItemStack[10]; private NBTTagCompound sampleNBTTagCompound = new NBTTagCompound(); /*EntityPlayerにIExtendedEntityPropertiesを登録。登録文字列はMOD固有のものを割り当てること*/ public static void register(EntityPlayer player) { player.registerExtendedProperties(EXT_PROP_NAME, new ExtendedPlayerProperties()); } /*IExtendedEntityPropertiesをEntityPlayerインスタンスから取得する*/ public static ExtendedPlayerProperties get(EntityPlayer player) { return (ExtendedPlayerProperties)player.getExtendedProperties(EXT_PROP_NAME); } @Override public void saveNBTData(NBTTagCompound compound) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setInteger("sampleInt", this.sampleInt); nbt.setDouble("sampleDouble", this.sampleDouble); nbt.setBoolean("sampleBoolean", this.sampleBoolean); nbt.setString("sampleString", this.sampleString); nbt.setTag("sampleTag", this.sampleNBTTagCompound); //ItemStackの保存 NBTTagCompound itemNBT = new NBTTagCompound(); this.sampleItemStack.writeToNBT(itemNBT); nbt.setTag("sampleItemStack", itemNBT); //ItemStackの配列の保存 NBTTagList itemsTagList = new NBTTagList(); for (int i = 0; i < this.sampleItemStacks.length; ++i) { if (this.sampleItemStacks[i] != null) { NBTTagCompound var4 = new NBTTagCompound(); var4.setByte("Slot", (byte)i); this.sampleItemStacks[i].writeToNBT(var4); itemsTagList.appendTag(var4); } } nbt.setTag("Items", itemsTagList); compound.setTag(EXT_PROP_NAME, nbt); } @Override public void loadNBTData(NBTTagCompound compound) { NBTTagCompound nbt = (NBTTagCompound)compound.getTag(EXT_PROP_NAME); this.sampleInt = nbt.getInteger("sampleInt"); this.sampleDouble = nbt.getDouble("sampleDouble"); this.sampleBoolean = nbt.getBoolean("sampleBoolean"); this.sampleString = nbt.getString("sampleString"); this.sampleNBTTagCompound = nbt.getCompoundTag("sampleTag"); //ItemStackの読み込み this.sampleItemStack = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("sampleItemStack")); //ItemStackの配列の読み込み NBTTagList itemsTagList = nbt.getTagList("Items", Constants.NBT.TAG_COMPOUND); this.sampleItemStacks = new ItemStack[10]; for (int i = 0; i < itemsTagList.tagCount(); ++i) { NBTTagCompound var4 = itemsTagList.getCompoundTagAt(i); int slot = var4.getByte("Slot") & 255; if (slot >= 0 && slot < this.sampleItemStacks.length) { this.sampleItemStacks[slot] = ItemStack.loadItemStackFromNBT(var4); } } } @Override /*初期化メソッド。今のところ使う必要はない。*/ public void init(Entity entity, World world) {} /*以降、各変数のGetterおよびSetter。 * 使い方としては、EntityPlayerのインスタンスが取得できるメソッド内で、 * ExtendedPlayerProperties.get(playerインスタンス).setSampleInt(sample) * と呼び出す。*/ public int getSampleInt() { return sampleInt; } public void setSampleInt(int sampleInt) { this.sampleInt = sampleInt; } public double getSampleDouble() { return sampleDouble; } public void setSampleDouble(double sampleDouble) { this.sampleDouble = sampleDouble; } public boolean isSampleBoolean() { return sampleBoolean; } public void setSampleBoolean(boolean sampleBoolean) { this.sampleBoolean = sampleBoolean; } public String getSampleString() { return sampleString; } public void setSampleString(String sampleString) { this.sampleString = sampleString; } public ItemStack getSampleItemStack() { return sampleItemStack; } public void setSampleItemStack(ItemStack sampleItemStack) { this.sampleItemStack = sampleItemStack; } public ItemStack[] getSampleItemStacks() { return sampleItemStacks; } public void setSampleItemStacks(ItemStack[] sampleItemStacks) { this.sampleItemStacks = sampleItemStacks; } public NBTTagCompound getSampleNBTTagCompound() { return sampleNBTTagCompound; } public void setSampleNBTTagCompound(NBTTagCompound sampleNBTTagCompound) { this.sampleNBTTagCompound = sampleNBTTagCompound; } }
CommonProxyクラス[編集]
package com.example.examplemod; import net.minecraft.entity.player.EntityPlayer; public class CommonProxy { public EntityPlayer getEntityPlayerInstance() {return null;} }
ClientProxyクラス[編集]
package com.example.examplemod; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; public class ClientProxy extends CommonProxy { @Override public EntityPlayer getEntityPlayerInstance() { return Minecraft.getMinecraft().thePlayer; } }
PacketHandlerクラス[編集]
package com.example.examplemod; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; import net.minecraftforge.fml.relauncher.Side; public class PacketHandler { /*MOD固有のSimpleNetworkWrapperを取得。 * 文字列は他のMODと被らないようにMOD_IDを指定しておくと良い*/ public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("samplemod"); public static void init() { /*Messageクラスの登録。 * 第一引数:IMessageHandlerクラス * 第二引数:送るMessageクラス * 第三引数:登録番号。255個まで * 第四引数:ClientとServerのどちらに送るか。送り先*/ INSTANCE.registerMessage(MessagePlayerPropertiesHandler.class, MessagePlayerProperties.class, 0, Side.CLIENT); INSTANCE.registerMessage(MessagePlayerJoinInAnoucementHandler.class, MessagePlayerJoinInAnnouncement.class, 1, Side.SERVER); } }
MessagePlayerPropertiesクラス[編集]
package com.example.examplemod; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; public class MessagePlayerProperties implements IMessage { public NBTTagCompound data; public MessagePlayerProperties(){} public MessagePlayerProperties(EntityPlayer entityPlayer) { this.data = new NBTTagCompound(); //EntityPlayerからIExtendedEntityPropertiesを取得。 ExtendedPlayerProperties.get(entityPlayer).saveNBTData(data); } @Override public void fromBytes(ByteBuf buf) { data = ByteBufUtils.readTag(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeTag(buf, data); } }
MessagePlayerPropertiesHandlerクラス[編集]
package com.example.examplemod; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; public class MessagePlayerPropertiesHandler implements IMessageHandler<MessagePlayerProperties, IMessage> { @Override public IMessage onMessage(MessagePlayerProperties message, MessageContext ctx) { //Client側にIExtendedEntityPropertiesを渡す。 ExtendedPlayerProperties.get(SampleMod.proxy.getEntityPlayerInstance()).loadNBTData(message.data); //REPLYは送らないので、nullを返す。 return null; } }
MessagePlayerJoinInAnnouncementクラス[編集]
package com.example.examplemod; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; public class MessagePlayerJoinInAnnouncement implements IMessage { private String uuid; public MessagePlayerJoinInAnnouncement(){} public MessagePlayerJoinInAnnouncement(EntityPlayer player) { //PlayerのUUIDを文字列で取得 this.uuid = player.getGameProfile().getId().toString(); } @Override public void fromBytes(ByteBuf buf) { this.uuid = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, this.uuid); } public String getUuid() { return uuid; } }
MessagePlayerJoinInAnnouncementHandlerクラス[編集]
package com.example.examplemod; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class MessagePlayerJoinInAnoucementHandler implements IMessageHandler<MessagePlayerJoinInAnnouncement, MessagePlayerProperties> { @Override public MessagePlayerProperties onMessage(MessagePlayerJoinInAnnouncement message, MessageContext ctx) { //UUIDの文字列を受け取る String uuidString = message.getUuid(); EntityPlayer player = ctx.getServerHandler().playerEntity; //取得したPlayerが同一UUIDを持つか判定 if (player.getGameProfile().getId().toString().equals(uuidString)) { //クライアント側にデータを送る return new MessagePlayerProperties(player); } //UUIDが違っていた場合、同期処理を呼ばない return null; } }
解説[編集]
細かい説明はソースコード内に付記したので、そちらを参照のこと。
使用の流れを簡単に書くと、
EntityEvent.EntityConstructingにて、IExtendedEntityPropertiesを登録。
ExtendedPlayerProperties.get(playerインスタンス).getSampleInt()という形でデータを呼び出す。
ExtendedPlayerProperties.get(playerインスタンス).setSampleInt(sample)という形でデータを書き込む。
死亡時等でカスタムデータが初期化されるので、CloneEventでデータを新しいインスタンスに移行し、EntityJoinWorldEventとRespawnEventで、クライアント側にデータを送って同期させている。