"I have a question. My plugin has two files, FireballPlugin.java (main program) and BlockReset.java (subprogram). However, when I write Bukkit.getPluginManager().registerEvents(new BlockReset(), this); in the main program to register BlockReset.java, Intellij does not show any errors, but it doesn't work in the game. However, if I merge Fireball.java and BlockReset.java together, it works. What could be the issue?"
Here is my code:
[main program]:
package com.badlyac.NewFireballPlugin;
import com.badlyac.NewFireballPlugin.BlockExplode.BlockReset;
import com.badlyac.NewFireballPlugin.PlayerResistance.AntiFire;
import org.bukkit.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
public class FireballPlugin extends JavaPlugin implements Listener {
private double horizontalKnockback;
private double verticalKnockback;
private double Speed;
private int Power;
private boolean Incendiary;
private boolean comboMode;
@SuppressWarnings("FieldCanBeLocal")
private boolean destroyBlocks;
private boolean fallDamage;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
Bukkit.getPluginManager().registerEvents(new GiveItemWhenJoin(), this);
Bukkit.getPluginManager().registerEvents(new AntiFire(),this);
Bukkit.getPluginManager().registerEvents(new BlockReset(),this);
loadConfig();
getLogger().info(ChatColor.GREEN + "FireballPlugin has been enabled!");
}
@Override
public void onDisable() {
getLogger().info(ChatColor.RED + "FireballPlugin has been disabled!");
}
@EventHandler
public void Fireball(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.hasPermission("fireball.admin")) {
if (player.getItemInHand().getType() == Material.FIREBALL) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Location loc = player.getLocation();
Vector dir = loc.getDirection().normalize();
Fireball fireball = player.getWorld().spawn(loc.add(0, 1.6, 0), Fireball.class);
fireball.setVelocity(dir.multiply(0.5 + Speed));
fireball.setShooter(player);
fireball.setIsIncendiary(Incendiary);
fireball.setYield(1 + Power);
}
}
}
Material material = player.getInventory().getItemInHand().getType();
if (material == Material.FIREBALL && player.hasPermission("fireball.admin")) {
event.setCancelled(true);
}
}
@EventHandler
public void SmallFireball(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.hasPermission("fireball.admin")) {
if (player.getItemInHand().getType() == Material.BLAZE_POWDER) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Location loc = player.getLocation();
Vector dir = loc.getDirection();
SmallFireball smallFireball = player.getWorld().spawn(loc.add(0, 1.6, 0), SmallFireball.class);
smallFireball.setVelocity(dir.multiply(0.5 + Speed));
smallFireball.setShooter(player);
smallFireball.setYield(Power);
smallFireball.setIsIncendiary(Incendiary);
}
}
}
Material material = player.getInventory().getItemInHand().getType();
if (material == Material.BLAZE_POWDER && player.hasPermission("fireball.admin")) {
event.setCancelled(true);
}
}
@EventHandler
public void WitherSKull(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.hasPermission("fireball.admin")) {
if (player.getItemInHand().getType() == Material.SKULL_ITEM) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Location loc = player.getLocation();
Vector dir = loc.getDirection();
WitherSkull witherSkull = player.getWorld().spawn(loc.add(0, 1.6, 0), WitherSkull.class);
witherSkull.setVelocity(dir.multiply(0.5 + Speed));
witherSkull.setShooter(player);
witherSkull.setYield(Power);
witherSkull.setIsIncendiary(Incendiary);
}
}
}
Material material = player.getInventory().getItemInHand().getType();
if (material == Material.SKULL_ITEM && player.getItemInHand().getDurability() == 1&& player.hasPermission("fireball.admin")) {
event.setCancelled(true);
}
}
@EventHandler
public void onTntLaunch(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.hasPermission("fireball.admin")) {
Material heldMaterial = getHeldMaterial(player);
if (heldMaterial == Material.TNT) {
if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
TNT(player);
event.setCancelled(true);
}
}
}
Material material = player.getInventory().getItemInHand().getType();
if (material == Material.TNT && player.hasPermission("fireball.admin")){
event.setCancelled(true);
}
}
private Material getHeldMaterial(Player player) {
ItemStack heldItem = player.getItemInHand();
return heldItem.getType();
}
private void TNT(Player player) {
TNTPrimed tnt = player.getWorld().spawn(player.getLocation(), TNTPrimed.class);
tnt.setFuseTicks(50);
double tntSpeed = 1.3;
tnt.setVelocity(player.getLocation().getDirection().multiply(tntSpeed));
tnt.setYield(1 + Power);
tnt.setIsIncendiary(Incendiary);
}
@EventHandler
public void onExplosion(EntityExplodeEvent event) {
if (event.getEntity() instanceof TNTPrimed) {
handleTNTExplosion(event);
} else if (event.getEntity() instanceof Fireball) {
handleFireballExplosion(event);
} else if(event.getEntity() instanceof WitherSkull){
handleWitherSkullExplosion(event);
}
}
private void handleTNTExplosion(EntityExplodeEvent event) {
if (!destroyBlocks) {
event.blockList().clear();
}
}
private void handleFireballExplosion(EntityExplodeEvent event) {
if (!destroyBlocks) {
event.blockList().clear();
}
}
private void handleWitherSkullExplosion(EntityExplodeEvent event) {
if (!destroyBlocks) {
event.blockList().clear();
}
}
@EventHandler
public void onEntityDamage(EntityDamageEvent event) {
if (event.getEntity() instanceof Player && event.getCause() == EntityDamageEvent.DamageCause.FALL) {
if (!fallDamage) {
event.setCancelled(true);
}
}
}
public void loadConfig() {
saveDefaultConfig();
FileConfiguration config = getConfig();
horizontalKnockback = config.getDouble("fireball.knockback.horizontalKnockback",5.0);
verticalKnockback = config.getDouble("fireball.knockback.verticalKnockback",-2.5);
Speed =config.getDouble("fireball.Speed",1.5);
Power = config.getInt("fireball.Power",3);
Incendiary = config.getBoolean("fireball.Incendiary",false);
comboMode = config.getBoolean("Combo",false);
destroyBlocks = config.getBoolean("fireball.destroyBlocks" , false);
fallDamage = config.getBoolean("fallDamage", false);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (label.equalsIgnoreCase("fireball")) {
if (args.length == 8) {
try {
double f1 = Double.parseDouble(args[0]);
double f2 = Double.parseDouble(args[1]);
double f3 = Double.parseDouble(args[2]);
int f4 = Integer.parseInt(args[3]);
boolean f5 = Boolean.parseBoolean(args[4]);
boolean f6 = Boolean.parseBoolean(args[5]);
boolean f7 = Boolean.parseBoolean(args[6]);
boolean f8 = Boolean.parseBoolean(args[7]);
horizontalKnockback = f1;
verticalKnockback = f2;
Speed = f3;
Power = f4;
Incendiary = f5;
comboMode = f6;
destroyBlocks = f7;
fallDamage = f8;
setMaxNoDamageTicks(comboMode);
FileConfiguration config = getConfig();
config.set("fireball.knockback.horizontalKnockback", horizontalKnockback);
config.set("fireball.knockback.verticalKnockback", verticalKnockback);
config.set("fireball.Speed", Speed);
config.set("fireball.Power", Power);
config.set("fireball.Incendiary", Incendiary);
config.set("Combo", comboMode);
config.set("fireball.destroyBlocks", destroyBlocks);
config.set("fireball.fallDamage", fallDamage);
saveConfig();
sender.sendMessage(
ChatColor.GREEN + "Fireball settings updated: " + " set vertical:" + verticalKnockback + " set horizontal:" + horizontalKnockback + " set Speed:" + Speed + " set Power:" + Power + " set Incendiary:" + Incendiary + " set ComboMode:" + comboMode + " set DestroyBlocks:" + destroyBlocks + " set FallDamage:" + fallDamage
);
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + "Invalid value! Please enter the correct number!");
}
} else {
Player player = (Player) sender;
player.sendMessage(ChatColor.RED + "Command usage: /fireball <horizontalKnockback> <verticalKnockback> <Speed> <Power> <Incendiary (true or false)> <ComboMode (true or false)> <DestroyBlocks (true or false)> <FallDamage (true or false)>");
}
return true;
}
return false;
}
private void setMaxNoDamageTicks(boolean comboMode) {
int ticks = comboMode ? 2 : 11;
for (World world : Bukkit.getWorlds()) {
for (LivingEntity entity : world.getLivingEntities()) {
entity.setMaximumNoDamageTicks(ticks);
}
}
}
@EventHandler
public void onEntityDamagebyEntity(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Fireball && event.getEntity() instanceof LivingEntity) {
Fireball fireball = (Fireball) event.getDamager();
LivingEntity livingEntity = (Player) event.getEntity();
livingEntity.damage(0, fireball);
Vector fireballVelocity = fireball.getVelocity().normalize();
Vector knockbackVector = new Vector(
fireballVelocity.getX() * horizontalKnockback,
fireballVelocity.getY() * (verticalKnockback * -1),
fireballVelocity.getZ() * horizontalKnockback
);
livingEntity.setVelocity(knockbackVector);
if (livingEntity.getLocation().distanceSquared(fireball.getLocation()) <= fireball.getYield() * fireball.getYield()) {
livingEntity.setVelocity(knockbackVector);
}
event.setDamage(0.0);
} else if (event.getDamager() instanceof TNTPrimed && event.getEntity() instanceof LivingEntity) {
if (event.getDamager() instanceof Fireball && event.getEntity() instanceof LivingEntity) {
TNTPrimed tntPrimed = (TNTPrimed) event.getDamager();
LivingEntity livingEntity = (Player) event.getEntity();
livingEntity.damage(0, tntPrimed);
Vector fireballVelocity = tntPrimed.getVelocity().normalize();
Vector knockbackVector = new Vector(
fireballVelocity.getX() * horizontalKnockback,
fireballVelocity.getY() * (verticalKnockback* -1),
fireballVelocity.getZ() * horizontalKnockback
);
livingEntity.setVelocity(knockbackVector);
if (livingEntity.getLocation().distanceSquared(tntPrimed.getLocation()) <= tntPrimed.getYield() * tntPrimed.getYield()) {
livingEntity.setVelocity(knockbackVector);
}
}
event.setDamage(0.0);
}
}
@EventHandler
public void onProjectileHit(ProjectileHitEvent event) {
if (event.getEntityType() == EntityType.FIREBALL) {
Fireball fireball = (Fireball) event.getEntity();
if (fireball.getShooter() instanceof Player) {
Player shooter = (Player) fireball.getShooter();
Location explosionLocation = fireball.getLocation();
if (shooter.getLocation().distance(explosionLocation) <= 1.5) {
Vector selfKnockback = shooter.getLocation().getDirection().multiply(Speed * horizontalKnockback);
selfKnockback.setY(verticalKnockback);
shooter.setVelocity(selfKnockback);
}
for (Entity entity : explosionLocation.getWorld().getNearbyEntities(explosionLocation, 1.5, 1.5, 1.5)) {
if (entity instanceof Player) {
Player target = (Player) entity;
if (!target.getUniqueId().equals(shooter.getUniqueId())) {
Vector knockback = target.getLocation().toVector().subtract(explosionLocation.toVector()).normalize().multiply(Speed * horizontalKnockback);
knockback.setY(verticalKnockback);
target.setVelocity(knockback);
}
}
}
}
}
if (event.getEntityType() == EntityType.WITHER_SKULL) {
WitherSkull witherSkull = (WitherSkull) event.getEntity();
if (witherSkull.getShooter() instanceof Player) {
Player shooter = (Player) witherSkull.getShooter();
Location explosionLocation = witherSkull.getLocation();
if (shooter.getLocation().distance(explosionLocation) <= 1.5) {
Vector selfKnockback = shooter.getLocation().getDirection().multiply(1 * horizontalKnockback);
selfKnockback.setY(verticalKnockback);
shooter.setVelocity(selfKnockback);
}
for (Entity entity : explosionLocation.getWorld().getNearbyEntities(explosionLocation, 1.5, 1.5, 1.5)) {
if (entity instanceof Player) {
Player target = (Player) entity;
if (!target.getUniqueId().equals(shooter.getUniqueId())) {
Vector knockback = target.getLocation().toVector().subtract(explosionLocation.toVector()).normalize().multiply(1 * horizontalKnockback);
knockback.setY(verticalKnockback);
target.setVelocity(knockback);
}
}
}
}
}
}
}
[sub program]:
package com.badlyac.NewFireballPlugin.BlockExplode;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.Material;
import java.util.HashMap;
import java.util.Map;
public class BlockReset extends JavaPlugin implements Listener {
final Map<EntityExplodeEvent, Map<Block, BlockData>> explosionsData = new HashMap<>();
@EventHandler
public void onEntityExplode(EntityExplodeEvent event) {
if (event.getEntity() instanceof TNTPrimed || event.getEntity() instanceof org.bukkit.entity.WitherSkull || event.getEntity() instanceof Fireball) {
saveBlockData(event);
restoreBlocksLater(event);
}
}
@SuppressWarnings("deprecation")
private void saveBlockData(EntityExplodeEvent event) {
Map<Block, BlockData> blockDataBackup = new HashMap<>();
for (Block block : event.blockList()) {
BlockState blockState = block.getState();
BlockData blockData = new BlockData(blockState.getType(), blockState.getData().getData());
blockDataBackup.put(block, blockData);
}
this.explosionsData.put(event, blockDataBackup);
}
private void restoreBlocksLater(final EntityExplodeEvent event) {
(new BukkitRunnable() {
public void run() {
BlockReset.this.restoreBlocks(event);
}
}).runTaskLater(this, 60L);
}
@SuppressWarnings("deprecation")
private void restoreBlocks(EntityExplodeEvent event) {
if (this.explosionsData.containsKey(event)) {
Map<Block, BlockData> blockDataBackup = this.explosionsData.get(event);
for (Block block : event.blockList()) {
if (blockDataBackup.containsKey(block)) {
BlockData blockData = blockDataBackup.get(block);
block.setType(blockData.getType());
block.setData(blockData.getData());
block.getState().update(true, false);
}
}
this.explosionsData.remove(event);
}
}
private static class BlockData {
private final Material type;
private final byte data;
public BlockData(Material type, byte data) {
this.type = type;
this.data = data;
}
public Material getType() {
return this.type;
}
public byte getData() {
return this.data;
}
}
}
I tried write them together , it works. But it will make the program looks very complex.
I see multiple issues or at least a couple of them are things I wouldn't handle that way.
1. Listener Convention
Normally to register listeners you write
Most likely it doesn't hurt anything to do it the way you are. It's just convention. It's probably best to stick with convention.
2. Plugin Instance Issues - I am certain this is causing the problem
ONLY extend the class from
JavaPluginin the main class. DO NOT extend it anywhere else. This means get rid ofextends JavaPluginin yourBlockResetclass. If you do this, you're basically making two plugins inside your one JAR. I don't think that will work. :)I see why you make the
BlockResetclass extendJavaPluginnow. You need instances of your plugin. To do this properly add the following to your main class:Also, add this in the
onEnablein your main class:That should be the first thing in your
onEnable. What this does is make it so can doinstead of trying to use
JavaPluginandthiswhenever you need a plugin instance in yourBlockResetclass now.Replace the
thisin theBlockResetclass hereThe improved version of that method would be
Get rid of all those other this'es. You don't need that because Java knows you're talking about a variable or method in that class. If you were talking about a variable in another class you would put
OtherClass.variable. The only reasonthis.whateverexists is for constructors.3. Artifact Naming Convention
Normally the plugin folder is in lower caps. That's not a big deal at all, but it's also convention. If you're using a build system, which you should be, you must make it in lower caps. I don't think you can use one with capitals in the artifact name. If you're using the IDE called IntelliJ and the
Minecraft Developmentplugin, it's all automatically made.The layout should normally be
com.example.yourplugin.YourPlugin, so like this:com.badlyac.newfireballplugin.FireballPlugin.But, you have it like this:
com.badlyac.NewFireballPlugin.FireballPlugin.Fixed classes
Here are your fixed classes by just fixing the first two issues. You can decide whether to fix the third issue or not.
Main class:
Sub-program:
Sheese, that's a lot of writing. Hope that fixes your problem and clears things up!