Mod開発 > メモ > CraftTweakerとの連携

CraftTweakerとの連携方法(メモ)

目的

自分のModで加工機械を追加し、その機械のレシピをCraftTweakerに対応させたい。
バージョンはMC1.7.10、CraftTweaker 3.0.13を使用
script.zs内で
import mods.mymod.MyMachine;
MyMachine.addRecipe(...);
みたいに書けるようにしたい。

ZenScriptのクラスを登録する


Githubを見てみる

1.7.10のブランチもタグもなかったのでMC1.12.2のコードを見てみた


  • ZenScript内で参照させるクラスに@ZenClass("...")と@ZenRegisterをつける
  • メソッドには@ZenMethodをつけIItemStackやIIndegrient[][]などで引数を受け取る
という方法を採っているのではないか
別途登録処理が必要なのか、@ZenReigsterアノテーションをつけるだけでいいのか、そもそも@ZenRegisterアノテーションがMC1.7.10に存在しているのかが不明(なさそう)


Jarをデコンパイルして中を見てみた

MC1.7.10、CraftTweaker 3.0.13を使用

@ZenRegisterアノテーションはなかった
ZenClassの登録方法は多分以下の通り

1. MineTweakerAPI.registerClass(Class annotatedClass)を呼び出す

ただしannotatedClassは@ZenClassアノテーションをつけたクラス

@ZenClassアノテーションをつけたクラスの中身の実装方法については別に書くつもり

2. GlobalRegistry.registerNativeClass(Class<?> cls)が呼び出される

clsは1.のannotatedClass
clsはZenTypeNativeに変換され、GlobalRegistry.rootに登録される
ZenTypeNativeも詳細は不明だが、@ZenClass("mods.mymod.MyMachine")とアノテーションをつけておくと、ZenScript内のパッケージmods.mymodやクラスMyMachineとして扱ってくれるようになる、と思う

minetweaker.modsにIC2、MFR、NEIとの連携の処理がある

@ModOnly({"IC2"})のように書くと、IC2が導入されているときしか使えなくなるようだ

minetweaker.mods.ic2.machines.BlastFurnace
クラスの宣言部分は
@ZenClass("mods.ic2.BlastFurnace")
@ModOnly({"IC2"})
public class BlastFurnace {
となっていて、@ZenClassアノテーションがついていることが確認できる
中のメソッドは、
@ZenMethod
public static void addRecipe(@NotNull IItemStack output, @NotNull IIngredient ingredient) {
  if(ingredient.getAmount() < 0) {
    MineTweakerAPI.logWarning("invalid ingredient: " + ingredient + " - stack size not known");
  }
  else {
    MineTweakerAPI.apply(new MachineAddRecipeAction("blast furnace", Recipes.blastfurance, MineTweakerMC.getItemStacks(new IItemStack[]{output}), (NBTTagCompound)null, new IC2RecipeInput(ingredient)));
}
 
のようになっていて、@ZenMethodアノテーションがついて、IItemStackやIIngredientを受け取っている。
そして**Actionのようなオブジェクトをつくってapplyしている。この**Actionについては調査中
IItemStackやIIngredientをItemStackなどに変換するメソッドも存在するので(https://docs.blamejared.com/ja/#Dev_Area/Ingredients/)、**Actionを使わなくても良いように思える

ClassRegistry

minetweaker.mods.ic2.ClassRegistryの中身は以下のようになっている
public class ClassRegistry {
   public static void getClasses(List arg) {
      arg.add(Crop.class);
      arg.add(CropsConfig.class);
      arg.add(GrowthRequirements.class);
      arg.add(SyntheticCrop.class);
      arg.add(IngredientExpansion.class);
      arg.add(ItemExpansion.class);
      arg.add(IC2BracketHandler.class);
      arg.add(IC2ExplosionWhitelist.class);
      arg.add(BlastFurnace.class);
      arg.add(BlockCutter.class);
      arg.add(Canner.class);
      arg.add(Compressor.class);
      arg.add(Extractor.class);
      arg.add(FluidHeatGenerator.class);
      arg.add(Macerator.class);
      arg.add(MatterAmplifier.class);
      arg.add(MetalFormer.class);
      arg.add(OreWasher.class);
      arg.add(Recycler.class);
      arg.add(ScrapBox.class);
      arg.add(SemiFluidGenerator.class);
      arg.add(ThermalCentrifuge.class);
   }
}
 
getClasses()というListを受け取りそこに@ZenClassアノテーションのついたクラスをいれる静的メソッドがある。

このClassRegistryMineTweakerAPI.registerClassRegistry(Class registryClass, String
description)にわたすと、自動でそれぞれのZenClassクラスについてMineTweakerAPI.registerClass(Class annotatedClass)を呼び出してくれるようだ。
なおdescriptionはログの出力にだけ使われるようだ

IUndoableActionについて調べる

IUndoableActionの内容は以下の通り
package minetweaker;
 
public interface IUndoableAction {
   void apply();
 
   boolean canUndo();
 
   void undo();
 
   String describe();
 
   String describeUndo();
 
   Object getOverrideKey();
}
 
例えばMyMachineAddRecipeActionクラスでIUndonableActionを実装して、
MineTweakerAPI.apply(new MyMachineAddRecipeAction(arg1, arg2...));
のようにすると、いろいろしてMTTweakerクラスのapply(IUndoableAction action)メソッドが呼び出され、最終的にMyMachineAddRecipeAction#apply()が実行される。

MTTweakerはログの出力や履歴の表示などをしてくれるようなので、Zenスクリプトから呼び出されるメソッドはIUndonableActionを使って実装する方が良いと思う。
最終更新:2019年08月20日 18:51