提供: Minecraft Modding Wiki
移動先: 案内検索
(ページが最後まで表示されないときについて)
(サンプルをなるべくコンパクトになるように変更し、解説もソースコード内のコメントに移動してできるだけ行数を減らしました(一時ページが最後まで表示されない事があったため))
9行目: 9行目:
 
*IPeripheralの実装
 
*IPeripheralの実装
 
*Turtle Upgradeの外観(独自テクスチャ・モデル)の実装
 
*Turtle Upgradeの外観(独自テクスチャ・モデル)の実装
 
'''※ページが最後まで表示されないときは上部メニューの「履歴」から最新版を選択して見てください。'''
 
  
 
=== ソースコード ===
 
=== ソースコード ===
[[ComputerCraft_API/1.76/ツールタイプTurtleの追加|MC1.8 ツールタイプTurtleの追加]]」や「[[ComputerCraft_API/1.76/周辺機器の追加|MC1.8 周辺機器の追加]]」の解説を元にして、変更部分のみを解説します。<br>
+
Turtle Upgradeの追加については「[[ComputerCraft_API/1.76/ツールタイプTurtleの追加|MC1.8 ツールタイプTurtleの追加]]」を、周辺機器の実装については「[[ComputerCraft_API/1.76/周辺機器の追加|MC1.8 周辺機器の追加]]」を合わせて参照してください。
  
 
==== SampleUpgradeCore.java ====
 
==== SampleUpgradeCore.java ====
 +
Modのコアとなるクラス
 
<source lang = "java">
 
<source lang = "java">
 
package mods.sample.upgrade;
 
package mods.sample.upgrade;
  
 +
import mods.sample.upgrade.client.ClientEventHandler;
 +
import net.minecraftforge.common.MinecraftForge;
 
import net.minecraftforge.fml.common.Mod;
 
import net.minecraftforge.fml.common.Mod;
 
import net.minecraftforge.fml.common.Mod.EventHandler;
 
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.SidedProxy;
 
 
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
 
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
 
import dan200.computercraft.api.ComputerCraftAPI;
 
import dan200.computercraft.api.ComputerCraftAPI;
35行目: 35行目:
 
public static final String MOD_NAME = "Sample Upgrade Mod";
 
public static final String MOD_NAME = "Sample Upgrade Mod";
 
public static final String MOD_VERSION = "1.0";
 
public static final String MOD_VERSION = "1.0";
public static final String MOD_DEPENDENCIES = "after:ComputerCraft";
+
public static final String MOD_DEPENDENCIES = "required-after:ComputerCraft"; // 前提MODとしてComputerCraftを要求
public static final String MOD_ACCEPTED_MC_VERSIONS = "[1.8,1.8.9]";
+
public static final String MOD_ACCEPTED_MC_VERSIONS = "[1.8,1.8.9]"; // Minecraft 1.8~1.8.9でのみ起動可能
 
 
@SidedProxy(clientSide = "mods.sample.upgrade.client.ClientProxy", serverSide = "mods.sample.upgrade.CommonProxy")
 
public static CommonProxy proxy;
 
  
 
@EventHandler
 
@EventHandler
 
public void init(FMLInitializationEvent event) {
 
public void init(FMLInitializationEvent event) {
proxy.registerEventHandlers();
+
// Turtle Upgradeの登録
 
ComputerCraftAPI.registerTurtleUpgrade(new TurtleSample());
 
ComputerCraftAPI.registerTurtleUpgrade(new TurtleSample());
}
 
 
}
 
</source>
 
 
==== CommonProxy.java ====
 
<source lang = "java">
 
package mods.sample.upgrade;
 
 
import java.util.Set;
 
 
import net.minecraft.util.ResourceLocation;
 
import net.minecraftforge.fml.relauncher.Side;
 
 
public class CommonProxy {
 
 
public Side getSide() {
 
return Side.SERVER;
 
}
 
 
public void registerEventHandlers() {
 
 
}
 
 
public void registerTextureLocation(String domain, String path) {
 
  
}
+
if (event.getSide().isClient()) { // クライアント限定の処理
 
+
// クライアントイベント受信クラスの登録
public Set<ResourceLocation> getTextureLocations() {
+
MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
return null;
+
}
}
 
 
 
public String loadModelLocation(String domain, String path) {
 
return null;
 
}
 
 
 
public Set<ResourceLocation> getModelLocations() {
 
return null;
 
}
 
 
 
}
 
</source>
 
 
 
==== ClientProxy.java ====
 
<source lang = "java">
 
package mods.sample.upgrade.client;
 
 
 
import java.util.HashSet;
 
import java.util.Set;
 
 
 
import mods.sample.upgrade.CommonProxy;
 
import net.minecraft.client.resources.model.ModelResourceLocation;
 
import net.minecraft.util.ResourceLocation;
 
import net.minecraftforge.common.MinecraftForge;
 
import net.minecraftforge.fml.relauncher.Side;
 
 
 
public class ClientProxy extends CommonProxy {
 
 
 
private Set<ResourceLocation> textureLocations = new HashSet<ResourceLocation>();
 
private Set<ResourceLocation> modelLocations = new HashSet<ResourceLocation>();
 
 
 
@Override
 
public Side getSide() {
 
return Side.CLIENT;
 
}
 
 
 
@Override
 
public void registerEventHandlers() {
 
MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
 
}
 
 
 
@Override
 
public void registerTextureLocation(String domain, String path) {
 
ResourceLocation location = new ResourceLocation(domain, path);
 
textureLocations.add(location);
 
}
 
 
 
@Override
 
public Set<ResourceLocation> getTextureLocations() {
 
return textureLocations;
 
}
 
 
 
@Override
 
public String loadModelLocation(String domain, String path) {
 
ResourceLocation location = new ResourceLocation(domain, path);
 
modelLocations.add(location);
 
return (new ModelResourceLocation(location, "inventory")).toString();
 
}
 
 
 
@Override
 
public Set<ResourceLocation> getModelLocations() {
 
return modelLocations;
 
 
}
 
}
  
