
那們我們今天呢,就用自定義AI的功能來做一隻孤僻的貓吧!
我們先把需要的檔案先建立好,一共有:
com.ithome.mymod.entities.LonerCat : 孤僻貓實體類別。com.ithome.mymod.ai.EntityAILoner : 自定義的AI工作,用來控制孤僻貓的行為。在LonerCat這個檔案內,我們會繼承現有的EntityOcelot類別,並且自訂我們自己的AI行為:
LonerCat繼承EntityOcelot後,會跳出紅色底線要我們建立建構子方法:
public class LonerCat extends EntityOcelot {
    public LonerCat(World worldIn) {
        super(worldIn);
        // 設置AI
        setupUI();
    }
}
private void setupUI() {
    this.tasks.taskEntries.clear();
    this.targetTasks.taskEntries.clear();
    // 自定義的AI工作
    tasks.addTask(0, new EntityAILoner(this));
}
// 孤僻貓的類別ID
public static final String name = "LonerCat";
// 是否為第一次與其它實體碰撞
public static AtomicBoolean firstHit = new AtomicBoolean(true);
// 與這個實體碰撞的玩家
public static EntityPlayer thePlayer;
EntityPlayer與是否為第一次碰撞;在這個EntityOcelot類別內,有一個onCollideWithPlayer方法可以供我們覆寫並且定義自己的動作:
@Override
public void onCollideWithPlayer(EntityPlayer player) {
    // 是第一次被碰撞 (第一個參數先判斷為true後,就透過第二個參數將這個firstHit更改為false)
    if(firstHit.compareAndSet(true, false)) {
        // 將AI工作內的判斷變數改為true
        EntityAILoner.isHit = true;
        // 設定玩家物件
        thePlayer = player;
    }
}
在EntityAILoner這個類別中,我們需要繼承EntityAIBase這個類別,並且實作方法:
EntityAIBase:
public class EntityAILoner extends EntityAIBase {
}
// 定義實體的物件
 private final EntityAnimal animal;
 // 用來判斷是否需要執行這個AI工作
 public static boolean isHit = false;
 // 判斷碰撞的時間,避免太頻繁執行
 public static long timer;
public EntityAILoner(EntityAnimal entity) {
    this.animal = entity;
    // 7可以與大部分的AI工作同時發生
    setMutexBits(7);
}
shouldExecute方法:
@Override
public boolean shouldExecute() {
    // 如果碰撞了,開始執行AI工作
    if(isHit) {
        // 將該變數設定為false等待下次碰撞發生
        isHit = false;
        return true;
    } else {
        // 其餘狀況都不執行AI工作
        return false;
    }
}
startExecuting方法:
@Override
public void startExecuting() {
    // 往碰撞的玩家送出隨機的訊息
    LonerCat.thePlayer.addChatComponentMessage(new ChatComponentText(
            EnumChatFormatting.RED + messages.get(new Random().nextInt(messages.size()))
    ));
    // 設定執行時間
    timer = System.currentTimeMillis();
}
continueExecuting方法:
@Override
public boolean continueExecuting() {
    // 若當前時間與執行時間相差在2秒內,就繼續這個AI工作來避免下一輪的觸發 (避免太頻繁)
    if(System.currentTimeMillis() - timer < 2 * 1000) {
        return true;
    } else {
        // 此次AI工作完成,讓LonerCat實體可以開始下一次的碰撞判斷事件了
        LonerCat.firstHit.compareAndSet(false, true);
        return false;
    }
}
private static List<String> messages = new ArrayList<String>();
static {
    messages.add("Don't touch me!");
    messages.add("Mew~~~~~~~");
    messages.add("Are you alone?");
    messages.add("Do you wanna be a cat?");
    messages.add("What does the fox say?");
}
最後一步驟,來到MyMod類別中,在preInit這個方法內需要註冊我們的自定義實體LonerCat:
@EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        int availableId = 1;
        while (EntityList.getClassFromID(availableId) != null) {
            availableId++;
        }
        EntityRegistry.registerGlobalEntityID(EntityScalePig.class, EntityScalePig.name, availableId);
        // 註冊LonerCat類別,找一個可以用的ID給它
        while (EntityList.getClassFromID(availableId) != null) {
            availableId++;
        }
        EntityRegistry.registerGlobalEntityID(LonerCat.class, LonerCat.name, availableId);
...(略)
前半段是我們俄羅斯豬的註冊,在後面加上孤僻貓的註冊。
好了,至此你已經完成一個簡單的自定義AI工作,到遊戲內你可以透過:
/summon LonerCat ~2 ~ ~
來產生我們的孤僻貓,然後嘗試去碰牠看看會產生什麼事吧!