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();
コメントを残す