【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999

返信する

CAPTCHA 認証コード
表示されたコードを正確に入力してください。各文字は大文字・小文字の区別があります。

BBCode: OFF
スマイリー: OFF
トピックのレビュー
   

ファイルを添付します

展開ビュー トピックのレビュー: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by signal » 2018年12月13日(木) 19:30

この前インベントリを保存するやりかた
コード: 全て選択
public static String itemToString(ItemStack item){
         try{
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
            dataOutput.writeInt(54);
            //ここではItemStackが1つだけなので1に設定
            //引数にItemStack[]をとり、BukkitObjectOutputStream#writeInt(int)に配列長を設定しループ処理でオブジェクトを書き込む事で一纏めに処理する事も出来ます。
            dataOutput.writeObject(item);
            dataOutput.close();
            return Base64Coder.encodeLines(outputStream.toByteArray());
         }catch(Exception e){
            e.printStackTrace();
         }
         return null;
      }


      public static ItemStack stringToItem(String data){
         ItemStack item = null;

         try{
         ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
         BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
            dataInput.readInt();
            item = (ItemStack) dataInput.readObject();
            //書き込み時に複数のItemStackを書き込んでいた場合はこちらもループ処理でオブジェクトを読み込んで下さい。
            dataInput.close();
            return item;
         }catch(ClassNotFoundException e){
            e.printStackTrace();
         }catch(IOException e){
            e.printStackTrace();
         }
           return null;
       }

正直これを置くところも曖昧なのでそれも教えてほしいです。

でやってきたのですが、一個以外の保存のやり方がわからず、困っています。自分なりに工夫して
コード: 全て選択
@EventHandler
   public void close(InventoryCloseEvent e)
   {
      FileConfiguration config = getConfig();
      saveDefaultConfig();
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No1"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("チェスト"+e.getPlayer().getName()+"_"+e.getPlayer()+e.getInventory().getName()+"_"+x, e.getInventory().getItem(x));
            e.getPlayer().sendMessage(x+"");
            saveConfig();
            reloadConfig();
         }
      }
         }

コード: 全て選択
@EventHandler
   public void open(InventoryOpenEvent e)
   {
      FileConfiguration config = getConfig();
      saveDefaultConfig();
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No1"))
      {
         for(int x=0; x<=53; x++)
         {
            e.getInventory().addItem((ItemStack) config.get("チェスト"+e.getPlayer().getName()+"_"+e.getPlayer()+e.getInventory().getName()+"_"+x));
            e.getPlayer().sendMessage(x+"");
         }
       }
        }

とやったのですが、これも何故か一個しか保存、読み取りができないので、できれば両方の全部のインベントリを保存する方法を教えていただきたいです。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by yotasaki » 2018年12月13日(木) 19:24

spuash918 さんが書きました:
yotasaki さんが書きました:
薄ら氷 雪 さんが書きました:プレーヤーがサーバーに参加したときにでてくるメッセージをランダムで変えたいんですがどうすればいいですか?


こんにちは、薄ら氷 雪 さん。私が提案するのは乱数を使った方法です。

コード: 全て選択
   @EventHandler
   public void onPlayerJoin(PlayerJoinEvent e) {
      Random r = new Random();
      int n = r.nextInt(3);
      switch(n) {
      case 0:
         e.setJoinMessage("こんにちは!");
         break;
      case 1:
         e.setJoinMessage("おはよう!");
         break;
      case 2:
         e.setJoinMessage("こんばんは!");
         break;
      } return;
   }

といったようにすると乱数に指定された数値が一致した際に特定のものが流れるというようにできると思います。
もしかするともっと良い方法があるかもしれませんが私がパッと思いつくのはこれですかね。

動作は問題ないと思うのですが、これだと動的に数を増やしたりできないので配列などを使ったほうが良いのでは
例えば
コード: 全て選択
public void onPlayerJoin(PlayerJoinEvent event)
{
      String[] message = new String[] { "Text1", "Text2", "Text3" };//適当に値を入れる
      int number = new Random().nextInt (message.length - 1);//-1してるのはArrayIndexOutOfBoundsException対策

      event.setJoinMessage (message[number]);
}

IDEとかでチェックしてないので動かないかもしれませんが、だいたいこんな感じですかね
変数の名前に「e」や「n」等はあまり好ましくないかと
パット見て何の値なのかわかったほうが良いです


spuash918 さん、追加の回答ありがとうございます。その方法を私は思いつかず、私自身も勉強になりました。
「e」や「n」という変数の名前は私の普段使うもので、自身が理解できればいいという理由でつけていますが、おっしゃる通り、説明の場では相手に伝わりにくくなり則さないと思い、反省しております。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by spuash918 » 2018年12月13日(木) 17:42

yotasaki さんが書きました:
薄ら氷 雪 さんが書きました:プレーヤーがサーバーに参加したときにでてくるメッセージをランダムで変えたいんですがどうすればいいですか?


こんにちは、薄ら氷 雪 さん。私が提案するのは乱数を使った方法です。

コード: 全て選択
   @EventHandler
   public void onPlayerJoin(PlayerJoinEvent e) {
      Random r = new Random();
      int n = r.nextInt(3);
      switch(n) {
      case 0:
         e.setJoinMessage("こんにちは!");
         break;
      case 1:
         e.setJoinMessage("おはよう!");
         break;
      case 2:
         e.setJoinMessage("こんばんは!");
         break;
      } return;
   }

といったようにすると乱数に指定された数値が一致した際に特定のものが流れるというようにできると思います。
もしかするともっと良い方法があるかもしれませんが私がパッと思いつくのはこれですかね。

動作は問題ないと思うのですが、これだと動的に数を増やしたりできないので配列などを使ったほうが良いのでは
例えば
コード: 全て選択
public void onPlayerJoin(PlayerJoinEvent event)
{
      String[] message = new String[] { "Text1", "Text2", "Text3" };//適当に値を入れる
      int number = new Random().nextInt (message.length - 1);//-1してるのはArrayIndexOutOfBoundsException対策

      event.setJoinMessage (message[number]);
}

