提供: Minecraft Modding Wiki
2014年10月23日 (木) 11:29時点におけるNMS (トーク | 投稿記録)による版 (Blockのソース、Tileの解説を修正)
移動先: 案内検索
この記事は執筆中です。加筆してくださる人を募集しています。

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

周辺機器からイベントを発生させる

右クリックされたとき、接続されたComputerやTurtleに対してイベントを発生させる周辺機器ブロックを追加する。

ソースコード

周辺機器の追加」のソースコードを元にして、変更部分のみを解説する。

  • BlockSamplePeripheral.java
package mods.sample.peripheral;

import java.util.Random;

import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

public class BlockSamplePeripheral extends BlockContainer {

	public BlockSamplePeripheral() {
		super(Material.ground);
	}

	@Override
	public boolean onBlockActivated(World world, int x, int y, int z,
			EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
		TileEntity tile = world.getTileEntity(x, y, z);
		if (!world.isRemote && tile != null && tile instanceof TileSamplePeripheral) {
			((TileSamplePeripheral)tile).click();
		}
		return true;
	}

	@Override
	public int quantityDropped(int meta, int fortune, Random random){
		return quantityDroppedWithBonus(fortune, random);
	}

	@Override
	public int quantityDropped(Random random){
		return 1;
	}

	@Override
	public TileEntity createNewTileEntity(World world, int a) {
		return new TileSamplePeripheral();
	}

}
  • TileSamplePeripheral.java
package mods.sample.peripheral;

import java.util.HashSet;
import java.util.Set;

import net.minecraft.tileentity.TileEntity;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;

public class TileSamplePeripheral extends TileEntity implements IPeripheral {

	private final Set<IComputerAccess> m_computers;

	public TileSamplePeripheral() {
		m_computers = new HashSet();
	}

	@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 {
		return null;
	}

	@Override
	public void attach(IComputerAccess computer) {
		synchronized (this.m_computers) {
			this.m_computers.add(computer);
		}
	}

	@Override
	public void detach(IComputerAccess computer) {
		synchronized (this.m_computers) {
			this.m_computers.remove(computer);
		}
	}

	@Override
	public boolean equals(IPeripheral other) {
		if ((other != null) && (other instanceof TileSamplePeripheral)) {
			return other == this;
		}
		return false;
	}

	public void click() {
		synchronized (this.m_computers) {
			for (IComputerAccess computer : this.m_computers) {
				computer.queueEvent("sample_click", new Object[] {computer.getAttachmentName()} );
			}
		}
	}

}

解説

BlockSamplePeripheral.java

周辺機器ブロックが右クリックされた時の処理を追加する。

@Override
public boolean onBlockActivated(World world, int x, int y, int z,
		EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
	TileEntity tile = world.getTileEntity(x, y, z);
	if (!world.isRemote && tile != null && tile instanceof TileSamplePeripheral) {
		((TileSamplePeripheral)tile).click();
	}
	return true;
}

ブロックが右クリックされたらTileEntity(周辺機器)を取得してclick()を呼び出す。

TileSamplePeripheral.java

イベント発生の処理と、イベントを発生させるための接続されたComputerやTurtleのリストの管理を追加する。

private final Set<IComputerAccess> m_computers;

public TileSamplePeripheral() {
	m_computers = new HashSet();
}

↑コンストラクタで接続されたComputerやTurtleへイベントを発生させるのに必要なIComputerAccessインスタンスのリストを初期化する。

@Override
public void attach(IComputerAccess computer) {
	synchronized(this.m_computers) {
		this.m_computers.add(computer);
	}
}
 
@Override
public void detach(IComputerAccess computer) {
	synchronized(this.m_computers) {
		this.m_computers.remove(computer);
	}
}

↑attach()で接続されたComputerやTurtleのIComputerAccessインスタンスをリストへ追加、detach()で取り外されたComputerやTurtleのComputerAccessインスタンスをリストから削除。
attach()とdetach()はComputerCraftのLuaスレッドから呼び出されている。このリストはMinecraftスレッドから呼び出されるclick()からもアクセスされるのでsynchronizedで排他制御している。

public void click() {
	synchronized (this.m_computers) {
		for (IComputerAccess computer : this.m_computers) {
			computer.queueEvent("sample_click", new Object[] {computer.getAttachmentName()} );
		}
	}
}

↑周辺機器ブロックが右クリックされた時に、BlockSamplePeripheralから呼び出される。IComputerAccessインスタンスのリストにある全てのComputerやTurtleへIComputerAccess.queueEvent()で"sample_click"イベントを発生させる。前述の通り、リストへのアクセスは排他的に行っている。

  • イベント

イベント名は、発生したイベントの内容が分かりやすいように"周辺機器の種類_イベントの内容"のような形にする事が推奨されている。(APIのjavadoc参照)
queueEvent()の引数はos.queueEvent関数と同様。ただし、イベントのパラメータはオブジェクト型配列として渡す。値の型はcallMethod()の戻り値と同様に適切なLuaの型へと変換される。イベントのパラメータの一番目には、ComputerやTurtleからどの周辺機器で発生したイベントなのかが分かるように、IComputerAccess.getAttachmentName()を渡すとよい。