143行目: 53行目:
  
 
==== ClientEventHandler.java ====
 
==== ClientEventHandler.java ====
 +
各種クライアントeventを受信するためのクラス<br />
 +
Turtle Upgradeの外見であるテクスチャとモデルを登録します。
 
<source lang = "java">
 
<source lang = "java">
 
package mods.sample.upgrade.client;
 
package mods.sample.upgrade.client;
  
 
import java.io.IOException;
 
import java.io.IOException;
import java.util.Set;
 
  
 
import mods.sample.upgrade.SampleUpgradeCore;
 
import mods.sample.upgrade.SampleUpgradeCore;
167行目: 78行目:
 
@SubscribeEvent
 
@SubscribeEvent
 
public void onTextureStitchEvent(TextureStitchEvent.Pre event) {
 
public void onTextureStitchEvent(TextureStitchEvent.Pre event) {
registerTextures(event);
+
// 使用するテクスチャの登録
 +
event.map.registerSprite(new ResourceLocation(SampleUpgradeCore.MOD_ID, "blocks/sample_upgrade"));
 
}
 
}
  
 
@SubscribeEvent
 
@SubscribeEvent
 
public void onModelBakeEvent(ModelBakeEvent event) {
 
public void onModelBakeEvent(ModelBakeEvent event) {
bakeModels(event);
+
ResourceLocation modelLeft  = new ResourceLocation(SampleUpgradeCore.MOD_ID, "block/turtle_sample_left");
}
+
ResourceLocation modelRight = new ResourceLocation(SampleUpgradeCore.MOD_ID, "block/turtle_sample_right");
 
 
private void registerTextures(TextureStitchEvent.Pre event) {
 
Set<ResourceLocation> textureLocations = SampleUpgradeCore.proxy.getTextureLocations();
 
 
 
if (textureLocations == null) {
 
return;
 
}
 
  
for (ResourceLocation location : textureLocations) {
+
// 使用するモデルの登録
event.map.registerSprite(location);
+
loadModel(event, modelLeft);
}
+
loadModel(event, modelRight);
 
}
 
}
  
private void bakeModels(ModelBakeEvent event) {
+
// モデルをロードしbakeして登録
Set<ResourceLocation> modelLocations = SampleUpgradeCore.proxy.getModelLocations();
+
private void loadModel(ModelBakeEvent event, ResourceLocation location) {
 +
try {
 +
IModel model = event.modelLoader.getModel(location);
 +
IBakedModel bakedModel = model.bake(model.getDefaultState(),
 +
DefaultVertexFormats.ITEM,
 +
new Function<ResourceLocation, TextureAtlasSprite>() {
  
if (modelLocations == null) {
+
@Override
return;
+
public TextureAtlasSprite apply(ResourceLocation location) {
}
+
Minecraft mc = Minecraft.getMinecraft();
 +
return mc.getTextureMapBlocks().getAtlasSprite(location.toString());
 +
}
  
for (ResourceLocation location : modelLocations) {
+
});
try {
+
ModelResourceLocation modelLocation = new ModelResourceLocation(location, "inventory");
IModel model = event.modelLoader.getModel(location);
+
event.modelRegistry.putObject(modelLocation, bakedModel);
IBakedModel bakedModel = model.bake(model.getDefaultState(),
+
} catch (IOException e) {
DefaultVertexFormats.ITEM,
+
e.printStackTrace();
new Function<ResourceLocation, TextureAtlasSprite>() {
 
 
 
@Override
 
public TextureAtlasSprite apply(ResourceLocation location) {
 
Minecraft mc = Minecraft.getMinecraft();
 
return mc.getTextureMapBlocks().getAtlasSprite(location.toString());
 
}
 
 
 
});
 
ModelResourceLocation modelLocation = new ModelResourceLocation(location, "inventory");
 
event.modelRegistry.putObject(modelLocation, bakedModel);
 
} catch (IOException e) {
 
e.printStackTrace();
 
}
 
 
}
 
}
 
}
 
}
220行目: 118行目:
  
 
==== TurtleSample.java ====
 
==== TurtleSample.java ====
 +
Turtle Upgradeを定義するクラス
 
<source lang = "java">
 
<source lang = "java">
 
package mods.sample.upgrade;
 
package mods.sample.upgrade;
233行目: 132行目:
 
import net.minecraft.util.EnumFacing;
 
import net.minecraft.util.EnumFacing;
 
import net.minecraft.util.ResourceLocation;
 
import net.minecraft.util.ResourceLocation;
 +
import net.minecraftforge.fml.common.FMLCommonHandler;
 
import net.minecraftforge.fml.relauncher.Side;
 
import net.minecraftforge.fml.relauncher.Side;
 
import net.minecraftforge.fml.relauncher.SideOnly;
 
import net.minecraftforge.fml.relauncher.SideOnly;
248行目: 148行目:
 
public class TurtleSample implements ITurtleUpgrade {
 
public class TurtleSample implements ITurtleUpgrade {
  
 +
// Turtle UpgradeのID
 
private ResourceLocation upgradeID = new ResourceLocation(SampleUpgradeCore.MOD_ID, "sample");
 
private ResourceLocation upgradeID = new ResourceLocation(SampleUpgradeCore.MOD_ID, "sample");
 +
// Turtle Upgradeの装着に必要なアイテム。ここではバニラブロックの石(焼石)
 
private ItemStack upgradeItem = new ItemStack(Blocks.stone);
 
private ItemStack upgradeItem = new ItemStack(Blocks.stone);
  