IDEとかでチェックしてないので動かないかもしれませんが、だいたいこんな感じですかね
変数の名前に「e」や「n」等はあまり好ましくないかと
パット見て何の値なのかわかったほうが良いです

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by 薄ら氷 雪 » 2018年12月13日(木) 14:07

yotasaki さん!ありがとうございます!

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by yotasaki » 2018年12月13日(木) 01:34

薄ら氷 雪 さんが書きました:プレーヤーがサーバーに参加したときにでてくるメッセージをランダムで変えたいんですがどうすればいいですか?


こんにちは、薄ら氷 雪 さん。私が提案するのは乱数を使った方法です。

コード: 全て選択
   @EventHandler
   public void onPlayerJoin(PlayerJoinEvent e) {
      Random r = new Random();
      int n = r.nextInt(3);
      switch(n) {
      case 0:
         e.setJoinMessage("こんにちは!");
         break;
      case 1:
         e.setJoinMessage("おはよう!");
         break;
      case 2:
         e.setJoinMessage("こんばんは!");
         break;
      } return;
   }

といったようにすると乱数に指定された数値が一致した際に特定のものが流れるというようにできると思います。
もしかするともっと良い方法があるかもしれませんが私がパッと思いつくのはこれですかね。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by 薄ら氷 雪 » 2018年12月12日(水) 19:00

プレーヤーがサーバーに参加したときにでてくるメッセージをランダムで変えたいんですがどうすればいいですか?

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by signal » 2018年12月10日(月) 20:58

amata1219 さんが書きました:
signal さんが書きました:保存できるインベントリを作りたいと思い、
コード: 全て選択
FileConfiguration config = getConfig();
      saveDefaultConfig();
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.1"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.2"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.3"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.4"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }

こうやって保存をして、読み取りもこれを取り出してという感じで検討してみたのですが、for文を何個も用いていることから落ちてしましました。
そこで調べてみるとBukkitObjectOutputStreamと本体にあるBase64Coderでシリアライズするというようなことがあったのでこれを使い、保存する方法を教えてください。
https://qiita.com/rushuu_r/items/677bf24db821838a7569


signalさん、こんにちは。

まず、ループ処理によってサーバーが落ちてしまうとのことですが、原因はfor文の多さでなく無限ループが発生しているからです。
下記コードを各for文から取り除いて下さい。この記述の通りに処理が実行されますと、for文のループ条件(x <= 53)を外れないうちにxが0となっています。ですので最初のfor文で無限ループが起きてしまいます。
コード: 全て選択
if(x >= 53) {
x=0;
}


次に、アイテムの保存方法の話になりますが、ItemStack自体はそのままコンフィグに保存出来ます。
ですのでわざわざシリアライズ処理を書く必要はありません。
コード: 全て選択
getConfig().set("Item", new ItemStack(Material.GRASS));
//ItemStackをコンフィグに保存
saveConfig();
reloadConfig();

ItemStack item = getConfig().getItemStack("Item");
//コンフィグからItemStackを取得


シリアライズ処理までご自身で実装されたい場合は下記コードと解説をご参考にして頂ければと思います。
コード: 全て選択
   public static String itemToString(ItemStack item){
      try{
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
         dataOutput.writeInt(1);
         //ここではItemStackが1つだけなので1に設定
         //引数にItemStack[]をとり、BukkitObjectOutputStream#writeInt(int)に配列長を設定しループ処理でオブジェクトを書き込む事で一纏めに処理する事も出来ます。
         dataOutput.writeObject(item);
         dataOutput.close();
         return Base64Coder.encodeLines(outputStream.toByteArray());
      }catch(Exception e){
         e.printStackTrace();
      }
      return null;
   }


   public static ItemStack stringToItem(String data){
      ItemStack item = null;

      try{
      ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
      BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
         dataInput.readInt();
         item = (ItemStack) dataInput.readObject();
         //書き込み時に複数のItemStackを書き込んでいた場合はこちらもループ処理でオブジェクトを読み込んで下さい。
         dataInput.close();
         return item;
      }catch(ClassNotFoundException e){
         e.printStackTrace();
      }catch(IOException e){
         e.printStackTrace();
      }
        return null;
    }

なるほど。無限ループしてたんですね...ありがとうございます。
シリアライズするだけにこれだけ書かなければならないのですね。
正直なところ、解説をつけてくださったのはありがたいのですが、それでもまだ意味がわからない領域にあるので今はとりあえず定型文みたいな感じで使用させていただきます。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by amata1219 » 2018年12月10日(月) 18:21

signal さんが書きました:保存できるインベントリを作りたいと思い、
コード: 全て選択
FileConfiguration config = getConfig();
      saveDefaultConfig();
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.1"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.2"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.3"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.4"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }

こうやって保存をして、読み取りもこれを取り出してという感じで検討してみたのですが、for文を何個も用いていることから落ちてしましました。
そこで調べてみるとBukkitObjectOutputStreamと本体にあるBase64Coderでシリアライズするというようなことがあったのでこれを使い、保存する方法を教えてください。
https://qiita.com/rushuu_r/items/677bf24db821838a7569


signalさん、こんにちは。

まず、ループ処理によってサーバーが落ちてしまうとのことですが、原因はfor文の多さでなく無限ループが発生しているからです。
下記コードを各for文から取り除いて下さい。この記述の通りに処理が実行されますと、for文のループ条件(x <= 53)を外れないうちにxが0となっています。ですので最初のfor文で無限ループが起きてしまいます。
コード: 全て選択
if(x >= 53) {
x=0;
}


次に、アイテムの保存方法の話になりますが、ItemStack自体はそのままコンフィグに保存出来ます。
ですのでわざわざシリアライズ処理を書く必要はありません。
コード: 全て選択
getConfig().set("Item", new ItemStack(Material.GRASS));
//ItemStackをコンフィグに保存
saveConfig();
reloadConfig();

ItemStack item = getConfig().getItemStack("Item");
//コンフィグからItemStackを取得


