A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.

[Sponge]SpongeAPIネタ(主にAPI7)

Spongeプラグインを作るためのSponge APIに関する小ネタです。しばらくSpongeAPI5を使ってたけど、SpongeAPI7になって変わった部分もあるので、その辺を中心に諸々調べた情報を掲載しておきます。(ほぼ、私のメモです)

EventContext

Sponge API 7(Minecraft 1.12系のSpongeサーバのプラグインAPI)を調べてるけど、なんだか、NamedCauseが見当たらなかったり、EventContextとかいうのが出現しているので調べてみた。

ちょっといろいろ実験中。ChangeBlockEvent.Breakの時はEventContextKeys.OWNER、EventContextKeys.NOTIFIER、EventContextKeys.SPAWN_TYPE、EventContextKeys.SPAWN_TYPE、EventContextKeys.USED_ITEMが発生する模様。
汎用性を持たせたいのはわかるけど、いい加減調べてみないと何が発生しているかわからない系の実装はやめて欲しいなぁ。

とりあえず、こんな感じのコードを書いてみる。

@Listener
public void onEvent( ChangeBlockEvent.Break e ) {
  if ( e.getContext().get( EventContextKeys.OWNER ).isPresent() ) {
    User a = e.getContext().get( EventContextKeys.OWNER ).get();
    logger.info( "OWNER:" + a.getName() );
  }
  if ( e.getContext().get( EventContextKeys.NOTIFIER ).isPresent() ) {
    User a = e.getContext().get( EventContextKeys.NOTIFIER ).get();
    logger.info( "NOTIFIER:" + a.getName() );
  }
  if ( e.getContext().get( EventContextKeys.SPAWN_TYPE ).isPresent() ) {
    logger.info( "SPAWN_TYPE:" + e.getContext().get( EventContextKeys.SPAWN_TYPE ).get().getName() );
  }
  if ( e.getContext().get( EventContextKeys.USED_ITEM ).isPresent() ) {
    logger.info( "USED_ITEM:" + e.getContext().get( EventContextKeys.USED_ITEM ).get().getType().getName() );
  }
}

結果

手で殴った時

OWNER:Tactica
NOTIFIER:Tactica
SPAWN_TYPE:DroppedItem
USED_ITEM:minecraft:air
※これは素手の場合。何か手に持って殴ると「USED_ITEM:minecraft:torch」になった。

TNT着火(火打ち石で)

OWNER:Tactica
NOTIFIER:Tactica
USED_ITEM:minecraft:flint_and_steel

TNT爆発

OWNER:Tactica
SPAWN_TYPE:TNTIgnite

どうやらNamedCause.SOURCE(発生元)はEventContextKeys.OWNERに置き換わったとかそんな感じかな。「e.getCause().first( Player.class )~」みたいな書き方もまだできるけど、「e.getCause().get( NamedCause.SOURCE, Player.class)~」はダメとか、「e.getCause().getContext()~」みたいな書き方が出来るようになったりとか、微妙な変わり方をしてる。

  • e.getCause().first( Player.class ).get()
    →間接的(TNTで破壊)の場合は取得不可。(User.classでも不可)
  • e.getCause().getContext().get(EventContextKeys.OWNER).get()
    →こっちは「e.getContext().get( EventContextKeys.OWNER ).get()」と同じ動きっぽい。

なんか、直感的にわかりづらくなった。

ItemStack/BlockState

アイテムやブロックのデータ取得時の値を見てみた。特に気になってるのは、1.13で値が大幅に変わるので、その辺の影響がどうなるのかなと。

ItemStack/ItemType/BlockState/BlockType

ItemStackは実際に(あるいは仮想的に)存在しているアイテム。ItemTypeはアイテムの定義ですね。ItemTypeはItemTypes.AIRみたいにスタティックに情報を取れますが、ItemStackは作成するなり、実データから取得します。
BlockStateはLocation.getBlock()で取れる値。つまり現物データが含まれてる。BlockTypeはItemTypeと同様に「定義」ですね。ちなみに、BlockSnapshotとかもありますが(詳細は[Sponge]ブロックイベントとCauseのメモを参照)、これはイベントなどで用いられる「変化」の情報が含まれているっぽい。

以下、手に持った32個の「磨かれた閃緑岩」のItemStackを見た結果。および設置済みの「磨かれた閃緑岩」のBlockStateを取得した結果。ちなみに「●.getType()」が実質的にItemType/BlockTypeです。

これを見ると、ItemとBlockが同じ物かの判定はgetIdやgetNameですが、そもそも石と変わらないです。1.13では「minecraft:polished_diorite」に変わるかもみたいですが、「minecraft:stone:6」みたいな表現が廃止になってる現状では、管理しやすくなるのかもですね。
一方でアイテム/ブロックの名前が「Type」から取れないのは謎ですね。

取得方法 ●=ItemStack ●=BlockState 補足
●.toString() 32xtile.stone@6 minecraft:stone[variant=smooth_andesite]
●.getMaxStackQuantity() 64 取得不可 最大の保有数。スタック出来ない物は「1」になる。
●.getQuantity() 32 取得不可 現在の数。スタック出来ない物は「1」になる。
●.getId() 取得不可 minecraft:stone[variant=smooth_andesite]
●.getName() 取得不可 minecraft:stone[variant=smooth_andesite]
●.getType().getId() minecraft:stone minecraft:stone この辺、1.13になると変わる?
●.getType().getName() minecraft:stone minecraft:stone 同上
●.getTranslation().get() Polished Andesite 取得不可 多分デフォのロケール
●.getTranslation().getId() tile.stone.andesiteSmooth.name 取得不可
●.getTranslation().get(Locale.JAPANESE) Polished Andesite 取得不可 日本語ロケールを指定しても無視.取り方はありそうだけど、、、
●.getTranslation().get(Locale.JAPAN) Polished Andesite 取得不可 同上
●.getType().getTranslation().get() tile.stone.name tile.stone.name getType()の結果が「minecraft:stone」だから、「磨かれた閃緑岩」では無く「石」と扱われてるみたい。ただ、表示されない理由は不明。
●.getType().getTranslation().getId() tile.stone.name tile.stone.name 同上
●.getType().getTranslation().get(Locale.JAPANESE) tile.stone.name tile.stone.name 同上
●.getType().getTranslation().get(Locale.JAPAN) tile.stone.name tile.stone.name 同上

なお、BlockState(BlockType)とItemStack(ItemType)の相互変換はこんな感じです。当然、変換できないパターンもあるので、Optional指定ですね。

  • ItemStack→BlockType
    (BlockType) = (ItemStack).getType().getBlock().get();
  • BlockState→ItemType
    (ItemType) = (BlockState).getBlockType().getItem();

 

コメントを残す

これらのHTMLタグが利用可能です

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

Time limit is exhausted. Please reload CAPTCHA.

A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.