 +
// Turtle UpgradeのモデルのModelResourceLocation.クライアント側でのみ参照される
 
@SideOnly(Side.CLIENT)
 
@SideOnly(Side.CLIENT)
 
private ModelResourceLocation modelLeft;
 
private ModelResourceLocation modelLeft;
257行目: 160行目:
  
 
public TurtleSample() {
 
public TurtleSample() {
CommonProxy proxy = SampleUpgradeCore.proxy;
+
if (FMLCommonHandler.instance().getSide().isClient()) { // クライアント限定の処理
 
 
if (proxy.getSide().isClient()) {
 
 
String modid = SampleUpgradeCore.MOD_ID;
 
String modid = SampleUpgradeCore.MOD_ID;
proxy.registerTextureLocation(modid, "blocks/sample_upgrade");
+
// 前もってgetModelで使用するモデルのModelResourceLocationを用意
modelLeft = new ModelResourceLocation(proxy.loadModelLocation(modid, "block/turtle_sample_left"));
+
modelLeft = new ModelResourceLocation(new ResourceLocation(modid, "block/turtle_sample_left"), "inventory");
modelRight = new ModelResourceLocation(proxy.loadModelLocation(modid, "block/turtle_sample_right"));
+
modelRight = new ModelResourceLocation(new ResourceLocation(modid, "block/turtle_sample_right"), "inventory");
 
}
 
}
 
}
 
}
269行目: 170行目:
 
@Override
 
@Override
 
public ResourceLocation getUpgradeID() {
 
public ResourceLocation getUpgradeID() {
 +
// Turtle UpgradeのIDをResourceLocationで指定
 +
// 他のTurtle Upgradeと重複しないようにする
 
return upgradeID;
 
return upgradeID;
 
}
 
}
274行目: 177行目:
 
@Override
 
@Override
 
public int getLegacyUpgradeID() {
 
public int getLegacyUpgradeID() {
 +
// Minecraft 1.7.10やそれ以前のワールドからTurtle Upgradeを引き継ぐ場合は、そのTurtle Upgradeと同じIDを返す
 +
// 引き継ぐ必要がない場合は-1を返す
 
return -1;
 
return -1;
 
}
 
}
279行目: 184行目:
 
@Override
 
@Override
 
public String getUnlocalisedAdjective() {
 
public String getUnlocalisedAdjective() {
 +
// Turtle Upgradeを装着したTurtleのアイテム名に付加される形容詞を返す
 +
// この例では"Sample Turtle"になる
 
return "Sample";
 
return "Sample";
 
}
 
}
284行目: 191行目:
 
@Override
 
@Override
 
public TurtleUpgradeType getType() {
 
public TurtleUpgradeType getType() {
 +
// Turtle Upgradeの種類の指定
 +
// 周辺機器タイプを指定
 
return TurtleUpgradeType.Peripheral;
 
return TurtleUpgradeType.Peripheral;
 
}
 
}
289行目: 198行目:
 
@Override
 
@Override
 
public ItemStack getCraftingItem() {
 
public ItemStack getCraftingItem() {
 +
// Turtle Upgradeの装着に必要なアイテムを返す
 
return upgradeItem;
 
return upgradeItem;
 
}
 
}
294行目: 204行目:
 
@Override
 
@Override
 
public IPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) {
 
public IPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) {
 +
// 周辺機器クラスのインスタンスを生成して返す
 
return new SamplePeripheral(turtle, side);
 
return new SamplePeripheral(turtle, side);
 
}
 
}
300行目: 211行目:
 
public TurtleCommandResult useTool(ITurtleAccess turtle, TurtleSide side,
 
public TurtleCommandResult useTool(ITurtleAccess turtle, TurtleSide side,
 
TurtleVerb verb, EnumFacing direction) {
 
TurtleVerb verb, EnumFacing direction) {
 +
// ツールタイプTurtle Upgradeの処理
 +
// 周辺機器タイプでは何もしない
 
return null;
 
return null;
 
}
 
}
309行目: 222行目:
 
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
 
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
  
 +
// Turtle Upgradeの装着方向に応じたモデルを取得して返す
 +
// このモデルはTurtleのTileEntitySpecialRenderer内で描画される
 