シリアライズ処理までご自身で実装されたい場合は下記コードと解説をご参考にして頂ければと思います。
コード: 全て選択
   public static String itemToString(ItemStack item){
      try{
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
         dataOutput.writeInt(1);
         //ここではItemStackが1つだけなので1に設定
         //引数にItemStack[]をとり、BukkitObjectOutputStream#writeInt(int)に配列長を設定しループ処理でオブジェクトを書き込む事で一纏めに処理する事も出来ます。
         dataOutput.writeObject(item);
         dataOutput.close();
         return Base64Coder.encodeLines(outputStream.toByteArray());
      }catch(Exception e){
         e.printStackTrace();
      }
      return null;
   }


   public static ItemStack stringToItem(String data){
      ItemStack item = null;

      try{
      ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
      BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
         dataInput.readInt();
         item = (ItemStack) dataInput.readObject();
         //書き込み時に複数のItemStackを書き込んでいた場合はこちらもループ処理でオブジェクトを読み込んで下さい。
         dataInput.close();
         return item;
      }catch(ClassNotFoundException e){
         e.printStackTrace();
      }catch(IOException e){
         e.printStackTrace();
      }
        return null;
    }

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by signal » 2018年12月09日(日) 13:26

保存できるインベントリを作りたいと思い、
コード: 全て選択
FileConfiguration config = getConfig();
      saveDefaultConfig();
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.1"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.2"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.3"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }
      if(e.getInventory().getName().equalsIgnoreCase("§r個人チェスト No.4"))
      {
         for(int x=0; x<=53; x++)
         {
            config.set("zzzzz"+e.getPlayer().getName()+e.getPlayer()+e.getInventory().getName(), e.getInventory().getItem(x));
            saveConfig();
            reloadConfig();
            if(x >= 53) {
               x=0;
            }
         }
      }

こうやって保存をして、読み取りもこれを取り出してという感じで検討してみたのですが、for文を何個も用いていることから落ちてしましました。
そこで調べてみるとBukkitObjectOutputStreamと本体にあるBase64Coderでシリアライズするというようなことがあったのでこれを使い、保存する方法を教えてください。
https://qiita.com/rushuu_r/items/677bf24db821838a7569

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by takumi_ » 2018年12月08日(土) 16:31

natsuri.net さんが書きました:
takumi_ さんが書きました:
コード: 全て選択
Player player = (Player) Bukkit.getOnlinePlayers();

これでしかプレイヤーは取得できないと思ったのですが、これではオンラインのプレイヤー全員が取得されるのではないかという考えたどり着いたのですがやはりこれ以外は僕がわかる限りの範囲ではできませんでした。どうすれば回復できるのでしょうか。


『Bukkit.getOnlinePlayers();』で取得できるのは『Player』ではなく『List<Player>』なので
List<Player> players = Bukkit.getOnlinePlayers();
になります。
ちなみに
コード: 全て選択
for(Player p:Bukkit.getOnlinePlayers()) {
    p.sendMessage("alert");
}

でプレイヤー全員にチャットを送れます

回答ありがとうございます。検討してみた結果無事実行されたのですが、きっと余分なものが書かれていたから結構重かったので使えませんでした。
コード: 全て選択
for(Player p:Bukkit.getOnlinePlayers()) {
    p.sendMessage("alert");
}

これは使えると思い使わさせて貰っています。



takumi_ さんが書きました:
前回までの内容
ヤドカリ さんが書きました:
takumi_ さんが書きました:HPの最大値(エフェクト等であげても画面が見づらくなるから)が決まっていて、それでは長いPVPが不可能だと思い、仮想のHP?みたいなのを作ろうとして、
コード: 全て選択
   @EventHandler
   public void join(PlayerJoinEvent e)
   {
      Player pl = e.getPlayer();
      FileConfiguration config = getConfig();
      String Name = config.getString(pl.getName()+".Name");
      String Custom = config.getString(pl.getName()+".CustomName");
      saveDefaultConfig();
      pl.setDisplayName("< "+Custom+" >");
      pl.setPlayerListName(Custom);
      pl.setCustomName(Custom);
      e.setJoinMessage(Name+"§bさんがサーバーに入ってきました。");
   }

   @EventHandler
   public void login(PlayerLoginEvent e)
   {
      FileConfiguration config = getConfig();
      saveDefaultConfig();
      Player pl = e.getPlayer();
      String Name = config.getString(pl.getName()+".Name");
      if(Name == pl.getName()) {
         //何もしない
      } else {
         config.set(pl.getName()+".Name", pl.getName());
         config.set(pl.getName()+".MIN_HP", 30);
         saveConfig();
         reloadConfig();
      }
   }

   @EventHandler
   public void HP(EntityDamageEvent e)  {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      Entity entity = e.getEntity();
      if(entity instanceof Player)
      {
         Player pl = (Player) entity;
         config.set(pl.getPlayer().getName()+".MIN_HP", config.getInt(pl.getPlayer().getName()+".MIN_HP")-e.getDamage());
         e.isCancelled();
         pl.getWorld().playSound(pl.getLocation(),Sound.ENTITY_PLAYER_ATTACK_NODAMAGE,1,1);
      }
   }

   //configを扱うためクラス分割不可
   @SuppressWarnings("deprecation")
   @EventHandler
   public void move(PlayerMoveEvent e) {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      ScoreboardManager manager = Bukkit.getScoreboardManager();
      Scoreboard board = manager.getMainScoreboard();
      Objective MAX_HP = board.registerNewObjective("MAX_HP", "dummy");
      Objective MIN_HP = board.registerNewObjective("MIN_HP", "dummy");
      MIN_HP.setDisplaySlot(DisplaySlot.SIDEBAR);
      MIN_HP.setDisplayName(" / 30");
      Player pl = e.getPlayer();
      MIN_HP.getScore(pl).setScore(config.getInt(pl.getName()+".MIN_HP"));
      pl.sendMessage((String) config.get(pl.getName()+".MIN_HP"));
      if(MIN_HP.getScore(pl).getScore() <= 0)
      {
         pl.damage(100);
      }
   }

   @EventHandler
   public void damage(EntityDamageByEntityEvent e) {e.isCancelled();}
