石橋を叩いて壊すブログ

bukkitのWorldクラスがなかなか面白い

ちょっと練習にと、指定したアイテムIDのアイテムを生成してプレイヤーの位置からぶん投げるコードを書くことにした。
アイテムを無から生み出すには…どうやらWorldクラスの以下を使えばいいらしい。

Item dropItem(Location location, ItemStack item)
指定された場所にアイテムをドロップします。

そこでこういうコードを書いてみた。

//チャットコマンドが実行された時に呼び出される
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
    
    //コマンドを実行したプレイヤーを特定する
    Player player=null;
    for(Player p : getServer().getOnlinePlayers())
    {
        //現在オンラインのPlayerの一覧から、コマンド実行者と同じ名前の者を探す
        if(p.getName().equals(sender.getName()))
        {
            player=p;
            break;
        }
    }

    //万一プレイヤーを特定できなかったら失敗
    if(player==null)
    {
        log.warning("コマンドを実行したプレイヤー(" + sender.getName() + ")を特定できませんでした。");
        return false;
    }

    //アイテムを投げる「throw」コマンド
    //引数は2つ、アイテムIDと数量を指定する
    if(cmd.getName().equalsIgnoreCase("throw")){ 

        //引数は2つか
        if(args.length==2)
        {
            //引数1:アイテムIDを整数にする(文字列が空文字だったら?は練習と割り切って無視する)
            int id=Integer.parseInt(args[0]);

            //引数2:アイテム数量を整数にする(同上)
            int num=Integer.parseInt(args[1]);

            //プレイヤーの座標を取得    
            Location pos=player.getLocation();

            //アイテムを生成し世界へ落とす
            player.getWorld().dropItem(pos,new ItemStack(id,num));

            //プレイヤーにメッセージを送る
            player.sendMessage("あなたにアイテムを与えました。");

            return true;
        }
    }
}

これで、目の前にアイテムを落とすことができる。
あくまで目の前なので、アイテムが生成された直後にアイテムはプレイヤーに拾われる。

どうやら、「世界にアイテムを落とす」には、Worldクラスを使えばいいようだ。
見回してみたらいろいろ面白いものを見つけた。

boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks)
指定した座標で指定したパワーの爆発を作成する。爆発後の火災の発生と、爆発によりブロックを破壊するかを設定できる。

爆発でブロックが壊れないように設定できる。
爆発が起きたときのイベントEntityExplodeEventでイベントをsetCancelledし、
代わりに同じパワーの、ブロックを壊さない爆発を起こせば、マップの破壊を阻止できる。

void loadChunk(int x, int z)
指定された座標のチャンクを読み込む。

チャンクが作成されていない場合は作成する効果がある。
チャンクの生成はマルチプレイの中でも負荷のかかる処理なので、あらかじめまとめて生成しておけば
プレイ中の負荷やバージョンの壁を解消できるかもしれない。
でも生成しすぎると、新しいブロックが実装されたときどこにもないなんて展開もありうる。

いくつか使ってみたなかで、1点気になったのが以下。

Collection<T> getEntitiesByClass(Class<T> cls)
指定したクラス/インターフェイスと一致するこの世界のすべてのエンティティのコレクションを取得する。

たとえばgetEntitiesByClass(Wither.class)などと指定するとその世界のすべてのウィザーを取得できる…
はずなのだが、どうもチャンクが読み込まれてないと空のリストが返ってくるようだ。
ワープした直後などは空のリストが返ってきやすいので、使いどころは気をつけたほうがよさそう。

この記事を評価

20 8

コメント

【この記事にコメント】
お名前:
コメント:

295,349

記事カテゴリー

最近の記事

  1. FF14を翻訳したら国によって結構特色が違った[12/11]
  2. ゼロから始めるFactorioの回路構築(実践例編)[7/24]
  3. ゼロから始めるFactorioの回路構築(条件回路・論理演算編)[7/24]
  4. ゼロから始めるFactorioの回路構築(定数回路・算術回路編)[7/24]
  5. ゼロから始めるFactorioの回路構築(入力・出力・混合編)[7/24]

RSS1.0 RSS2.0

最近のコメント

  1. おー、お役に立てたようでなによりです。再起…[9/11]
  2. この記事が非常の役立ちました。おかげさまで…[9/9]
  3. 1.14.2のAPIで試しましたが、MapInitializeEv…[9/9]
  4. 天晴れ!押したらポーションのモヤモヤでまし…[5/26]
  5. 習うより慣れろって感じで。この記事は記事冒…[4/7]

記事を検索


管理人

石橋

2014年から
神奈川県秦野市市民