if (side == TurtleSide.Left) {
 
if (side == TurtleSide.Left) {
 
return Pair.of(modelManager.getModel(modelLeft), null);
 
return Pair.of(modelManager.getModel(modelLeft), null);
318行目: 233行目:
 
@Override
 
@Override
 
public void update(ITurtleAccess turtle, TurtleSide side) {
 
public void update(ITurtleAccess turtle, TurtleSide side) {
 
+
// Tick毎の処理
 
}
 
}
  
325行目: 240行目:
  
 
==== SamplePeripheral.java ====
 
==== SamplePeripheral.java ====
 +
周辺機器を定義するクラス
 
<source lang = "java">
 
<source lang = "java">
 
package mods.sample.upgrade;
 
package mods.sample.upgrade;
341行目: 257行目:
  
 
public SamplePeripheral(ITurtleAccess turtle, TurtleSide side) {
 
public SamplePeripheral(ITurtleAccess turtle, TurtleSide side) {
 +
// 装着されたTurtleのTurtleAccessとTurtleSideを保存
 
turtleAccess = turtle;
 
turtleAccess = turtle;
 
turtleSide = side;
 
turtleSide = side;
 
}
 
}
 +
 +
/* 以下は周辺機器ブロックと同様に実装 */
  
 
@Override
 
@Override
368行目: 287行目:
 
@Override
 
@Override
 
public void attach(IComputerAccess computer) {
 
public void attach(IComputerAccess computer) {
 
+
// 装着されたTurtleが起動したとき、またはコマンドでTurtleに装着されたときに呼び出される
 
}
 
}
  
 
@Override
 
@Override
 
public void detach(IComputerAccess computer) {
 
public void detach(IComputerAccess computer) {
 
+
// 装着されたTurtleが終了したとき、またはコマンドでTurtleから取り外されたときに呼び出される
 
}
 
}
  
 
@Override
 
@Override
 
public boolean equals(IPeripheral other) {
 
public boolean equals(IPeripheral other) {
 +
// 周辺機器が同一のものであるかを返す
 +
// サンプルでは、このクラスのインスタンスで同一Turtleの同一方向に装着されている場合にのみtrueを返している
 
if ((other != null) && (other instanceof SamplePeripheral)) {
 
if ((other != null) && (other instanceof SamplePeripheral)) {
return other == this;
+
SamplePeripheral other1 = (SamplePeripheral)other;
 +
return (other1.turtleAccess == this.turtleAccess) && (other1.turtleSide == this.turtleSide);
 
}
 
}
  
389行目: 311行目:
  
 
==== turtle_sample_left.json ====
 
==== turtle_sample_left.json ====
 +
Turtle UpgradeをTurtleの左側に装着したときのモデル<br />
 
assets\sampleupgrademod\models\block ディレクトリに設置します。
 
assets\sampleupgrademod\models\block ディレクトリに設置します。
 
<source lang = "javascript">
 
<source lang = "javascript">
398行目: 321行目:
 
}
 
}
 
</source>
 
</source>
 +
※今回はComputerCraft本体で定義されている物を流用しています。
  
 
==== turtle_sample_right.json ====
 
==== turtle_sample_right.json ====
 +
Turtle UpgradeをTurtleの右側に装着したときのモデル<br />
 
assets\sampleupgrademod\models\block ディレクトリに設置します。
 
assets\sampleupgrademod\models\block ディレクトリに設置します。
 
<source lang = "javascript">
 
<source lang = "javascript">
409行目: 334行目:
 
}
 
}
 
</source>
 
</source>
 +
※今回はComputerCraft本体で定義されている物を流用しています。
  
 
==== sample_upgrade.png ====
 
==== sample_upgrade.png ====
 +
Turtle Upgradeのテクスチャ<br />
 
assets\sampleupgrademod\textures\blocks ディレクトリに設置します。
 
assets\sampleupgrademod\textures\blocks ディレクトリに設置します。
  
適当なテクスチャファイル(16x16の画像など)を各自で用意してください。
+
※サイズ16x16などの適当なテクスチャファイルを各自で用意してください。
 
 
 
 
=== 解説 ===
 
==== SampleUpgradeCore.java ====
 
Modのコアとなるクラス
 
 
 
*プロキシクラスの指定
 
<source lang = "java">
 
@SidedProxy(clientSide = "mods.sample.upgrade.client.ClientProxy", serverSide = "mods.sample.upgrade.CommonProxy")
 
public static CommonProxy proxy;
 
</source>
 
Turtle Upgradeのモデルに関する処理はクライアント側でのみ行うため、今回の例では[[プロキシシステムについて|プロキシシステム]]を利用しています。
 
 
 
*Event受信クラスの登録
 
<source lang = "java">
 
proxy.registerEventHandlers();
 
</source>
 
プロキシを介して登録用メソッドを呼び出し、クライアント側でのみ登録されるようにしています。
 
 
 
==== CommonProxy.java ====
 
サーバー側でのみ呼び出されるプロキシクラス
 
 
 
*getSide()
 
<source lang = "java">
 
public Side getSide() {
 
return Side.SERVER;
 
}
 
</source>
 
現在の処理がサーバー側かクライアント側かを判別するためのメソッドを用意します。<br>
 
こちらはサーバー側のときのみ呼び出されます。
 
 
 
*テクスチャ・モデル関連のメソッド
 
 
 
クライアント側のプロキシクラスでオーバーライドするためのメソッドを実装します。<br>
 
クライアント側での処理がメインとなるため、こちらでは何もしません。
 
 
 
==== ClientProxy.java ====
 
クライアント側でのみ呼び出されるプロキシクラス
 
 
 
*getSide()
 
<source lang = "java">
 
@Override
 
public Side getSide() {
 
return Side.CLIENT;
 
}
 
</source>
 
現在の処理がサーバー側かクライアント側かを判別するためのメソッドをオーバーライドで用意します。<br>
 
こちらはクライアント側のときのみ呼び出されます。
 
 
 
*クライアントevent受信クラスの登録
 
<source lang = "java">
 
@Override
 
public void registerEventHandlers() {
 
MinecraftForge.EVENT_BUS.register(new ModelBakeEventHandler());
 
}
 
</source>
 
クライアントevent受信クラス(ClientEventHandler)のインスタンスをForgeに登録します。
 
 
 
*テクスチャ関連のフィールドやメソッド
 
<source lang = "java">
 
private Set<ResourceLocation> textureLocations = new HashSet<ResourceLocation>();
 
 
 
@Override
 
public void registerTextureLocation(String domain, String path) {
 
ResourceLocation location = new ResourceLocation(domain, path);
 
textureLocations.add(location);
 
}
 
 
 
@Override
 
public Set<ResourceLocation> getTextureLocations() {
 
return textureLocations;
 
}
 
</source>
 
今回の例ではTurtle Upgradeの独自テクスチャをTextureStitchEvent.Preイベントでまとめて登録するために画像ファイルの位置を前もって登録するためのリストとメソッドを用意しています。<br>
 
