提供: Minecraft Modding Wiki
この編集を取り消せます。
下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。
最新版 | 編集中の文章 | ||
1行目: | 1行目: | ||
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}} | {{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}} | ||
− | |||
− | |||
{{stb}} | {{stb}} | ||
==プレイヤーへのカスタムデータの追加== | ==プレイヤーへのカスタムデータの追加== | ||
17行目: | 15行目: | ||
import cpw.mods.fml.common.Mod.EventHandler; | import cpw.mods.fml.common.Mod.EventHandler; | ||
import cpw.mods.fml.common.event.FMLInitializationEvent; | import cpw.mods.fml.common.event.FMLInitializationEvent; | ||
− | import cpw.mods.fml.common.event. | + | import cpw.mods.fml.common.event.FMLPostInitializationEvent; |
import cpw.mods.fml.common.eventhandler.SubscribeEvent; | import cpw.mods.fml.common.eventhandler.SubscribeEvent; | ||
import cpw.mods.fml.common.gameevent.PlayerEvent; | import cpw.mods.fml.common.gameevent.PlayerEvent; | ||
34行目: | 32行目: | ||
@Mod(modid = "SampleMod", name = "SampleMod", version = "1.0", dependencies = "required-after:Forge@[10.12.1.1090,)", useMetadata = true) | @Mod(modid = "SampleMod", name = "SampleMod", version = "1.0", dependencies = "required-after:Forge@[10.12.1.1090,)", useMetadata = true) | ||
public class SampleMod { | public class SampleMod { | ||
− | + | //Player毎のIExtendedEntityPropertiesを保存するMap。ダイヤモンド演算子はJava7以降なので注意。 | |
− | + | private static final Map<String, NBTTagCompound> extendedEntityData = new HashMap<>(); | |
+ | |||
@EventHandler | @EventHandler | ||
− | public void preInit( | + | public void preInit(FMLPostInitializationEvent event) { |
//Messageの登録呼び出し | //Messageの登録呼び出し | ||
PacketHandler.init(); | PacketHandler.init(); | ||
44行目: | 43行目: | ||
@EventHandler | @EventHandler | ||
public void init(FMLInitializationEvent event) { | public void init(FMLInitializationEvent event) { | ||
− | |||
− | |||
//Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent | //Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent | ||
− | MinecraftForge.EVENT_BUS.register( | + | MinecraftForge.EVENT_BUS.register(this); |
− | //FML | + | //FML Eventの登録。PlayerChangedDimensionEventとPlayerRespawnEvent |
− | FMLCommonHandler.instance().bus().register( | + | FMLCommonHandler.instance().bus().register(this); |
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | @SubscribeEvent | ||
/*IExtendedEntityPropertiesを登録する処理を呼び出す*/ | /*IExtendedEntityPropertiesを登録する処理を呼び出す*/ | ||
− | |||
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); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @SubscribeEvent | ||
+ | /*死亡時に呼ばれるイベント。ここで、IExtendedEntityPropertiesを保存する処理を呼び出す*/ | ||
+ | public void onLivingDeathEvent(LivingDeathEvent event) { | ||
+ | if (event.entityLiving instanceof EntityPlayer && !event.entity.worldObj.isRemote) { | ||
+ | NBTTagCompound playerData = new NBTTagCompound(); | ||
+ | (event.entity.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME)).saveNBTData(playerData); | ||
+ | storeEntityData(event.entity.getCommandSenderName(), playerData); | ||
} | } | ||
} | } | ||
80行目: | 70行目: | ||
/*ワールドに入った時に呼ばれるイベント。ここでIExtendedEntityPropertiesを読み込む処理を呼び出す*/ | /*ワールドに入った時に呼ばれるイベント。ここでIExtendedEntityPropertiesを読み込む処理を呼び出す*/ | ||
public void onEntityJoinWorld(EntityJoinWorldEvent event) { | public void onEntityJoinWorld(EntityJoinWorldEvent event) { | ||
− | if (event. | + | if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) { |
− | + | NBTTagCompound playerData = getEntityData(event.entity.getCommandSenderName()); | |
− | + | if (playerData != null) { | |
+ | (event.entity.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME)).loadNBTData(playerData); | ||
+ | } | ||
+ | ((ExtendedPlayerProperties)(event.entity.getExtendedProperties(ExtendedPlayerProperties.EXT_PROP_NAME))).loadProxyData((EntityPlayer)event.entity); | ||
} | } | ||
} | } | ||
− | + | @SubscribeEvent | |
− | // | + | /*リスポーン時に呼ばれるイベント。Serverとの同期を取る*/ |
− | public void | + | public void respawnEvent(PlayerEvent.PlayerRespawnEvent event) { |
− | + | if (!event.player.worldObj.isRemote) { | |
− | if (event. | + | PacketHandler.INSTANCE.sendTo(new MessagePlayerProperties(event.player), (EntityPlayerMP)event.player); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
@SubscribeEvent | @SubscribeEvent | ||
− | /* | + | /*Dimensionを移動した時に呼ばれるイベント。Serverとの同期を取る*/ |
− | public void | + | public void changedDimension(PlayerEvent.PlayerChangedDimensionEvent 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); | ||
} | } | ||
+ | } | ||
+ | |||
+ | /*PlayerのIExtendedEntityPropertiesをMapに保存*/ | ||
+ | public static void storeEntityData(String name, NBTTagCompound compound) { | ||
+ | extendedEntityData.put(name, compound); | ||
+ | } | ||
+ | |||
+ | /*PlayerのIExtendedEntityPropertiesをMapから読み込み*/ | ||
+ | public static NBTTagCompound getEntityData(String name) { | ||
+ | return extendedEntityData.remove(name); | ||
} | } | ||
} | } | ||
133行目: | 126行目: | ||
public final static String EXT_PROP_NAME = "samplePlayerData"; | public final static String EXT_PROP_NAME = "samplePlayerData"; | ||
− | private int sampleInt | + | private int sampleInt; |
− | private double sampleDouble | + | private double sampleDouble; |
− | private boolean sampleBoolean | + | private boolean sampleBoolean; |
− | private String sampleString | + | private String sampleString; |
− | private ItemStack sampleItemStack | + | private ItemStack sampleItemStack; |
private ItemStack[] sampleItemStacks = new ItemStack[10]; | private ItemStack[] sampleItemStacks = new ItemStack[10]; | ||
− | private NBTTagCompound sampleNBTTagCompound | + | private NBTTagCompound sampleNBTTagCompound; |
+ | |||
+ | /*EntityPlayerインスタンスから外部保存時の固有文字列を返す | ||
+ | *1.7ではusername変数が使えないので、コマンド送信時の名前で代用 */ | ||
+ | private static String getSaveKey(EntityPlayer player) { | ||
+ | return player.getCommandSenderName() + ":" + EXT_PROP_NAME; | ||
+ | } | ||
/*EntityPlayerにIExtendedEntityPropertiesを登録。登録文字列はMOD固有のものを割り当てること*/ | /*EntityPlayerにIExtendedEntityPropertiesを登録。登録文字列はMOD固有のものを割り当てること*/ | ||
208行目: | 207行目: | ||
/*初期化メソッド。今のところ使う必要はない。*/ | /*初期化メソッド。今のところ使う必要はない。*/ | ||
public void init(Entity entity, World world) {} | public void init(Entity entity, World world) {} | ||
+ | |||
+ | /*ServerのIExtendedEntityPropertiesを読み込んで、Clientに送信するメソッド*/ | ||
+ | public void loadProxyData(EntityPlayer player) { | ||
+ | ExtendedPlayerProperties playerData = ExtendedPlayerProperties.get(player); | ||
+ | NBTTagCompound savedData = SampleMod.getEntityData(getSaveKey(player)); | ||
+ | if (savedData != null) { playerData.loadNBTData(savedData); } | ||
+ | PacketHandler.INSTANCE.sendTo(new MessagePlayerProperties(player), (EntityPlayerMP)player); | ||
+ | } | ||
/*以降、各変数のGetterおよびSetter。 | /*以降、各変数のGetterおよびSetter。 | ||
269行目: | 276行目: | ||
this.sampleNBTTagCompound = sampleNBTTagCompound; | this.sampleNBTTagCompound = sampleNBTTagCompound; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
330行目: | 298行目: | ||
* 第三引数:登録番号。255個まで | * 第三引数:登録番号。255個まで | ||
* 第四引数:ClientとServerのどちらに送るか。送り先*/ | * 第四引数:ClientとServerのどちらに送るか。送り先*/ | ||
− | INSTANCE.registerMessage( | + | INSTANCE.registerMessage(MessagePlayerProperties.class, MessagePlayerProperties.class, 0, Side.CLIENT); |
− | |||
} | } | ||
} | } | ||
342行目: | 309行目: | ||
import cpw.mods.fml.common.network.ByteBufUtils; | import cpw.mods.fml.common.network.ByteBufUtils; | ||
import cpw.mods.fml.common.network.simpleimpl.IMessage; | import cpw.mods.fml.common.network.simpleimpl.IMessage; | ||
+ | import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; | ||
+ | import cpw.mods.fml.common.network.simpleimpl.MessageContext; | ||
import io.netty.buffer.ByteBuf; | import io.netty.buffer.ByteBuf; | ||
+ | import net.minecraft.client.Minecraft; | ||
import net.minecraft.entity.player.EntityPlayer; | import net.minecraft.entity.player.EntityPlayer; | ||
import net.minecraft.nbt.NBTTagCompound; | import net.minecraft.nbt.NBTTagCompound; | ||
− | public class MessagePlayerProperties implements IMessage { | + | public class MessagePlayerProperties implements IMessage, IMessageHandler<MessagePlayerProperties, IMessage> { |
− | + | private NBTTagCompound data; | |
public MessagePlayerProperties(){} | public MessagePlayerProperties(){} | ||
367行目: | 337行目: | ||
ByteBufUtils.writeTag(buf, data); | ByteBufUtils.writeTag(buf, data); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
@Override | @Override | ||
public IMessage onMessage(MessagePlayerProperties message, MessageContext ctx) { | public IMessage onMessage(MessagePlayerProperties message, MessageContext ctx) { | ||
//Client側にIExtendedEntityPropertiesを渡す。 | //Client側にIExtendedEntityPropertiesを渡す。 | ||
− | ExtendedPlayerProperties.get( | + | ExtendedPlayerProperties.get(Minecraft.getMinecraft().thePlayer).loadNBTData(message.data); |
//REPLYは送らないので、nullを返す。 | //REPLYは送らないので、nullを返す。 | ||
return null; | return null; | ||
394行目: | 348行目: | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==解説== | ==解説== | ||
細かい説明はソースコード内に付記したので、そちらを参照のこと。 | 細かい説明はソースコード内に付記したので、そちらを参照のこと。 | ||
465行目: | 355行目: | ||
ExtendedPlayerProperties.get(playerインスタンス).getSampleInt()という形でデータを呼び出す。<br> | ExtendedPlayerProperties.get(playerインスタンス).getSampleInt()という形でデータを呼び出す。<br> | ||
ExtendedPlayerProperties.get(playerインスタンス).setSampleInt(sample)という形でデータを書き込む。<br> | ExtendedPlayerProperties.get(playerインスタンス).setSampleInt(sample)という形でデータを書き込む。<br> | ||
− | + | 死亡時等でクライアント側のNBTデータが初期化されるので、LivingDeathEventでデータを保存し、EntityJoinWorldEventで、保存したデータを復帰させる。<br> | |
+ | PlayerRespawnEventやPlayerChangedDimensionEventでも同期を取っているが、Forgeのビルドによっては修正されているかもしれないので、適宜確認の上、追加削除を行うこと。 |