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

Modding・サーバPlugin制作・ツール制作など、開発関連の質問があればこちらにお願い致します。
フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999
  • (PostNo.318206)

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

投稿記事by takepansan » 2018年7月20日(金) 22:23

ExampleTask().runTaskLaterを使用するときに,Mainクラス以外で使うとnew ExampleTask().runTaskLater(this ,100);でエラーが出ます。解決方法はありますか?
takepansan
ID:72621b84
水から上がったとこ
 
記事: 2
登録日時: 2018年7月20日(金) 22:19

  • (PostNo.318207)

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

投稿記事by TA3 » 2018年7月20日(金) 22:33

takepansan さんが書きました:ExampleTask().runTaskLaterを使用するときに,Mainクラス以外で使うとnew ExampleTask().runTaskLater(this ,100);でエラーが出ます。解決方法はありますか?

JavaPluginを継承しているクラス以外ではPluginのparamとして自クラスのインスタンスを使用することができません。
javaPluginを継承しているMainクラスのインスタンスを保持してそれを使います。
コード: 全て選択
/*    Mainクラス    */
private static Main i;

@Override
public void onEnable(){
    i = this;
}

public static Main getInstance(){
    return i;
}

/*    別のクラス    */
public void delayTaskTest(){
    Main i = Main.getInstance();
    Bukkit.getScheduler().runTaskLater(i, new Runnable(){});
}
アバター
TA3
ID:a95d26b2
木を殴ってる
 
記事: 18
登録日時: 2016年8月18日(木) 17:44

  • (PostNo.318217)

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

投稿記事by takepansan » 2018年7月21日(土) 13:21

TA3 さんが書きました:
takepansan さんが書きました:ExampleTask().runTaskLaterを使用するときに,Mainクラス以外で使うとnew ExampleTask().runTaskLater(this ,100);でエラーが出ます。解決方法はありますか?

JavaPluginを継承しているクラス以外ではPluginのparamとして自クラスのインスタンスを使用することができません。
javaPluginを継承しているMainクラスのインスタンスを保持してそれを使います。
コード: 全て選択
/*    Mainクラス    */
private static Main i;

@Override
public void onEnable(){
    i = this;
}

public static Main getInstance(){
    return i;
}

/*    別のクラス    */
public void delayTaskTest(){
    Main i = Main.getInstance();
    Bukkit.getScheduler().runTaskLater(i, new Runnable(){});
}


ありがとうございます。解決しました。
takepansan
ID:72621b84
水から上がったとこ
 
記事: 2
登録日時: 2018年7月20日(金) 22:19

  • (PostNo.318461)

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

投稿記事by 八咫烏 » 2018年7月29日(日) 15:11

MainClass↓
コード: 全て選択
   private int counter;

   @EventHandler
   public void onWeapon(PlayerInteractEvent e){

      Material m = e.getItem().getType();
      ItemStack itemStack = e.getItem();
      if(m == Material.STICK && itemStack.hasItemMeta() == true && e.getAction() == Action.RIGHT_CLICK_AIR ){


         counter = 5;
         new WeaponTask(this, counter ,e.getPlayer()).runTaskTimer(this, 0, 5);


         }

   }


サブクラス↓