画像ファイルの位置は各ITurtleUpgrade実装クラスのコンストラクタでregisterTextureLocationメソッドを呼び出して登録します。
 
 
 
*モデル関連のフィールドやメソッド
 
<source lang = "java">
 
private Set<ResourceLocation> modelLocations = new HashSet<ResourceLocation>();
 
 
 
@Override
 
public String loadModelLocation(String domain, String path) {
 
ResourceLocation location = new ResourceLocation(domain, path);
 
modelLocations.add(location);
 
return (new ModelResourceLocation(location, "inventory")).toString();
 
}
 
 
 
@Override
 
public Set<ResourceLocation> getModelLocations() {
 
return modelLocations;
 
}
 
</source>
 
今回の例ではTurtle Upgradeの各モデルをModelBakeEventでまとめてbakeするためにモデルのJSONファイルの位置を前もって登録するためのリストとメソッドを用意しています。<br>
 
モデルの位置は各ITurtleUpgrade実装クラスのコンストラクタでloadModelLocationメソッドを呼び出して登録します。
 
 
 
==== ClientEventHandler.java ====
 
各種クライアントeventを受信するためのクラス
 
 
 
*TextureStitchEvent.Preイベント
 
<source lang = "java">
 
@SubscribeEvent
 
public void onTextureStitchEvent(TextureStitchEvent.Pre event) {
 
registerTextures(event);
 
}
 
</source>
 
このメソッドはTextureStitchEvent.Preイベント発生時に呼び出されます。<br>
 
ここでは自前のテクスチャ画像をテクスチャマップに登録するために、registerTextures()を呼び出しています。
 
 
 
*独自テクスチャの登録
 
<source lang = "java">
 
private void registerTextures(TextureStitchEvent.Pre event) {
 
Set<ResourceLocation> textureLocations = SampleUpgradeCore.proxy.getTextureLocations();
 
 
 
if (textureLocations == null) {
 
return;
 
}
 
 
 
for (ResourceLocation location : textureLocations) {
 
event.map.registerSprite(location);
 
}
 
}
 
</source>
 
ClientProxy.textureLocationsに登録されたテクスチャファイルをすべてテクスチャマップに登録します。<br>
 
これにより、自前の画像ファイルがテクスチャとして使用できるようになります。
 
 
 
*ModelBakeEvent
 
<source lang = "java">
 
@SubscribeEvent
 
public void onModelBakeEvent(ModelBakeEvent event) {
 
bakeModels(event);
 
}
 
</source>
 
このメソッドはModelBakeEvent発生時に呼び出されます。<br>
 
ここではモデルをbakeしてmodelRegistryへ登録するため、bakeModels()を呼び出しています。
 
 
 
*モデルのbakeと登録
 
<source lang = "java">
 
private void bakeModels(ModelBakeEvent event) {
 
Set<ResourceLocation> modelLocations = SampleUpgradeCore.proxy.getModelLocations();
 
 
 
if (modelLocations == null) {
 
return;
 
}
 
 
 
for (ResourceLocation location : modelLocations) {
 
try {
 
IModel model = event.modelLoader.getModel(location);
 
IBakedModel bakedModel = model.bake(model.getDefaultState(),
 
DefaultVertexFormats.ITEM,
 
new Function<ResourceLocation, TextureAtlasSprite>() {
 
 
 
@Override
 
public TextureAtlasSprite apply(ResourceLocation location) {
 
Minecraft mc = Minecraft.getMinecraft();
 
return mc.getTextureMapBlocks().getAtlasSprite(location.toString());
 
}
 
 
 
});
 
ModelResourceLocation modelLocation = new ModelResourceLocation(location, "inventory");
 
event.modelRegistry.putObject(modelLocation, bakedModel);
 
} catch (Exception e) {
 
e.printStackTrace();
 
}
 
}
 
}
 
</source>
 
ClientProxy.modelLocationsに登録されたモデルをすべてbakeし、modelRegistryに登録します。<br>
 
ここで登録したbake済みモデルは、MinecraftのModelManagerからgetModel(ModelResourceLocation)メソッドで取得できるようになります。(後述のTurtleSample.getModel()の解説を参照)
 
 
 
==== TurtleSample.java ====
 
Turtle Upgradeの機能を定義するクラス
 
 
 
*コンストラクタ
 
<source lang = "java">
 
@SideOnly(Side.CLIENT)
 
private ModelResourceLocation modelLeft;
 
@SideOnly(Side.CLIENT)
 
private ModelResourceLocation modelRight;
 
 
 
public TurtleSample() {
 
CommonProxy proxy = SampleUpgradeCore.proxy;
 
 
 
if (proxy.getSide().isClient()) {
 
String modid = SampleUpgradeCore.MOD_ID;
 
proxy.registerTextureLocation(modid, "blocks/sample_upgrade");
 
modelLeft = new ModelResourceLocation(proxy.loadModelLocation(modid, "block/turtle_sample_left"));
 
modelRight = new ModelResourceLocation(proxy.loadModelLocation(modid, "block/turtle_sample_right"));
 
}
 
}
 
</source>
 
proxy.getSide()の返値で処理を分岐して、TurtleUpgradeで使用するテクスチャやモデル関連の処理がクライアント側でのみ実行されるようにしています。
 
 
 
*TurtleUpgradeで使用するテクスチャファイル位置の登録
 
<source lang = "java">
 
proxy.registerTextureLocation(modid, "blocks/sample_upgrade");
 
</source>
 
今回は自前の画像ファイルをテクスチャとして使用するので、プロキシクラスで用意したregisterTextureLocationメソッドをコンストラクタで呼び出して(クライアント側でのみ)Turtle Upgradeのテクスチャファイルの位置を登録します。<br>
 