ほかのpluginの内容が少し入っていますがお許しください。

仕組みとしてはログインしたらHPを30(test中のため低め)に設定し、ダメージを受けたらconfigの中にあるHPを減らし、それをmoveeventでスコアボードに反映しようとしたのですが、何故かうまく動作しませんでした。
一応、configの中身を見たら、MIN_HPは30となっており、ダメージを食らっても反映されず、スコアボードにも反映されず...
直すための助言をお願いします。
あとコマンドをopのみしか使えないようにする場合はどうしたらいいですか?

HPメソッドでsaveConfigしてないからだと思われます
あとスコアボードの反映ですが、MoveEventでやるよりもHPメソッドで更新した方が負荷も少なくていい気がします・・・
何か意味があるのであればすみません

op専用にするにはdescriptionやusageと同じ階層にpermissionを追加し、そこに任意のパーミッションを書きます
コード: 全て選択
commands:
  test:
    description: テスト
    usage: test
    permission: "test.op"

permissions:
  test.op:
    description: テスト
    default: op

test.opは好きな名前で大丈夫です

ありがとうございます。確かにmoveはいらないでしたね...
そこは解決したのはいいのですけれど、opだけというものが解決できていません。
一応plugin.ymlの中身はこうなっていますが...(必要な部分のみ)
コード: 全て選択
commands:
   name_edit:
      description:
      usage:
   name_edit_op:
      description:
      usage:
      permission: op.op
   name_menu:
      description:
      usage:
permissions:
   op.op:
      description:
      default: op

何か間違いとかありますか?
あと、使ってみてわかったのですが、これでは自動で回復する機能がないなと思い、
コード: 全て選択
new BukkitRunnable()
      {
         @Override
         public void run()
         {
            int t = 1;
            if(player instanceof Player)
            {
               Player pl = (Player) player;
               if(t == 0) {
                  this.cancel();
               } else {
                  config.set(pl.getName()+".MIN_HP", config.getInt(pl.getName()+".MIN_HP")+2);
                  saveConfig();
                  reloadConfig();
                  if(config.getInt(pl.getName()+".MIN_HP") <= config.getInt(pl.getName()+".MAN_HP"))
                  {
                     config.set(pl.getName()+".MIN_HP",  config.getInt(pl.getName()+".MAN_HP"));
                     saveConfig();
                     reloadConfig();
                  }
               }
            }
            t++;
         }
      }.runTaskTimer(this,0 ,20);

とやり、永久的に止まらないようにしたのですが、回復できず...ここで思ったのが、
コード: 全て選択
Player player = (Player) Bukkit.getOnlinePlayers();

これでしかプレイヤーは取得できないと思ったのですが、これではオンラインのプレイヤー全員が取得されるのではないかという考えたどり着いたのですがやはりこれ以外は僕がわかる限りの範囲ではできませんでした。どうすれば回復できるのでしょうか。


教えてもらったのにできないというのはおかしいと思ったので一回ほかのplugin抜いて試したら出来ました。ありがとうございます。ちなみにその原因はpermissonExでした。

回答してくださった皆様ありがとうございました。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by natsuri.net » 2018年12月06日(木) 19:58

takumi_ さんが書きました:
コード: 全て選択
Player player = (Player) Bukkit.getOnlinePlayers();

これでしかプレイヤーは取得できないと思ったのですが、これではオンラインのプレイヤー全員が取得されるのではないかという考えたどり着いたのですがやはりこれ以外は僕がわかる限りの範囲ではできませんでした。どうすれば回復できるのでしょうか。


『Bukkit.getOnlinePlayers();』で取得できるのは『Player』ではなく『List<Player>』なので
List<Player> players = Bukkit.getOnlinePlayers();
になります。
ちなみに
コード: 全て選択
for(Player p:Bukkit.getOnlinePlayers()) {
    p.sendMessage("alert");
}

でプレイヤー全員にチャットを送れます

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by takumi_ » 2018年12月06日(木) 18:11

前回までの内容
ヤドカリ さんが書きました:
takumi_ さんが書きました:HPの最大値(エフェクト等であげても画面が見づらくなるから)が決まっていて、それでは長いPVPが不可能だと思い、仮想のHP?みたいなのを作ろうとして、
コード: 全て選択
   @EventHandler
   public void join(PlayerJoinEvent e)
   {
      Player pl = e.getPlayer();
      FileConfiguration config = getConfig();
      String Name = config.getString(pl.getName()+".Name");
      String Custom = config.getString(pl.getName()+".CustomName");
      saveDefaultConfig();
      pl.setDisplayName("< "+Custom+" >");
      pl.setPlayerListName(Custom);
      pl.setCustomName(Custom);
      e.setJoinMessage(Name+"§bさんがサーバーに入ってきました。");
   }

   @EventHandler
   public void login(PlayerLoginEvent e)
   {
      FileConfiguration config = getConfig();
      saveDefaultConfig();
      Player pl = e.getPlayer();
      String Name = config.getString(pl.getName()+".Name");
      if(Name == pl.getName()) {
         //何もしない
      } else {
         config.set(pl.getName()+".Name", pl.getName());
         config.set(pl.getName()+".MIN_HP", 30);
         saveConfig();
         reloadConfig();
      }
   }

   @EventHandler
   public void HP(EntityDamageEvent e)  {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      Entity entity = e.getEntity();
      if(entity instanceof Player)
      {
         Player pl = (Player) entity;
         config.set(pl.getPlayer().getName()+".MIN_HP", config.getInt(pl.getPlayer().getName()+".MIN_HP")-e.getDamage());
         e.isCancelled();
         pl.getWorld().playSound(pl.getLocation(),Sound.ENTITY_PLAYER_ATTACK_NODAMAGE,1,1);
      }
   }

   //configを扱うためクラス分割不可
   @SuppressWarnings("deprecation")
   @EventHandler
   public void move(PlayerMoveEvent e) {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      ScoreboardManager manager = Bukkit.getScoreboardManager();
      Scoreboard board = manager.getMainScoreboard();
      Objective MAX_HP = board.registerNewObjective("MAX_HP", "dummy");
      Objective MIN_HP = board.registerNewObjective("MIN_HP", "dummy");
      MIN_HP.setDisplaySlot(DisplaySlot.SIDEBAR);
      MIN_HP.setDisplayName(" / 30");
      Player pl = e.getPlayer();
      MIN_HP.getScore(pl).setScore(config.getInt(pl.getName()+".MIN_HP"));
      pl.sendMessage((String) config.get(pl.getName()+".MIN_HP"));
      if(MIN_HP.getScore(pl).getScore() <= 0)
      {
         pl.damage(100);
      }
   }

   @EventHandler
   public void damage(EntityDamageByEntityEvent e) {e.isCancelled();}