コード: 全て選択
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class WeaponTask extends BukkitRunnable{

   private final JavaPlugin plugin;
   private int counter;
   private Player player;

   public WeaponTask(JavaPlugin plugin, int counter , Player player){

      this.plugin = plugin;

      if(counter < 1){

         throw new IllegalArgumentException("counter には1以上を指定してください。");

      }

      else{

         this.player = player;
         this.counter = counter;

      }

   }

   @SuppressWarnings("deprecation")
   @Override
   public void run(){

      if(counter > 0){

         player.throwSnowball();
         player.playSound(player.getLocation(), Sound.BLAZE_HIT, 10, 10);
         counter--;

      }

      else{

         plugin.getServer().broadcastMessage("ラストカウンター: " + counter);
         plugin.getServer().broadcastMessage("END");
         this.cancel();

      }

   }


これで、スノーボール発射するんですけど、右クリックで連射中にもう一度右クリックすると
かぶせて発射されてしまいます(2回分サブクラスが働く)
こうしないためにはどうすればいいんでしょうか。
アバター
八咫烏
ID:41f9f109
木を殴ってる
 
記事: 21
登録日時: 2014年8月14日(木) 18:06
お住まい: 闇の中

  • (PostNo.318467)

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

投稿記事by amata1219 » 2018年7月29日(日) 17:40

八咫烏 さんが書きました:MainClass↓
コード: 全て選択
   private int counter;

   @EventHandler
   public void onWeapon(PlayerInteractEvent e){

      Material m = e.getItem().getType();
      ItemStack itemStack = e.getItem();
      if(m == Material.STICK && itemStack.hasItemMeta() == true && e.getAction() == Action.RIGHT_CLICK_AIR ){


         counter = 5;
         new WeaponTask(this, counter ,e.getPlayer()).runTaskTimer(this, 0, 5);


         }

   }


サブクラス↓

コード: 全て選択
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class WeaponTask extends BukkitRunnable{

   private final JavaPlugin plugin;
   private int counter;
   private Player player;

   public WeaponTask(JavaPlugin plugin, int counter , Player player){

      this.plugin = plugin;

      if(counter < 1){

         throw new IllegalArgumentException("counter には1以上を指定してください。");

      }

      else{

         this.player = player;
         this.counter = counter;

      }

   }

   @SuppressWarnings("deprecation")
   @Override
   public void run(){

      if(counter > 0){

         player.throwSnowball();
         player.playSound(player.getLocation(), Sound.BLAZE_HIT, 10, 10);
         counter--;

      }

      else{

         plugin.getServer().broadcastMessage("ラストカウンター: " + counter);
         plugin.getServer().broadcastMessage("END");
         this.cancel();

      }

   }


これで、スノーボール発射するんですけど、右クリックで連射中にもう一度右クリックすると
かぶせて発射されてしまいます(2回分サブクラスが働く)
こうしないためにはどうすればいいんでしょうか。


八咫烏さん、こんにちは。
それでしたら、ループ処理中か確認するコードを追加するだけで簡単に解決出来ます。

1. Mainクラスにpublic List<UUID>を作成(ここでは変数名listとします)。
2. Main#onWeapon(…)のif文に、!list.contains(e.getPlayer().getUniqueId())の条件文を追加。
3. Main#onWeapon(…)でのWeaponTask生成後にlist.add(e.getPlayer().getUniqueId())の記述を追加。
4. WeaponTask#run()のbroadcastMessage("END")の後に、plugin.list.remove(player.getPlayer().getUniqueId())の記述を追加。

Main.class
コード: 全て選択
public List<UUID> list = new ArrayList<UUID>();

@EventHandler
public void onWeapon(PlayerInteractEvent e){
Player p = e.getPlayer();
UUID uuid = p.getUniqueId();
ItemStack itemStack = e.getItem();
if(e.getAction() == Action.RIGHT_CLICK_AIR && !list.contains(uuid) && itemStack.hasItemMeta() && itemStack.getType == Material.STICK){
new WeaponTask(this, 5 , p).runTaskTimer(this, 0, 5);
list.add(uuid);
}
}


WeaponTask.class
コード: 全て選択
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class WeaponTask extends BukkitRunnable{

private final JavaPlugin plugin;
private int counter;
private Player player;

public WeaponTask(JavaPlugin plugin, int counter , Player player){
if(counter > 0){
this.plugin = plugin;
this.player = player;
this.counter = counter;
}else{
throw new IllegalArgumentException("counter には1以上を指定してください。");
}
}

@SuppressWarnings("deprecation")
@Override
public void run(){
if(counter > 0){
player.throwSnowball();
//throwSnowball():これはコードを省略されただけでしょうか…?
player.playSound(player.getLocation(), Sound.BLAZE_HIT, 10, 10);
counter--;
}else{
plugin.getServer().broadcastMessage("ラストカウンター: " + counter);
plugin.getServer().broadcastMessage("END");
plugin.list.remove(player.getUniqueId());
this.cancel();
}
}


1~4に従いコードを記述するとこのようになると思います。

1~4以外で個人的に気になる点がいくつかありましたので合わせて修正させて頂きました。

a: Main#counter - 必要無いのでnew WeaponTask(…)に数値をそのまま記述(呼び出し元でメソッドの引数に基本データ型を使用した場合、メソッドではその値のコピーを受け取ります。単純に値のコピーを渡しているだけなので、メソッド内でその値に変更を加えても、呼び出し元には影響しません)。

b: Main#onWeapon(…) - if文の条件「itemStack.hasItemMeta()がtrue」は==trueを記述する必要無し(代入と見間違えたり、コードが冗長になるため)。

c: WeaponTask#WeaponTask - 条件は分かりやすくrun()と同じ記述にし、最初の代入処理(this.plugin = plugin;)はif文内に他の代入処理と一緒に記述。


追記:

後々思いつきましたがループ処理の終了時間が分かっているなら、onWeapon(…)でlist.remove(uuid)を遅延実行処理するという方法もあります(というかこちらの方が楽)。
アバター
amata1219
ID:3a1efa28
大工さん
 
記事: 59
登録日時: 2016年11月18日(金) 16:46
お住まい: 愛知県

  • (PostNo.318482)

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

投稿記事by 八咫烏 » 2018年7月30日(月) 08:49

amata1219 さんが書きました:
八咫烏 さんが書きました:MainClass↓
コード: 全て選択
   private int counter;

   @EventHandler
   public void onWeapon(PlayerInteractEvent e){

      Material m = e.getItem().getType();
      ItemStack itemStack = e.getItem();
      if(m == Material.STICK && itemStack.hasItemMeta() == true && e.getAction() == Action.RIGHT_CLICK_AIR ){


         counter = 5;
         new WeaponTask(this, counter ,e.getPlayer()).runTaskTimer(this, 0, 5);


         }

   }


サブクラス↓

コード: 全て選択
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class WeaponTask extends BukkitRunnable{

   private final JavaPlugin plugin;
   private int counter;
   private Player player;

   public WeaponTask(JavaPlugin plugin, int counter , Player player){

      this.plugin = plugin;

      if(counter < 1){

         throw new IllegalArgumentException("counter には1以上を指定してください。");

      }

      else{

         this.player = player;
         this.counter = counter;

      }

   }

   @SuppressWarnings("deprecation")
   @Override
   public void run(){

      if(counter > 0){

         player.throwSnowball();
         player.playSound(player.getLocation(), Sound.BLAZE_HIT, 10, 10);
         counter--;

      }

      else{

         plugin.getServer().broadcastMessage("ラストカウンター: " + counter);
         plugin.getServer().broadcastMessage("END");
         this.cancel();

      }

   }


これで、スノーボール発射するんですけど、右クリックで連射中にもう一度右クリックすると
かぶせて発射されてしまいます(2回分サブクラスが働く)
こうしないためにはどうすればいいんでしょうか。


八咫烏さん、こんにちは。
それでしたら、ループ処理中か確認するコードを追加するだけで簡単に解決出来ます。

1. Mainクラスにpublic List<UUID>を作成(ここでは変数名listとします)。
2. Main#onWeapon(…)のif文に、!list.contains(e.getPlayer().getUniqueId())の条件文を追加。
3. Main#onWeapon(…)でのWeaponTask生成後にlist.add(e.getPlayer().getUniqueId())の記述を追加。
4. WeaponTask#run()のbroadcastMessage("END")の後に、plugin.list.remove(player.getPlayer().getUniqueId())の記述を追加。

Main.class
コード: 全て選択
public List<UUID> list = new ArrayList<UUID>();

@EventHandler
public void onWeapon(PlayerInteractEvent e){
Player p = e.getPlayer();
UUID uuid = p.getUniqueId();
ItemStack itemStack = e.getItem();
if(e.getAction() == Action.RIGHT_CLICK_AIR && !list.contains(uuid) && itemStack.hasItemMeta() && itemStack.getType == Material.STICK){
new WeaponTask(this, 5 , p).runTaskTimer(this, 0, 5);
list.add(uuid);
}
}


WeaponTask.class
コード: 全て選択
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class WeaponTask extends BukkitRunnable{

private final JavaPlugin plugin;
private int counter;
private Player player;

public WeaponTask(JavaPlugin plugin, int counter , Player player){
if(counter > 0){
this.plugin = plugin;
this.player = player;
this.counter = counter;
}else{
throw new IllegalArgumentException("counter には1以上を指定してください。");
}
}

@SuppressWarnings("deprecation")
@Override
public void run(){
if(counter > 0){
player.throwSnowball();
//throwSnowball():これはコードを省略されただけでしょうか…?
player.playSound(player.getLocation(), Sound.BLAZE_HIT, 10, 10);
counter--;
}else{
plugin.getServer().broadcastMessage("ラストカウンター: " + counter);
plugin.getServer().broadcastMessage("END");
plugin.list.remove(player.getUniqueId());
this.cancel();
}
}


1~4に従いコードを記述するとこのようになると思います。

1~4以外で個人的に気になる点がいくつかありましたので合わせて修正させて頂きました。

a: Main#counter - 必要無いのでnew WeaponTask(…)に数値をそのまま記述(呼び出し元でメソッドの引数に基本データ型を使用した場合、メソッドではその値のコピーを受け取ります。単純に値のコピーを渡しているだけなので、メソッド内でその値に変更を加えても、呼び出し元には影響しません)。

b: Main#onWeapon(…) - if文の条件「itemStack.hasItemMeta()がtrue」は==trueを記述する必要無し(代入と見間違えたり、コードが冗長になるため)。

c: WeaponTask#WeaponTask - 条件は分かりやすくrun()と同じ記述にし、最初の代入処理(this.plugin = plugin;)はif文内に他の代入処理と一緒に記述。


追記:

後々思いつきましたがループ処理の終了時間が分かっているなら、onWeapon(…)でlist.remove(uuid)を遅延実行処理するという方法もあります(というかこちらの方が楽)。


指摘に合わせ、丁寧な返信ありがとうございました!
無事解決しました。
アバター
八咫烏
ID:41f9f109
木を殴ってる
 
記事: 21
登録日時: 2014年8月14日(木) 18:06
お住まい: 闇の中

  • (PostNo.318487)

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

投稿記事by 八咫烏 » 2018年7月30日(月) 11:10

詰まってしまって、たびたび質問失礼します。
(上記コード参照)
銃を打つ(雪玉を発射する)たびに残りの弾数表示をItemDisplayNameに表示させたいんですけど
Mainクラスでのアイテムの名前変更はできるんですけど
このMainクラスで取得したアイテムスタックをサブクラスに渡して
サブクラスでそのitemmetaを設定しSetItemmetaをした際に
名前の変更が表示されません。(サブクラスに渡している時点でItemStackが別物として扱われるのでしょうか)
よろしくお願いします。
アバター
八咫烏
ID:41f9f109
木を殴ってる
 
記事: 21
登録日時: 2014年8月14日(木) 18:06
お住まい: 闇の中

  • (PostNo.318817)

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

投稿記事by CYBORG » 2018年8月08日(水) 16:44

特定の剣(アイテム)にエフェクトを追加したいんですが、詰まってしまってできません。
CYBORG
ID:c1b32beb
 

  • (PostNo.318908)

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

投稿記事by amata1219 » 2018年8月10日(金) 17:34

八咫烏 さんが書きました:詰まってしまって、たびたび質問失礼します。
(上記コード参照)
銃を打つ(雪玉を発射する)たびに残りの弾数表示をItemDisplayNameに表示させたいんですけど
Mainクラスでのアイテムの名前変更はできるんですけど
このMainクラスで取得したアイテムスタックをサブクラスに渡して
サブクラスでそのitemmetaを設定しSetItemmetaをした際に
名前の変更が表示されません。(サブクラスに渡している時点でItemStackが別物として扱われるのでしょうか)
よろしくお願いします。


八咫烏さん、こんにちは。
サブクラスに渡そうとItemStackが別物として処理されることはありません。
一応検証に使ったコードがありますので、よければ参考にして下さい。

メインクラス(Check.class)
コード: 全て選択
package amata1219.check;

import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

public class Check extends JavaPlugin implements Listener{

   @Override
   public void onEnable(){
      getServer().getPluginManager().registerEvents(this, this);
   }

   @Override
   public void onDisable(){

   }

   @EventHandler
   public void onInteract(PlayerInteractEvent e){
      ItemStack item = e.getItem();
      if(item != null && item.getType() != Material.AIR){
         setMeta(item);
         System.out.println(item.getItemMeta().getDisplayName());
         new SubCheck().setMeta(item);
         System.out.println(item.getItemMeta().getDisplayName());
         SubCheck.setMetaa(item);
         System.out.println(item.getItemMeta().getDisplayName());
      }
   }

   public void setMeta(ItemStack item){
      ItemMeta meta = item.getItemMeta();
      meta.setDisplayName("GRASS");
      item.setItemMeta(meta);
   }

}


サブクラス(SubCheck.class)

コード: 全て選択
package amata1219.check;

import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

public class SubCheck {

   public void setMeta(ItemStack item){
      ItemMeta meta = item.getItemMeta();
      meta.setDisplayName("DIRT");
      item.setItemMeta(meta);
   }

   public static void setMetaa(ItemStack item){
      ItemMeta meta = item.getItemMeta();
      meta.setDisplayName("PODZOL");
      item.setItemMeta(meta);
   }

}


コンソール(出力結果)

コード: 全て選択
[17:25:43] [Server thread/INFO]: GRASS
[17:25:43] [Server thread/INFO]: DIRT
[17:25:43] [Server thread/INFO]: PODZOL


各メソッドを単体で実行した時も問題なく、ゲーム内でも表示名が変更されました。
もしこれでも解決しないようでしたらソースコードを再度貼り付けて下さいー。

CYBORG さんが書きました:特定の剣(アイテム)にエフェクトを追加したいんですが、詰まってしまってできません。


CYBORGさん、こんにちは。
エンチャントの追加方法はプラグインチュートリアルに記載されています。
Plugin Tutorial - Minecraft Modding Wiki #エンチャント
調べればすぐに出てくる内容ですので、最低限ご自身でお調べになった上で質問して下さい_(:3 ∠ )_。
アバター
amata1219
ID:b3820ecb
大工さん
 
記事: 59
登録日時: 2016年11月18日(金) 16:46
お住まい: 愛知県

1つ前へ

Return to 質問:開発・制作関連

x