ちなみにこの工程は他所で登録されているテクスチャを流用するときには不要です。
 
 
 
*TurtleUpgradeで使用するモデルャファイル位置の登録
 
<source lang = "java">
 
modelLeft = new ModelResourceLocation(proxy.loadModelLocation(modid, "block/turtle_sample_left"));
 
modelRight = new ModelResourceLocation(proxy.loadModelLocation(modid, "block/turtle_sample_right"));
 
</source>
 
プロキシクラスで用意したloadModelLocationメソッドをコンストラクタで呼び出して(クライアント側でのみ)Turtle UpgradeのモデルのJSONファイルの位置を登録します。<br>
 
戻り値はgetModel()で使うためModelResourceLocation形式でメンバフィールドに保存します。
 
 
 
*getType()
 
<source lang = "java">
 
@Override
 
public TurtleUpgradeType getType() {
 
return TurtleUpgradeType.Peripheral;
 
}
 
</source>
 
Turtle Upgradeの種類をTurtleUpgradeTypeの値で指定します。
 
 
 
今回は周辺機器タイプなので TurtleUpgradeType.Peripheral を返しています。
 
 
 
*getCraftingItem()
 
<source lang = "java">
 
private ItemStack upgradeItem = new ItemStack(Blocks.stone);
 
 
 
@Override
 
public ItemStack getCraftingItem() {
 
return upgradeItem;
 
}
 
</source>
 
Turtle Upgradeを装着するためのアイテムをItemStackで指定します。
 
 
 
今回はバニラブロックの石(焼石)を指定していますが、modで追加した独自のブロックやアイテムも同様に指定できます。
 
 
 
*createPeripheral()
 
<source lang = "java">
 
@Override
 
public IPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) {
 
return new SamplePeripheral(turtle, side);
 
}
 
</source>
 
周辺機器タイプのTurtle Upgradeの場合、周辺機器の動作を定義したIPeripheral実装クラスのインスタンスを返します。
 
 
 
IPeripheral実装クラスにはコンストラクタの引数でTurtle Upgradeの情報を渡しています。
 
 
 
*useTool()
 
<source lang = "java">
 
@Override
 
public TurtleCommandResult useTool(ITurtleAccess turtle, TurtleSide side,
 
TurtleVerb verb, EnumFacing direction) {
 
return null;
 
}
 
</source>
 
周辺機器タイプのTurtle Upgradeでは呼び出されることは無いため、単にnullを返しています。
 
 
 
*getModel()
 
<source lang = "java">
 
@Override
 
@SideOnly(Side.CLIENT)
 
public Pair<IBakedModel, Matrix4f> getModel(ITurtleAccess turtle, TurtleSide side) {
 
Minecraft mc = Minecraft.getMinecraft();
 
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
 
 
 
if (side == TurtleSide.Left) {
 
return Pair.of(modelManager.getModel(modelLeft), null);
 
} else {
 
return Pair.of(modelManager.getModel(modelRight), null);
 
}
 
}
 
</source>
 
Turtleに装着されたTurtle Upgradeの外観を指定します。<br>
 
戻り値はPair<IBakedModel, Matrix4f>で、IBakedModelがモデル、Matrix4fがモデルを変形する座標変換行列です。
 
 
 
今回はCC1.76の実装を参考にしています。<br>
 
コンストラクタで登録してModelBakeEventでbakeされたモデルをModelManager.getModel()で取得して返しています。<br>
 
Turtle Upgradeを装着した位置がTurtleの左側ならば左用のモデルを、右側ならば右用のモデルを描画するようにしています。
 
 
 
*update()
 
<source lang = "java">
 
@Override
 
public void update(ITurtleAccess turtle, TurtleSide side) {
 
 
}
 
</source>
 
Turtle UpgradeがTurtleに装着されている間、毎tick呼び出されます。<br>
 
ロードされているワールド上で装着されている数だけ呼び出されますが、各パラメータでどれに対する呼び出しなのかが判別が可能です。<br>
 
また、サーバ側とクライアント側でそれぞれ別に呼び出されますが、どちら側の呼び出しなのかはturtle.getWorld().isRemoteの値で判別可能です。<br>
 
ITurtleAccess.getPeripheral()で装着されている周辺機器Upgradeの周辺機器クラスのインスタンスを取得できます。<br>
 
turtle.getUpgradeNBTData()で読み書き可能なNBTTagCompoundを取得できます。このNBTTagCompoundはTurtleに記録され、ゲームを終了しても消去されません(Turtle Upgradeを取り外したりTurtleが破壊されると消えます)。
 
 
 
今回は何もしていません。
 
 
 
==== SamplePeripheral.java ====
 
周辺機器を定義するクラス
 
 
 
*装着されたTurtleの情報取得・保存
 
<source lang = "java">
 
private final ITurtleAccess turtleAccess;
 
private final TurtleSide turtleSide;
 
 
 
public SamplePeripheral(ITurtleAccess turtle, TurtleSide side) {
 
turtleAccess = turtle;
 
turtleSide = side;
 
}
 
</source>
 
周辺機器でTurtle Upgradeの情報を利用したい場合、コンストラクタで受け取って周辺機器側で保存しておきます。<br>
 
 
 
==== turtle_sample_left.json ====
 
Turtleの左側に装着された時のTurtle Upgradeのモデルを指定するJSONファイルです。<br>
 
 
 
今回の例では、TurtleSampleのコンストラクタでファイル位置を "sampleupgrademod:block/turtle_sample_left" と指定したため、assets\sampleupgrademod\models\block ディレクトリに設置します。
 
 
 