ほかのpluginの内容が少し入っていますがお許しください。

仕組みとしてはログインしたらHPを30(test中のため低め)に設定し、ダメージを受けたらconfigの中にあるHPを減らし、それをmoveeventでスコアボードに反映しようとしたのですが、何故かうまく動作しませんでした。
一応、configの中身を見たら、MIN_HPは30となっており、ダメージを食らっても反映されず、スコアボードにも反映されず...
直すための助言をお願いします。
あとコマンドをopのみしか使えないようにする場合はどうしたらいいですか?

HPメソッドでsaveConfigしてないからだと思われます
あとスコアボードの反映ですが、MoveEventでやるよりもHPメソッドで更新した方が負荷も少なくていい気がします・・・
何か意味があるのであればすみません

op専用にするにはdescriptionやusageと同じ階層にpermissionを追加し、そこに任意のパーミッションを書きます
コード: 全て選択
commands:
  test:
    description: テスト
    usage: test
    permission: "test.op"

permissions:
  test.op:
    description: テスト
    default: op

test.opは好きな名前で大丈夫です

ありがとうございます。確かにmoveはいらないでしたね...
そこは解決したのはいいのですけれど、opだけというものが解決できていません。
一応plugin.ymlの中身はこうなっていますが...(必要な部分のみ)
コード: 全て選択
commands:
   name_edit:
      description:
      usage:
   name_edit_op:
      description:
      usage:
      permission: op.op
   name_menu:
      description:
      usage:
permissions:
   op.op:
      description:
      default: op

何か間違いとかありますか?
あと、使ってみてわかったのですが、これでは自動で回復する機能がないなと思い、
コード: 全て選択
new BukkitRunnable()
      {
         @Override
         public void run()
         {
            int t = 1;
            if(player instanceof Player)
            {
               Player pl = (Player) player;
               if(t == 0) {
                  this.cancel();
               } else {
                  config.set(pl.getName()+".MIN_HP", config.getInt(pl.getName()+".MIN_HP")+2);
                  saveConfig();
                  reloadConfig();
                  if(config.getInt(pl.getName()+".MIN_HP") <= config.getInt(pl.getName()+".MAN_HP"))
                  {
                     config.set(pl.getName()+".MIN_HP",  config.getInt(pl.getName()+".MAN_HP"));
                     saveConfig();
                     reloadConfig();
                  }
               }
            }
            t++;
         }
      }.runTaskTimer(this,0 ,20);

とやり、永久的に止まらないようにしたのですが、回復できず...ここで思ったのが、
コード: 全て選択
Player player = (Player) Bukkit.getOnlinePlayers();

これでしかプレイヤーは取得できないと思ったのですが、これではオンラインのプレイヤー全員が取得されるのではないかという考えたどり着いたのですがやはりこれ以外は僕がわかる限りの範囲ではできませんでした。どうすれば回復できるのでしょうか。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by natsuri.net » 2018年12月06日(木) 14:15

2つ質問させていただきます。

1つ目は、中身が書かれた本を開かせるPacketをプレイヤーに送りたいのですが、どうすればいいのでしょうか。
プレイヤーにアイテムは持たせたくないです。
バージョンは1.13.2です

2つ目は、1.13.2でブロックのHitBoxを取得したいのですが、1.10や1.8などの時と取得方法が変わっていて同じコードでは取得できませんでした。
コード: 全て選択
BlockPosition pos = new BlockPosition(x, y, z);
AxisAlignedBB box = new AxisAlignedBB(pos);

このコードでエラーは出ないのですが、worldを指定していないですし、hitboxは取得できませんでした。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by yotasaki » 2018年12月06日(木) 08:29

