问题
I'm making a MagicBows plugin where you can select spells by doing left click and if you shoot the bow the selected spell will give its effect, but the selector doesn't work. I'm not sure how to fix this.
This is my Main file:
package me.Pixel;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin implements Listener {
public Main plugin;
public List<String> spells = new ArrayList<String>();
public getTargets getTargets = new getTargets();
private Arrow arrow;
public LightningShot LightningShot = new LightningShot(arrow);
public ExplosionShot ExplosionShot = new ExplosionShot(arrow);
@Override
public void onEnable() {
plugin = this;
this.getServer().getPluginManager().registerEvents(this, this);
getCommand("bow").setExecutor(new BowCommand());
spells.add("LightningShot");
spells.add("ExplosionShot");
}
@EventHandler
public void onEntityShootBow(EntityShootBowEvent event) {
if(event.getProjectile() instanceof Arrow) {
Arrow arrow = (Arrow) event.getProjectile();
new LightningShot(arrow).runTaskTimer(this, 0, 1);
}
}
@EventHandler
public void onEntityShootBow1(EntityShootBowEvent event) {
if(event.getProjectile() instanceof Arrow) {
Arrow arrow = (Arrow) event.getProjectile();
new ExplosionShot(arrow).runTaskTimer(this, 0, 1);
}
}
@EventHandler
public void onClick(PlayerInteractEvent e) {
if(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK) {
Player p = e.getPlayer();
ItemStack stack = p.getItemInHand();
if(stack != null && stack.getType() == Material.BOW && stack.hasItemMeta() && stack.getItemMeta().getDisplayName().equals(ChatColor.RED + "Bow")) {
int SpellSelected = stack.getDurability();
if (SpellSelected < 2) {
stack.setDurability((short) (SpellSelected + 1));
p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, ParticleEffect.SNOW_SHOVEL);
} else {
stack.setDurability((short) 0);
}
ChatUtilities.sendMessage(p, "Selected: " + spells.get(SpellSelected));
}
}
if(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Player p = e.getPlayer();
ItemStack stack = p.getItemInHand();
if(stack != null && stack.getType() == Material.BOW && stack.hasItemMeta() && stack.getItemMeta().getDisplayName().equals(ChatColor.RED + "Bow")) {
int SpellSelected = stack.getDurability();
if(SpellSelected == 1) {
this.LightningShot.run();
} else if (SpellSelected == 2) {
this.ExplosionShot.run();
}
}
}
}
}
And this is my first spell: LightningShot
package me.Pixel;
import org.bukkit.entity.Arrow;
import org.bukkit.scheduler.BukkitRunnable;
public class LightningShot extends BukkitRunnable {
private Arrow arrow;
private int tick = 1;
public LightningShot(Arrow arrow) {
this.arrow = arrow;
}
@Override
public void run() {
if (arrow == null || arrow.isOnGround() || tick++ > 20 * 10) {
this.cancel();
} else {
arrow.getWorld().strikeLightning(arrow.getLocation());
}
}
}
And this is my second spell: ExplosionShot
(I'm trying to make an "explosion wave")
package me.Pixel;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.entity.Arrow;
import org.bukkit.scheduler.BukkitRunnable;
public class ExplosionShot extends BukkitRunnable {
private Arrow arrow;
private int tick = 1;
public ExplosionShot(Arrow arrow) {
this.arrow = arrow;
}
@Override
public void run() {
if (arrow == null || arrow.isOnGround() || tick++ > 20 * 10) {
this.cancel();
} else {
arrow.getWorld().createExplosion(arrow.getLocation(), 1);
FireworkEffect.builder().with(Type.BALL).withColor(Color.AQUA).withFade(Color.FUCHSIA).flicker(true).trail(true);
}
}
}
Also, somehow the ExplosionShot
and LightningShot
are combining so the LightningShot has explosions at the arrow's trail?
So if a user clicks their right mouse button there should be a message in chat that says:
[X] (this is my chat utility so this is nothing to worry about) Selected: LightningShot
And if they click their right mouse button again:
[X] Selected: ExplosionShot
And then it should create this "explosion wave" as it's following the arrow, but I can't get the scroller to work.
回答1:
I suggest that instead of using a BukkitRunnable, you make a new abstract class (ArrowSpell?) and make LightningShot and ExplosiveShot extend that class. You can add abstract methods to ArrowSpell which LightningShot and ExplosiveShot must implement, such as onShoot(EntityShootBowEvent) or onHit(EntityDamageByEntityEvent) which it does not listen for, but get passed to it. I actually did something similar, you can see an example here: https://github.com/ViperLordX/Divinity/tree/master/src/redempt/divinity/ability/modifier
This way, you don't need to use a BukkitRunnable, which is, from what I see, a very awkward way of doing it.
来源:https://stackoverflow.com/questions/36954963/spell-scroller-doesnt-work