<source lang = "javascript">
 
"parent": "computercraft:block/turtle_upgrade_base_left",
 
"textures": {
 
"texture": "sampleupgrademod:blocks/sample_upgrade"
 
}
 
</source>
 
モデル自体はComputerCraft本体で定義されている物を流用しており、テクスチャのみ独自に設定しています。
 
 
 
==== turtle_sample_right.json ====
 
Turtleの右側に装着された時のTurtle Upgradeのモデルを指定するJSONファイルです。<br>
 
解説はturtle_sample_left.jsonの項目を参照してください。
 
 
 
==== sample_upgrade.png ====
 
Turtle Upgradeのテクスチャ画像ファイルです。
 
 
 
今回の例では、TurtleSampleのコンストラクタとモデルのJSONファイルでファイル位置を "sampleupgrademod:blocks/sample_upgrade" と指定したため、assets\sampleupgrademod\textures\blocks ディレクトリに設置します。
 

2016年4月16日 (土) 01:02時点における版

ComputerCraft API >

この記事は"Minecraft Forge Universal 10.14.4.x~"及び"ComputerCraft 1.76~"を前提MODとしています。

周辺機器タイプTurtleの追加

周辺機器タイプのTurtle Upgradeを追加します。

  • ITurtleUpgrade(周辺機器タイプ)の実装
  • TurtleUpgradeの登録
  • IPeripheralの実装
  • Turtle Upgradeの外観(独自テクスチャ・モデル)の実装

ソースコード

Turtle Upgradeの追加については「MC1.8 ツールタイプTurtleの追加」を、周辺機器の実装については「MC1.8 周辺機器の追加」を合わせて参照してください。

SampleUpgradeCore.java

Modのコアとなるクラス

package mods.sample.upgrade;

import mods.sample.upgrade.client.ClientEventHandler;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import dan200.computercraft.api.ComputerCraftAPI;

@Mod(	modid = SampleUpgradeCore.MOD_ID,
		name = SampleUpgradeCore.MOD_NAME,
		version = SampleUpgradeCore.MOD_VERSION,
		dependencies = SampleUpgradeCore.MOD_DEPENDENCIES,
		acceptedMinecraftVersions = SampleUpgradeCore.MOD_ACCEPTED_MC_VERSIONS)
public class SampleUpgradeCore {

	public static final String MOD_ID = "sampleupgrademod";
	public static final String MOD_NAME = "Sample Upgrade Mod";
	public static final String MOD_VERSION = "1.0";
	public static final String MOD_DEPENDENCIES = "required-after:ComputerCraft";	// 前提MODとしてComputerCraftを要求
	public static final String MOD_ACCEPTED_MC_VERSIONS = "[1.8,1.8.9]";	// Minecraft 1.8~1.8.9でのみ起動可能

	@EventHandler
	public void init(FMLInitializationEvent event) {
		// Turtle Upgradeの登録
		ComputerCraftAPI.registerTurtleUpgrade(new TurtleSample());

		if (event.getSide().isClient()) {	// クライアント限定の処理
			// クライアントイベント受信クラスの登録
			MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
		}
	}

}

ClientEventHandler.java

各種クライアントeventを受信するためのクラス
Turtle Upgradeの外見であるテクスチャとモデルを登録します。

package mods.sample.upgrade.client;

import java.io.IOException;

import mods.sample.upgrade.SampleUpgradeCore;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

import com.google.common.base.Function;

public class ClientEventHandler {

	@SubscribeEvent
	public void onTextureStitchEvent(TextureStitchEvent.Pre event) {
		// 使用するテクスチャの登録
		event.map.registerSprite(new ResourceLocation(SampleUpgradeCore.MOD_ID, "blocks/sample_upgrade"));
	}

	@SubscribeEvent
	public void onModelBakeEvent(ModelBakeEvent event) {
		ResourceLocation modelLeft  = new ResourceLocation(SampleUpgradeCore.MOD_ID, "block/turtle_sample_left");
		ResourceLocation modelRight = new ResourceLocation(SampleUpgradeCore.MOD_ID, "block/turtle_sample_right");

		// 使用するモデルの登録
		loadModel(event, modelLeft);
		loadModel(event, modelRight);
	}