amata1219 さんが書きました:
yotasaki さんが書きました:スケジューラーについての質問です。
BukkitRunnableのTimerTaskをキャンセルしたあとに処理を行おうと思って、
以下は例として上げますが、
コード: 全て選択
   public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
      if (label.equalsIgnoreCase("start")) {
         new BukkitRunnable() {
            int timer = 600;
            @Override
            public void run() {
               if (0 >= timer) {
                  this.cancel();
               }
               timer = timer - 1;
            }
         }.runTaskTimer(this, 0, 20);
         sender.sendMessage("タイマー終了");

のようにしたのですが、どうもタスクが行われてる最中に次の処理が行われているみたいです。
どうすればTaskTimerが終わった後処理ができるのでしょうか・・・ 


yotasakiさん、こんにちは。
そのコードですとループ処理を始めた直後にタイマー終了と表示されてしまいます。
cancel()したタイミングでメッセージを送信して下さい。
コード: 全て選択
   public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
      if (label.equalsIgnoreCase("start")) {
         new BukkitRunnable() {
            int timer = 600;
            @Override
            public void run() {
               if (0 >= timer) {
                  this.cancel();
                  sender.sendMessage("タイマー終了");
                  //ここに記述する
               }
               timer = timer - 1;
            }
         }.runTaskTimer(this, 0, 20);
         //sender.sendMessage("タイマー終了"); ここではなく

amata1219さんどうもありがとうございます。cancel()した後、runTaskTimer();の下へ移るものだと思っておりました。
そして、記述どおりにしたところ想像通りの処理が行えました。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by ヤドカリ » 2018年12月05日(水) 20:49

takumi_ さんが書きました:HPの最大値(エフェクト等であげても画面が見づらくなるから)が決まっていて、それでは長いPVPが不可能だと思い、仮想のHP?みたいなのを作ろうとして、
コード: 全て選択
   @EventHandler
   public void join(PlayerJoinEvent e)
   {
      Player pl = e.getPlayer();
      FileConfiguration config = getConfig();
      String Name = config.getString(pl.getName()+".Name");
      String Custom = config.getString(pl.getName()+".CustomName");
      saveDefaultConfig();
      pl.setDisplayName("< "+Custom+" >");
      pl.setPlayerListName(Custom);
      pl.setCustomName(Custom);
      e.setJoinMessage(Name+"§bさんがサーバーに入ってきました。");
   }

   @EventHandler
   public void login(PlayerLoginEvent e)
   {
      FileConfiguration config = getConfig();
      saveDefaultConfig();
      Player pl = e.getPlayer();
      String Name = config.getString(pl.getName()+".Name");
      if(Name == pl.getName()) {
         //何もしない
      } else {
         config.set(pl.getName()+".Name", pl.getName());
         config.set(pl.getName()+".MIN_HP", 30);
         saveConfig();
         reloadConfig();
      }
   }

   @EventHandler
   public void HP(EntityDamageEvent e)  {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      Entity entity = e.getEntity();
      if(entity instanceof Player)
      {
         Player pl = (Player) entity;
         config.set(pl.getPlayer().getName()+".MIN_HP", config.getInt(pl.getPlayer().getName()+".MIN_HP")-e.getDamage());
         e.isCancelled();
         pl.getWorld().playSound(pl.getLocation(),Sound.ENTITY_PLAYER_ATTACK_NODAMAGE,1,1);
      }
   }

   //configを扱うためクラス分割不可
   @SuppressWarnings("deprecation")
   @EventHandler
   public void move(PlayerMoveEvent e) {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      ScoreboardManager manager = Bukkit.getScoreboardManager();
      Scoreboard board = manager.getMainScoreboard();
      Objective MAX_HP = board.registerNewObjective("MAX_HP", "dummy");
      Objective MIN_HP = board.registerNewObjective("MIN_HP", "dummy");
      MIN_HP.setDisplaySlot(DisplaySlot.SIDEBAR);
      MIN_HP.setDisplayName(" / 30");
      Player pl = e.getPlayer();
      MIN_HP.getScore(pl).setScore(config.getInt(pl.getName()+".MIN_HP"));
      pl.sendMessage((String) config.get(pl.getName()+".MIN_HP"));
      if(MIN_HP.getScore(pl).getScore() <= 0)
      {
         pl.damage(100);
      }
   }

   @EventHandler
   public void damage(EntityDamageByEntityEvent e) {e.isCancelled();}
ほかのpluginの内容が少し入っていますがお許しください。

仕組みとしてはログインしたらHPを30(test中のため低め)に設定し、ダメージを受けたらconfigの中にあるHPを減らし、それをmoveeventでスコアボードに反映しようとしたのですが、何故かうまく動作しませんでした。
一応、configの中身を見たら、MIN_HPは30となっており、ダメージを食らっても反映されず、スコアボードにも反映されず...
直すための助言をお願いします。
あとコマンドをopのみしか使えないようにする場合はどうしたらいいですか?

HPメソッドでsaveConfigしてないからだと思われます
あとスコアボードの反映ですが、MoveEventでやるよりもHPメソッドで更新した方が負荷も少なくていい気がします・・・
何か意味があるのであればすみません

op専用にするにはdescriptionやusageと同じ階層にpermissionを追加し、そこに任意のパーミッションを書きます
コード: 全て選択
commands:
  test:
    description: テスト
    usage: test
    permission: "test.op"

permissions:
  test.op:
    description: テスト
    default: op

test.opは好きな名前で大丈夫です

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by takumi_ » 2018年12月05日(水) 17:55

HPの最大値(エフェクト等であげても画面が見づらくなるから)が決まっていて、それでは長いPVPが不可能だと思い、仮想のHP?みたいなのを作ろうとして、
コード: 全て選択
   @EventHandler
   public void join(PlayerJoinEvent e)
   {
      Player pl = e.getPlayer();
      FileConfiguration config = getConfig();
      String Name = config.getString(pl.getName()+".Name");
      String Custom = config.getString(pl.getName()+".CustomName");
      saveDefaultConfig();
      pl.setDisplayName("< "+Custom+" >");
      pl.setPlayerListName(Custom);
      pl.setCustomName(Custom);
      e.setJoinMessage(Name+"§bさんがサーバーに入ってきました。");
   }

   @EventHandler
   public void login(PlayerLoginEvent e)
   {
      FileConfiguration config = getConfig();
      saveDefaultConfig();
      Player pl = e.getPlayer();
      String Name = config.getString(pl.getName()+".Name");
      if(Name == pl.getName()) {
         //何もしない
      } else {
         config.set(pl.getName()+".Name", pl.getName());
         config.set(pl.getName()+".MIN_HP", 30);
         saveConfig();
         reloadConfig();
      }
   }

   @EventHandler
   public void HP(EntityDamageEvent e)  {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      Entity entity = e.getEntity();
      if(entity instanceof Player)
      {
         Player pl = (Player) entity;
         config.set(pl.getPlayer().getName()+".MIN_HP", config.getInt(pl.getPlayer().getName()+".MIN_HP")-e.getDamage());
         e.isCancelled();
         pl.getWorld().playSound(pl.getLocation(),Sound.ENTITY_PLAYER_ATTACK_NODAMAGE,1,1);
      }
   }

   //configを扱うためクラス分割不可
   @SuppressWarnings("deprecation")
   @EventHandler
   public void move(PlayerMoveEvent e) {
      saveDefaultConfig();
      FileConfiguration config = getConfig();
      ScoreboardManager manager = Bukkit.getScoreboardManager();
      Scoreboard board = manager.getMainScoreboard();
      Objective MAX_HP = board.registerNewObjective("MAX_HP", "dummy");
      Objective MIN_HP = board.registerNewObjective("MIN_HP", "dummy");
      MIN_HP.setDisplaySlot(DisplaySlot.SIDEBAR);
      MIN_HP.setDisplayName(" / 30");
      Player pl = e.getPlayer();
      MIN_HP.getScore(pl).setScore(config.getInt(pl.getName()+".MIN_HP"));
      pl.sendMessage((String) config.get(pl.getName()+".MIN_HP"));
      if(MIN_HP.getScore(pl).getScore() <= 0)
      {
         pl.damage(100);
      }
   }

   @EventHandler
   public void damage(EntityDamageByEntityEvent e) {e.isCancelled();}
ほかのpluginの内容が少し入っていますがお許しください。

仕組みとしてはログインしたらHPを30(test中のため低め)に設定し、ダメージを受けたらconfigの中にあるHPを減らし、それをmoveeventでスコアボードに反映しようとしたのですが、何故かうまく動作しませんでした。
一応、configの中身を見たら、MIN_HPは30となっており、ダメージを食らっても反映されず、スコアボードにも反映されず...
直すための助言をお願いします。
あとコマンドをopのみしか使えないようにする場合はどうしたらいいですか?

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by チェリーブロッサム » 2018年12月04日(火) 18:33

amata1219 さんが書きました:
チェリーブロッサム さんが書きました:
amata1219 さんが書きました:
チェリーブロッサム さんが書きました:こんにちは
この前質問させていただいた者です

addItemFlags(ItemFlag.HIDE_ENCHANTS);
これだとエンチャントのキラキラがなくなるので、内容だけ隠すことはできますか。

不可能なら別の方法でキラキラをつけることはできますか?

わかるかた教えてください


チェリーブロッサムさん、こんにちは。

クライアントサイドに無いエンチャントが読み込まれるとエンチャントオーラだけ付与される仕様を利用する事で実現出来ます。
org.bukkit.enchantments.Enchantmentを継承したクラス(ここではCustomEnchant.class)を用意して下さい。
CustomEnchant.class
コード: 全て選択
public class CustomEnchant extends Enchantment {

     public CustomEnchant(int id){
         super(id);
     }

     @Override
     public boolean canEnchantItem(ItemStack arg0){
         return false;
     }

     @Override
     public boolean conflictsWith(Enchantment arg0){
         return false;
     }

     @Override
     public EnchantmentTarget getItemTarget(){
         return null;
     }

     @Override
     public int getMaxLevel(){
         return 0;
     }

     @Override
     public String getName(){
         return null;
     }

     @Override
     public int getStartLevel() {
         return 0;
     }
}


後は通常通りアイテムにエンチャントを追加するだけになります。
コード: 全て選択
ItemStack item = new ItemStack(Material.GRASS);
ItemMeta meta = item.getItemMeta();
CustomEnchant customEnchant = new CustomEnchant(1000);
//バニラのエンチャントと被らないIDを入力します。
meta.addEnchant(customEnchant, 1, true);
item.setItemMeta(meta);



何度もすみません。

クラスの用意の仕方教えてもらってもいいですか。(public class CustomEnchant extends Enchantment のところに赤線がついてしまいます。)

メインクラスに書き加えることとかありますか?

教えていただくとありがたいです


エンチャントの登録処理を書き忘れておりました、すみません…。

メインクラスのonEnable()でエンチャントの登録をする必要があります。
Enchantment#registerEnchantment(Enchantment)で登録出来ますが、通常のままでは新しいエンチャントの登録が許可されていないため、Enchantment#acceptingNewをtrueに変更します。
コード: 全て選択
@Override
public void onEnable(){
        try{
            Field field = Enchantment.class.getDeclaredField("acceptingNew");
            field.setAccessible(true);
            field.set(null, true);
        }catch(Exception e){
            e.printStackTrace();
        }

        try{
            CustomEnchant customEnchant = new CustomEnchant(1000);
            Enchantment.registerEnchantment(customEnchant);
        }catch(IllegalArgumentException e){
            //何もしない
        }catch(Exception e){
            e.printStackTrace();
        }
}


破線が引かれてしまう原因は何かしら別の問題があると思います。
一応CustomEnchant.classのimport部を載せておきます。
コード: 全て選択
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.ItemStack;


成功しました。手厚いサポートありがとうございました!

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by amata1219 » 2018年12月03日(月) 20:21

チェリーブロッサム さんが書きました:
amata1219 さんが書きました:
チェリーブロッサム さんが書きました:こんにちは
この前質問させていただいた者です

addItemFlags(ItemFlag.HIDE_ENCHANTS);
これだとエンチャントのキラキラがなくなるので、内容だけ隠すことはできますか。

不可能なら別の方法でキラキラをつけることはできますか?

わかるかた教えてください


チェリーブロッサムさん、こんにちは。

クライアントサイドに無いエンチャントが読み込まれるとエンチャントオーラだけ付与される仕様を利用する事で実現出来ます。
org.bukkit.enchantments.Enchantmentを継承したクラス(ここではCustomEnchant.class)を用意して下さい。
CustomEnchant.class
コード: 全て選択
public class CustomEnchant extends Enchantment {

     public CustomEnchant(int id){
         super(id);
     }

     @Override
     public boolean canEnchantItem(ItemStack arg0){
         return false;
     }

     @Override
     public boolean conflictsWith(Enchantment arg0){
         return false;
     }

     @Override
     public EnchantmentTarget getItemTarget(){
         return null;
     }

     @Override
     public int getMaxLevel(){
         return 0;
     }

     @Override
     public String getName(){
         return null;
     }

     @Override
     public int getStartLevel() {
         return 0;
     }
}


後は通常通りアイテムにエンチャントを追加するだけになります。
コード: 全て選択
ItemStack item = new ItemStack(Material.GRASS);
ItemMeta meta = item.getItemMeta();
CustomEnchant customEnchant = new CustomEnchant(1000);
//バニラのエンチャントと被らないIDを入力します。
meta.addEnchant(customEnchant, 1, true);
item.setItemMeta(meta);



何度もすみません。

クラスの用意の仕方教えてもらってもいいですか。(public class CustomEnchant extends Enchantment のところに赤線がついてしまいます。)

メインクラスに書き加えることとかありますか?

教えていただくとありがたいです


エンチャントの登録処理を書き忘れておりました、すみません…。

メインクラスのonEnable()でエンチャントの登録をする必要があります。
Enchantment#registerEnchantment(Enchantment)で登録出来ますが、通常のままでは新しいエンチャントの登録が許可されていないため、Enchantment#acceptingNewをtrueに変更します。
コード: 全て選択
@Override
public void onEnable(){
        try{
            Field field = Enchantment.class.getDeclaredField("acceptingNew");
            field.setAccessible(true);
            field.set(null, true);
        }catch(Exception e){
            e.printStackTrace();
        }

        try{
            CustomEnchant customEnchant = new CustomEnchant(1000);
            Enchantment.registerEnchantment(customEnchant);
        }catch(IllegalArgumentException e){
            //何もしない
        }catch(Exception e){
            e.printStackTrace();
        }
}


破線が引かれてしまう原因は何かしら別の問題があると思います。
一応CustomEnchant.classのimport部を載せておきます。
コード: 全て選択
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.ItemStack;

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by チェリーブロッサム » 2018年12月03日(月) 19:23

amata1219 さんが書きました:
チェリーブロッサム さんが書きました:こんにちは
この前質問させていただいた者です

addItemFlags(ItemFlag.HIDE_ENCHANTS);
これだとエンチャントのキラキラがなくなるので、内容だけ隠すことはできますか。

不可能なら別の方法でキラキラをつけることはできますか?

わかるかた教えてください


チェリーブロッサムさん、こんにちは。

クライアントサイドに無いエンチャントが読み込まれるとエンチャントオーラだけ付与される仕様を利用する事で実現出来ます。
org.bukkit.enchantments.Enchantmentを継承したクラス(ここではCustomEnchant.class)を用意して下さい。
CustomEnchant.class
コード: 全て選択
public class CustomEnchant extends Enchantment {

     public CustomEnchant(int id){
         super(id);
     }

     @Override
     public boolean canEnchantItem(ItemStack arg0){
         return false;
     }

     @Override
     public boolean conflictsWith(Enchantment arg0){
         return false;
     }

     @Override
     public EnchantmentTarget getItemTarget(){
         return null;
     }

     @Override
     public int getMaxLevel(){
         return 0;
     }

     @Override
     public String getName(){
         return null;
     }

     @Override
     public int getStartLevel() {
         return 0;
     }
}


後は通常通りアイテムにエンチャントを追加するだけになります。
コード: 全て選択
ItemStack item = new ItemStack(Material.GRASS);
ItemMeta meta = item.getItemMeta();
CustomEnchant customEnchant = new CustomEnchant(1000);
//バニラのエンチャントと被らないIDを入力します。
meta.addEnchant(customEnchant, 1, true);
item.setItemMeta(meta);



何度もすみません。

クラスの用意の仕方教えてもらってもいいですか。(public class CustomEnchant extends Enchantment のところに赤線がついてしまいます。)

メインクラスに書き加えることとかありますか?

教えていただくとありがたいです

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by amata1219 » 2018年12月03日(月) 17:59

チェリーブロッサム さんが書きました:こんにちは
この前質問させていただいた者です

addItemFlags(ItemFlag.HIDE_ENCHANTS);
これだとエンチャントのキラキラがなくなるので、内容だけ隠すことはできますか。

不可能なら別の方法でキラキラをつけることはできますか?

わかるかた教えてください


チェリーブロッサムさん、こんにちは。

クライアントサイドに無いエンチャントが読み込まれるとエンチャントオーラだけ付与される仕様を利用する事で実現出来ます。
org.bukkit.enchantments.Enchantmentを継承したクラス(ここではCustomEnchant.class)を用意して下さい。
CustomEnchant.class
コード: 全て選択
public class CustomEnchant extends Enchantment {

     public CustomEnchant(int id){
         super(id);
     }

     @Override
     public boolean canEnchantItem(ItemStack arg0){
         return false;
     }

     @Override
     public boolean conflictsWith(Enchantment arg0){
         return false;
     }

     @Override
     public EnchantmentTarget getItemTarget(){
         return null;
     }

     @Override
     public int getMaxLevel(){
         return 0;
     }

     @Override
     public String getName(){
         return null;
     }

     @Override
     public int getStartLevel() {
         return 0;
     }
}


後は通常通りアイテムにエンチャントを追加するだけになります。
コード: 全て選択
ItemStack item = new ItemStack(Material.GRASS);
ItemMeta meta = item.getItemMeta();
CustomEnchant customEnchant = new CustomEnchant(1000);
//バニラのエンチャントと被らないIDを入力します。
meta.addEnchant(customEnchant, 1, true);
item.setItemMeta(meta);


yotasaki さんが書きました:スケジューラーについての質問です。
BukkitRunnableのTimerTaskをキャンセルしたあとに処理を行おうと思って、
以下は例として上げますが、
コード: 全て選択
   public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
      if (label.equalsIgnoreCase("start")) {
         new BukkitRunnable() {
            int timer = 600;
            @Override
            public void run() {
               if (0 >= timer) {
                  this.cancel();
               }
               timer = timer - 1;
            }
         }.runTaskTimer(this, 0, 20);
         sender.sendMessage("タイマー終了");

のようにしたのですが、どうもタスクが行われてる最中に次の処理が行われているみたいです。
どうすればTaskTimerが終わった後処理ができるのでしょうか・・・ 


yotasakiさん、こんにちは。
そのコードですとループ処理を始めた直後にタイマー終了と表示されてしまいます。
cancel()したタイミングでメッセージを送信して下さい。
コード: 全て選択
   public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
      if (label.equalsIgnoreCase("start")) {
         new BukkitRunnable() {
            int timer = 600;
            @Override
            public void run() {
               if (0 >= timer) {
                  this.cancel();
                  sender.sendMessage("タイマー終了");
                  //ここに記述する
               }
               timer = timer - 1;
            }
         }.runTaskTimer(this, 0, 20);
         //sender.sendMessage("タイマー終了"); ここではなく

ページトップ

x