提供: Minecraft Modding Wiki
移動先: 案内検索

警告: ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。ログインまたはアカウントを作成すれば、あなたの編集はその利用者名とともに表示されるほか、その他の利点もあります。

この編集を取り消せます。 下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。
最新版 編集中の文章
1行目: 1行目:
 
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}}
 
{{前提MOD|reqmod="Minecraft Forge Universal 10.12.1.1090~"}}
{{ チュートリアル難易度 | difficulty=1|clear=none}}
 
{{ チュートリアルカテゴリー |difficulty=1|type=Player}}
 
 
{{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.FMLPreInitializationEvent;
+
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 {
     @SidedProxy(clientSide = "sampleMod.ClientProxy", serverSide = "sampleMod.CommonProxy")
+
     //Player毎のIExtendedEntityPropertiesを保存するMap。ダイヤモンド演算子はJava7以降なので注意。
    public static CommonProxy proxy;
+
    private static final Map<String, NBTTagCompound> extendedEntityData = new HashMap<>();
 +
 
 
     @EventHandler
 
     @EventHandler
     public void preInit(FMLPreInitializationEvent event) {
+
     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) {
      //二箇所に登録するので、先にインスタンスを生成しておく。
 
        SampleEntityPropertiesEventHandler sampleEntityPropertiesEventHandler = new SampleEntityPropertiesEventHandler();
 
 
         //Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent
 
         //Forge Eventの登録。EntityEvent.EntityConstructingとLivingDeathEventとEntityJoinWorldEvent
         MinecraftForge.EVENT_BUS.register(sampleEntityPropertiesEventHandler);
+
         MinecraftForge.EVENT_BUS.register(this);
         //FML Eventの登録。PlayerRespawnEvent
+
         //FML Eventの登録。PlayerChangedDimensionEventとPlayerRespawnEvent
         FMLCommonHandler.instance().bus().register(sampleEntityPropertiesEventHandler);
+
         FMLCommonHandler.instance().bus().register(this);
 
     }
 
     }
}
 
 
</source>
 
===SampleEntityPropertiesEventHandlerクラス===
 
<source lang = "java">
 
package sampleMod;
 
 
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
 
import cpw.mods.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.IExtendedEntityProperties;
 
import net.minecraftforge.event.entity.EntityEvent;
 
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
 
 
public class SampleEntityPropertiesEventHandler {
 
  
 +
    @SubscribeEvent
 
     /*IExtendedEntityPropertiesを登録する処理を呼び出す*/
 
     /*IExtendedEntityPropertiesを登録する処理を呼び出す*/
    @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);
 +
        }
 +
    }
 +
 +
    @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.world.isRemote && event.entity instanceof EntityPlayer) {
+
         if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) {
             EntityPlayer player = (EntityPlayer)event.entity;
+
             NBTTagCompound playerData = getEntityData(event.entity.getCommandSenderName());
             PacketHandler.INSTANCE.sendToServer(new MessagePlayerJoinInAnnouncement(player));
+
            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
+
    @SubscribeEvent
     //Dimension移動時や、リスポーン時に呼ばれるイベント。古いインスタンスと新しいインスタンスの両方を参照できる。
+
     /*リスポーン時に呼ばれるイベント。Serverとの同期を取る*/
     public void onClonePlayer(net.minecraftforge.event.entity.player.PlayerEvent.Clone event) {
+
     public void respawnEvent(PlayerEvent.PlayerRespawnEvent event) {
        //死亡時に呼ばれてるかどうか
+
         if (!event.player.worldObj.isRemote) {
         if (event.wasDeath) {
+
             PacketHandler.INSTANCE.sendTo(new MessagePlayerProperties(event.player), (EntityPlayerMP)event.player);
            //古いカスタムデータ
 
            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との同期を取る*/
+
     /*Dimensionを移動した時に呼ばれるイベント。Serverとの同期を取る*/
     public void respawnEvent(PlayerEvent.PlayerRespawnEvent event) {
+
     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 = 0;
+
     private int sampleInt;
     private double sampleDouble = 0.0D;
+
     private double sampleDouble;
     private boolean sampleBoolean = false;
+
     private boolean sampleBoolean;
     private String sampleString = "";
+
     private String sampleString;
     private ItemStack sampleItemStack = new ItemStack(Items.apple);
+
     private ItemStack sampleItemStack;
 
     private ItemStack[] sampleItemStacks = new ItemStack[10];
 
     private ItemStack[] sampleItemStacks = new ItemStack[10];
     private NBTTagCompound sampleNBTTagCompound = new NBTTagCompound();
+
     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;
 
     }
 
     }
}
 
 
</source>
 
===CommonProxyクラス===
 
 
<source lang = "java">
 
 
package sampleMod;
 
 
import net.minecraft.entity.player.EntityPlayer;
 
 
public class CommonProxy {
 
 
public EntityPlayer getEntityPlayerInstance() {return null;}
 
 
}
 
 
</source>
 
 
===ClientProxyクラス===
 
 
<source lang = "java">
 
 
package sampleMod;
 
 
import net.minecraft.client.Minecraft;
 
 
import net.minecraft.entity.player.EntityPlayer;
 
 
public class ClientProxy extends CommonProxy {
 
 
@Override
 
 
public EntityPlayer getEntityPlayerInstance() {
 
 
return Minecraft.getMinecraft().thePlayer;
 
 
}
 
 
 
}
 
}
  
313行目: 281行目:
 
===PacketHandlerクラス===
 
===PacketHandlerクラス===
 
<source lang = "java">
 
<source lang = "java">
package sampleMod;
+
package ak.sampleMod;
  
 
import cpw.mods.fml.common.network.NetworkRegistry;
 
import cpw.mods.fml.common.network.NetworkRegistry;
330行目: 298行目:
 
         * 第三引数:登録番号。255個まで
 
         * 第三引数:登録番号。255個まで
 
         * 第四引数:ClientとServerのどちらに送るか。送り先*/
 
         * 第四引数:ClientとServerのどちらに送るか。送り先*/
         INSTANCE.registerMessage(MessagePlayerPropertiesHandler.class, MessagePlayerProperties.class, 0, Side.CLIENT);
+
         INSTANCE.registerMessage(MessagePlayerProperties.class, MessagePlayerProperties.class, 0, Side.CLIENT);
        INSTANCE.registerMessage(MessagePlayerJoinInAnoucementHandler.class, MessagePlayerJoinInAnnouncement.class, 1, Side.SERVER);
 
 
     }
 
     }
 
}
 
}
338行目: 305行目:
 