	// モデルをロードしbakeして登録
	private void loadModel(ModelBakeEvent event, ResourceLocation location) {
		try {
			IModel model = event.modelLoader.getModel(location);
			IBakedModel bakedModel = model.bake(model.getDefaultState(),
					DefaultVertexFormats.ITEM,
					new Function<ResourceLocation, TextureAtlasSprite>() {

						@Override
						public TextureAtlasSprite apply(ResourceLocation location) {
							Minecraft mc = Minecraft.getMinecraft();
							return mc.getTextureMapBlocks().getAtlasSprite(location.toString());
						}

					});
			ModelResourceLocation modelLocation = new ModelResourceLocation(location, "inventory");
			event.modelRegistry.putObject(modelLocation, bakedModel);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

TurtleSample.java

Turtle Upgradeを定義するクラス

package mods.sample.upgrade;

import javax.vecmath.Matrix4f;

import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import org.apache.commons.lang3.tuple.Pair;

import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.TurtleUpgradeType;
import dan200.computercraft.api.turtle.TurtleVerb;

public class TurtleSample implements ITurtleUpgrade {

	// Turtle UpgradeのID
	private ResourceLocation upgradeID = new ResourceLocation(SampleUpgradeCore.MOD_ID, "sample");
	// Turtle Upgradeの装着に必要なアイテム。ここではバニラブロックの石(焼石)
	private ItemStack upgradeItem = new ItemStack(Blocks.stone);

	// Turtle UpgradeのモデルのModelResourceLocation.クライアント側でのみ参照される
	@SideOnly(Side.CLIENT)
	private ModelResourceLocation modelLeft;
	@SideOnly(Side.CLIENT)
	private ModelResourceLocation modelRight;

	public TurtleSample() {
		if (FMLCommonHandler.instance().getSide().isClient()) {	// クライアント限定の処理
			String modid = SampleUpgradeCore.MOD_ID;
			// 前もってgetModelで使用するモデルのModelResourceLocationを用意
			modelLeft  = new ModelResourceLocation(new ResourceLocation(modid, "block/turtle_sample_left"), "inventory");
			modelRight = new ModelResourceLocation(new ResourceLocation(modid, "block/turtle_sample_right"), "inventory");
		}
	}

	@Override
	public ResourceLocation getUpgradeID() {
		// Turtle UpgradeのIDをResourceLocationで指定
		// 他のTurtle Upgradeと重複しないようにする
		return upgradeID;
	}

	@Override
	public int getLegacyUpgradeID() {
		// Minecraft 1.7.10やそれ以前のワールドからTurtle Upgradeを引き継ぐ場合は、そのTurtle Upgradeと同じIDを返す
		// 引き継ぐ必要がない場合は-1を返す
		return -1;
	}

	@Override
	public String getUnlocalisedAdjective() {
		// Turtle Upgradeを装着したTurtleのアイテム名に付加される形容詞を返す
		// この例では"Sample Turtle"になる
		return "Sample";
	}

	@Override
	public TurtleUpgradeType getType() {
		// Turtle Upgradeの種類の指定
		// 周辺機器タイプを指定
		return TurtleUpgradeType.Peripheral;
	}

	@Override
	public ItemStack getCraftingItem() {
		// Turtle Upgradeの装着に必要なアイテムを返す
		return upgradeItem;
	}

	@Override
	public IPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) {
		// 周辺機器クラスのインスタンスを生成して返す
		return new SamplePeripheral(turtle, side);
	}

	@Override
	public TurtleCommandResult useTool(ITurtleAccess turtle, TurtleSide side,
			TurtleVerb verb, EnumFacing direction) {
		// ツールタイプTurtle Upgradeの処理
		// 周辺機器タイプでは何もしない
		return null;
	}

	@Override
	@SideOnly(Side.CLIENT)
	public Pair<IBakedModel, Matrix4f> getModel(ITurtleAccess turtle, TurtleSide side) {
		Minecraft mc = Minecraft.getMinecraft();
		ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();

		// Turtle Upgradeの装着方向に応じたモデルを取得して返す
		// このモデルはTurtleのTileEntitySpecialRenderer内で描画される
		if (side == TurtleSide.Left) {
			return Pair.of(modelManager.getModel(modelLeft), null);
		} else {
			return Pair.of(modelManager.getModel(modelRight), null);
		}
	}

	@Override
	public void update(ITurtleAccess turtle, TurtleSide side) {
		// Tick毎の処理
	}

}

SamplePeripheral.java

周辺機器を定義するクラス

package mods.sample.upgrade;

import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleSide;

public class SamplePeripheral implements IPeripheral {

	private final ITurtleAccess turtleAccess;
	private final TurtleSide turtleSide;

	public SamplePeripheral(ITurtleAccess turtle, TurtleSide side) {
		// 装着されたTurtleのTurtleAccessとTurtleSideを保存
		turtleAccess = turtle;
		turtleSide = side;
	}

	/* 以下は周辺機器ブロックと同様に実装 */

	@Override
	public String getType() {
		return "sample";
	}

	@Override
	public String[] getMethodNames() {
		return new String[] {};
	}

	@Override
	public Object[] callMethod(IComputerAccess computer, ILuaContext context,
			int method, Object[] arguments) throws LuaException,
			InterruptedException {
		switch(method) {

		}

		return null;
	}

	@Override
	public void attach(IComputerAccess computer) {
		// 装着されたTurtleが起動したとき、またはコマンドでTurtleに装着されたときに呼び出される
	}

	@Override
	public void detach(IComputerAccess computer) {
		// 装着されたTurtleが終了したとき、またはコマンドでTurtleから取り外されたときに呼び出される
	}

	@Override
	public boolean equals(IPeripheral other) {
		// 周辺機器が同一のものであるかを返す
		// サンプルでは、このクラスのインスタンスで同一Turtleの同一方向に装着されている場合にのみtrueを返している
		if ((other != null) && (other instanceof SamplePeripheral)) {
			SamplePeripheral other1 = (SamplePeripheral)other;
			return (other1.turtleAccess == this.turtleAccess) && (other1.turtleSide == this.turtleSide);
		}

		return false;
	}

}

turtle_sample_left.json

Turtle UpgradeをTurtleの左側に装着したときのモデル
assets\sampleupgrademod\models\block ディレクトリに設置します。

{
	"parent": "computercraft:block/turtle_upgrade_base_left",
	"textures": {
		"texture": "sampleupgrademod:blocks/sample_upgrade"
	}
}

※今回はComputerCraft本体で定義されている物を流用しています。

turtle_sample_right.json

Turtle UpgradeをTurtleの右側に装着したときのモデル
assets\sampleupgrademod\models\block ディレクトリに設置します。

{
	"parent": "computercraft:block/turtle_upgrade_base_right",
	"textures": {
		"texture": "sampleupgrademod:blocks/sample_upgrade"
	}
}

※今回はComputerCraft本体で定義されている物を流用しています。

sample_upgrade.png

Turtle Upgradeのテクスチャ
assets\sampleupgrademod\textures\blocks ディレクトリに設置します。

※サイズ16x16などの適当なテクスチャファイルを各自で用意してください。