===MessagePlayerPropertiesクラス===
 
===MessagePlayerPropertiesクラス===
 
<source lang = "java">
 
<source lang = "java">
package sampleMod;
+
package ak.sampleMod;
  
 
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> {
  
     public NBTTagCompound data;
+
     private NBTTagCompound data;
  
 
     public MessagePlayerProperties(){}
 
     public MessagePlayerProperties(){}
367行目: 337行目:
 
         ByteBufUtils.writeTag(buf, data);
 
         ByteBufUtils.writeTag(buf, data);
 
     }
 
     }
}
 
 
</source>
 
 
===MessagePlayerPropertiesHandlerクラス===
 
<source lang = "java">
 
package sampleMod;
 
 
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 net.minecraft.entity.player.EntityPlayer;
 
import net.minecraft.nbt.NBTTagCompound;
 
 
public class MessagePlayerPropertiesHandler implements IMessageHandler<MessagePlayerProperties, IMessage> {
 
  
 
     @Override
 
     @Override
 
     public IMessage onMessage(MessagePlayerProperties message, MessageContext ctx) {
 
     public IMessage onMessage(MessagePlayerProperties message, MessageContext ctx) {
 
         //Client側にIExtendedEntityPropertiesを渡す。
 
         //Client側にIExtendedEntityPropertiesを渡す。
         ExtendedPlayerProperties.get(SampleMod.proxy.getEntityPlayerInstance()).loadNBTData(message.data);
+
         ExtendedPlayerProperties.get(Minecraft.getMinecraft().thePlayer).loadNBTData(message.data);
 
         //REPLYは送らないので、nullを返す。
 
         //REPLYは送らないので、nullを返す。
 
         return null;
 
         return null;
394行目: 348行目:
  
 
</source>
 
</source>
===MessagePlayerJoinInAnnouncementクラス===
 
<source lang = "java">
 
package sampleMod;
 
 
import cpw.mods.fml.common.network.ByteBufUtils;
 
import cpw.mods.fml.common.network.simpleimpl.IMessage;
 
import io.netty.buffer.ByteBuf;
 
import net.minecraft.entity.player.EntityPlayer;
 
 
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;
 
    }
 
 
    public void setUuid(String uuid) {
 
        this.uuid = uuid;
 
    }
 
}
 
</source>
 
===MessagePlayerJoinInAnoucementHandlerクラス===
 
<source lang = "java">
 
package sampleMod;
 
 
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
 
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
 
import net.minecraft.entity.player.EntityPlayer;
 
 
public class MessagePlayerJoinInAnnouncementHandler 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;
 
    }
 
}
 
</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>
死亡時等でカスタムデータが初期化されるので、CloneEventでデータを新しいインスタンスに移行し、EntityJoinWorldEventとRespawnEventで、クライアント側にデータを送って同期させている。
+
死亡時等でクライアント側のNBTデータが初期化されるので、LivingDeathEventでデータを保存し、EntityJoinWorldEventで、保存したデータを復帰させる。<br>
 +
PlayerRespawnEventやPlayerChangedDimensionEventでも同期を取っているが、Forgeのビルドによっては修正されているかもしれないので、適宜確認の上、追加削除を行うこと。

Minecraft Modding Wikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細はMinecraft Modding Wiki:著作権を参照)。 著作権保護されている作品は、許諾なしに投稿しないでください!

このページを編集するには、下記の確認用の質問に回答してください (詳細):

取り消し 編集の仕方 (新しいウィンドウで開きます)