Refactored listener into multiple classes
Also added a class for egg-related helper methods. Deleted the now-redundant EggRespawn class.
This commit is contained in:
parent
c48141239f
commit
3dfecb5226
10 changed files with 939 additions and 774 deletions
|
|
@ -9,6 +9,9 @@ import org.bukkit.Particle;
|
|||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Misc helper methods relating to player notification
|
||||
*/
|
||||
public class Announcement {
|
||||
public static void announce(String message, Logger logger) {
|
||||
List<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||
|
|
@ -23,7 +26,10 @@ public class Announcement {
|
|||
logger.info(String.format("Told %d player(s) \"%s\"", playersNotified, message));
|
||||
}
|
||||
|
||||
public static void claimEggEffects(Player Player){
|
||||
/**
|
||||
* Creates sound/particle effects to let the given player know that they have claimed the dragon egg
|
||||
*/
|
||||
public static void ShowEggClaimEffects(Player Player){
|
||||
Player.playSound(Player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 10, 0);
|
||||
Player.spawnParticle(Particle.SPELL_WITCH, Player.getLocation(), 50, 0.3, 0.1, 0.3);
|
||||
Player.spawnParticle(Particle.PORTAL, Player.getLocation(), 50, 0.3, 0.1, 0.3);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,297 @@
|
|||
package io.github.J0hnL0cke.egghunt.Controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityCreatePortalEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.ItemDespawnEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data.Egg_Storage_Type;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Egg;
|
||||
|
||||
/**
|
||||
* Listens for Bukkit events related to destruction of the dragon egg
|
||||
* Prevents destruction or respawns the egg, depending on config settings
|
||||
*/
|
||||
public class EggDestroyListener implements Listener {
|
||||
private Logger logger;
|
||||
private Configuration config;
|
||||
private Data data;
|
||||
|
||||
|
||||
public EggDestroyListener(Logger logger, Configuration config, Data data) {
|
||||
this.logger = logger;
|
||||
this.config = config;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for the egg being destroyed
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDamageEvent(EntityDamageEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity.getType().equals(EntityType.DROPPED_ITEM)) {
|
||||
ItemStack item = ((Item)entity).getItemStack();
|
||||
if (Egg.isEgg(item)) {
|
||||
//make sure item is destroyed to prevent dupes
|
||||
event.getEntity().remove();
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that the egg is destroyed if the egg item dies
|
||||
* Also respawns the egg when the dragon is killed
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
//if the egg item dies, notify that it has been destroyed
|
||||
if (event.getEntityType().equals(EntityType.DROPPED_ITEM)) {
|
||||
if (Egg.isEgg((ItemStack) event.getEntity())) {
|
||||
//remove just in case to prevent dupes
|
||||
event.getEntity().remove();
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
else if (event.getEntity().getType().equals(EntityType.ITEM_FRAME)
|
||||
|| event.getEntity().getType().equals(EntityType.GLOW_ITEM_FRAME)) {
|
||||
ItemFrame frame = (ItemFrame) event.getEntity();
|
||||
if (Egg.isEgg(frame.getItem())) {
|
||||
frame.setItem(null); //make sure the item is destroyed
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
//if the dragon is killed, respawn the egg
|
||||
else if (config.getRespawnEgg()) {
|
||||
if (data.getEggType() == Egg_Storage_Type.DNE) {
|
||||
//if the egg does not exist
|
||||
if (event.getEntityType().equals(EntityType.ENDER_DRAGON)) {
|
||||
//if the dragon is killed
|
||||
if (config.getEndWorld().getEnderDragonBattle().hasBeenPreviouslyKilled()) {
|
||||
//if the dragon has already been beaten
|
||||
respawnEgg();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop portals from removing the egg
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onCreatePortal(EntityCreatePortalEvent event) {
|
||||
//not specific to any particular creation reason because multiple events could cause the egg to be removed (obby platform regen, gateway portal spawning, stronghold portal activation)
|
||||
boolean egg_affected = false;
|
||||
Location l = null;
|
||||
List<BlockState> blocks = event.getBlocks();
|
||||
console_log(String.format("blocks: %s", blocks.toString()));
|
||||
for (BlockState blockState : blocks) {
|
||||
console_log(String.format("Block update at %s: from %s to %s", blockState.getLocation(),
|
||||
blockState.getBlock().getType(), blockState.getType()));
|
||||
if (blockState.getBlock().getType().equals(Material.DRAGON_EGG)) {
|
||||
egg_affected = true;
|
||||
l = blockState.getLocation();
|
||||
//extra check to make sure egg is removed
|
||||
blockState.getBlock().setType(Material.AIR);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (egg_affected) {
|
||||
String entityName = "Unknown entity";
|
||||
if (event.getEntity() != null) {
|
||||
if (event.getEntity().getCustomName() != null) {
|
||||
entityName = event.getEntity().getCustomName();
|
||||
}
|
||||
}
|
||||
console_log(String.format("%s tried to overwrite egg with a portal", entityName));
|
||||
data.resetEggOwner(false);
|
||||
if (l != null) {
|
||||
data.updateEggLocation(Egg.spawnEggItem(l, config, data));
|
||||
} else {
|
||||
console_log("Could not spawn egg item! Invalid block location.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent the egg from despawning
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onDespawn(ItemDespawnEvent event) {
|
||||
if (Egg.isEgg(event.getEntity().getItemStack())) {
|
||||
event.setCancelled(true);
|
||||
//set the age back to 1 so it doesn't try to despawn every tick
|
||||
event.getEntity().setTicksLived(1);
|
||||
console_log("Canceled egg despawn");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent growing mushrooms from overwriting the egg
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onGrow(StructureGrowEvent event) {
|
||||
boolean destroy = false;
|
||||
if (event.getSpecies().equals(TreeType.RED_MUSHROOM)) {
|
||||
List<BlockState> blocks = event.getBlocks();
|
||||
for (BlockState blockState : blocks) {
|
||||
Block block = blockState.getBlock();
|
||||
if (Egg.isEgg(block)) {
|
||||
destroy = true;
|
||||
if (!config.getEggInvincible()) { //if egg will be replaced, make sure it gets removed
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} else {
|
||||
if (blockState instanceof Container) { //TODO exclude item frames, which aren't destroyed by this
|
||||
Container cont = (Container) blockState;
|
||||
if (cont.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
destroy = true;
|
||||
cont.getInventory().remove(Material.DRAGON_EGG); //make sure egg is removed from container
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (destroy) {
|
||||
if (config.getEggInvincible()) {
|
||||
event.setCancelled(true);
|
||||
Player p = event.getPlayer();
|
||||
if (p != null) {
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_LAND, 1, 1);
|
||||
p.sendMessage("Cannot grow mushroom: obstructed by dragon egg");
|
||||
p.setCooldown(Material.BONE_MEAL, 100);
|
||||
console_log(String.format("%s tried to mushroom the dragon egg", p.getName()));
|
||||
}
|
||||
} else {
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel events that damage the egg item if enabled in config
|
||||
* TODO: figure out if this is still needed, since when active, egg is set to be invlunerable
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onConsiderEntityDamageEvent(EntityDamageEvent event) {
|
||||
if (config.getEggInvincible()) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity.getType().equals(EntityType.DROPPED_ITEM)) {
|
||||
if (Egg.isEgg((Item) entity)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a portal is updated, check if the egg will be replaced
|
||||
*/
|
||||
private void checkPortalBlocks() {
|
||||
//TODO there has to be a better way to do this
|
||||
//Check end platform
|
||||
Location l1 = new Location(config.getEndWorld(), 102, 48, 2);
|
||||
Location l2 = new Location(config.getEndWorld(), 98, 51, -2);
|
||||
Location res = checkBlockMaterialFromLocation(config.getEndWorld(), Material.DRAGON_EGG, l1, l2);
|
||||
if (res != null) {
|
||||
portalOverwriteEgg(res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data and spawn a new egg when the egg is overwritten with a portal
|
||||
*/
|
||||
private void portalOverwriteEgg(Location res) {
|
||||
res.getBlock().setType(Material.AIR);
|
||||
console_log("Egg was overwritten with a portal");
|
||||
if (config.getEggInvincible()) {
|
||||
console_log("Spawning new egg");
|
||||
data.updateEggLocation(Egg.spawnEggItem(res, config, data));
|
||||
} else {
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks blocks within the cube created by the given locations.
|
||||
* Returns the first location corresponding to the block found with the given material.
|
||||
* Returns null if no matching block is found or locations are in different worlds.
|
||||
*/
|
||||
private static Location checkBlockMaterialFromLocation(World w, Material m, Location l1, Location l2) {
|
||||
if (l1.getWorld().equals(l2.getWorld())) {
|
||||
for (int x = l1.getBlockX(); x < l2.getBlockX(); x++) {
|
||||
for (int y = l1.getBlockY(); y < l2.getBlockY(); y++) {
|
||||
for (int z = l1.getBlockZ(); z < l2.getBlockZ(); z++) {
|
||||
if (w.getBlockAt(x, y, z).getType().equals(m)) {
|
||||
return new Location(w, x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alerts when the egg is destroyed and respawns it if needed
|
||||
*/
|
||||
public void eggDestroyed() {
|
||||
announce("The dragon egg has been destroyed!");
|
||||
data.resetEggOwner(false);
|
||||
|
||||
if (config.getRespawnEgg()) {
|
||||
if (config.getRespawnImmediately()) {
|
||||
respawnEgg();
|
||||
} else {
|
||||
data.resetEggLocation();
|
||||
announce("It will respawn the next time the dragon is defeated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respawns the dragon egg in the end
|
||||
*/
|
||||
private void respawnEgg() {
|
||||
data.updateEggLocation(Egg.respawnEgg(config));
|
||||
announce("The dragon egg has spawned in the end!");
|
||||
}
|
||||
|
||||
private void announce(String msg) {
|
||||
Announcement.announce(msg, logger);
|
||||
}
|
||||
|
||||
private void console_log(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,735 +0,0 @@
|
|||
package io.github.J0hnL0cke.egghunt.Controller;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.inventory.*;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.event.world.WorldSaveEvent;
|
||||
import org.bukkit.inventory.AbstractHorseInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data.Egg_Storage_Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class EggHuntListener implements Listener {
|
||||
|
||||
/*Store either the location of the block/inventory it is stored in,
|
||||
or store a reference to the entity that is holding the egg.
|
||||
Stored entity is separate from the owner because the egg can be stored in any entity
|
||||
(ex: held by a zombie or item frame), but only players can "own" the egg*/
|
||||
|
||||
private Logger logger;
|
||||
private Configuration config;
|
||||
private Data data;
|
||||
|
||||
|
||||
public EggHuntListener(Logger logger, Configuration config, Data data) {
|
||||
this.logger = logger;
|
||||
this.config = config;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onAutosave(WorldSaveEvent event) {
|
||||
//TODO: don't save data until an autosave happens
|
||||
data.saveData();
|
||||
}
|
||||
|
||||
// Drop egg if a player logs off with it in their inventory
|
||||
//TODO: check if item spawn and item drop events overlap, and check which can be replaced
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onLogoff(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
// Check if the player has a dragon egg
|
||||
if (player.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
|
||||
// Set owner and remove
|
||||
data.setEggOwner(player); //TODO is this necessary? player will likely already be owner
|
||||
player.getInventory().remove(Material.DRAGON_EGG);
|
||||
|
||||
// Drop it on the floor and set its location
|
||||
//TODO use drop egg method in EggRespawn
|
||||
Item egg_drop = event.getPlayer().getWorld().dropItem(player.getLocation(), new ItemStack(Material.DRAGON_EGG));
|
||||
data.updateEggLocation(egg_drop);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle egg removal and drop upon the player dropping it
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onItemDrop(PlayerDropItemEvent event) {
|
||||
|
||||
Item item = event.getItemDrop();
|
||||
ItemStack stack=item.getItemStack();
|
||||
|
||||
// Check if the dropped item is the egg
|
||||
if(isEgg(stack)) {
|
||||
data.setEggOwner(event.getPlayer());
|
||||
data.updateEggLocation(item);
|
||||
makeEggInvulnerable(event.getItemDrop());
|
||||
}
|
||||
}
|
||||
|
||||
// No handler to check if the falling egg drops an item, so we have to check every item spawn
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onItemSpawn(ItemSpawnEvent event) {
|
||||
|
||||
// Check if the spawned item is the egg
|
||||
Item item = event.getEntity();
|
||||
|
||||
if (isEgg(item)) {
|
||||
data.updateEggLocation(item);
|
||||
makeEggInvulnerable(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being picked up by an entity
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPickupItem(EntityPickupItemEvent event) {
|
||||
// Check if item picked up is an egg
|
||||
if (isEgg(event.getItem())) {
|
||||
data.updateEggLocation(event.getEntity());
|
||||
if (event.getEntity() instanceof Player) {
|
||||
data.setEggOwner((Player)event.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being picked up by a container (hopper or hopper minecart)
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onHopperCollect(InventoryPickupItemEvent event) {
|
||||
|
||||
// Check if the dragon egg was picked up
|
||||
ItemStack item = event.getItem().getItemStack();
|
||||
|
||||
if (isEgg(item)) {
|
||||
//check if the inventory has open space
|
||||
//TODO test this with edge cases for hopper pull/push
|
||||
if (event.getInventory().firstEmpty() != -1 || event.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
data.updateEggLocation(event.getInventory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the player closes an inventory,
|
||||
* check the player and the inventory for the egg when the inventory closes.
|
||||
* This removes the need to check specifics about a player's clicks in an inventory
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onInventoryClose(InventoryCloseEvent event) {
|
||||
|
||||
Player player = (Player) event.getPlayer();
|
||||
Inventory otherInv = event.getInventory();
|
||||
|
||||
//force an egg in the ender chest to be dropped if enabled in config and if the player is not in creative
|
||||
if (otherInv.getType().equals(InventoryType.ENDER_CHEST)){
|
||||
if (config.getDropEnderchestedEgg() && player.getGameMode() != GameMode.CREATIVE) {
|
||||
if (otherInv.contains(Material.DRAGON_EGG)) {
|
||||
ItemStack egg = otherInv.getItem(otherInv.first(Material.DRAGON_EGG));
|
||||
Location playerLoc = player.getLocation();
|
||||
otherInv.remove(egg);
|
||||
Item i = playerLoc.getWorld().dropItem(playerLoc, egg); //TODO use drop item function
|
||||
console_log(String.format(
|
||||
"Dropped the dragon egg on the ground since %s had it in their ender chest.",
|
||||
player.getName()));
|
||||
console_log(
|
||||
"Set ignore_echest_egg to \"true\" in the config file to disable this feature.");
|
||||
data.updateEggLocation(i);
|
||||
}
|
||||
}
|
||||
//whether the egg is dropped or not, ignore all other checking
|
||||
//since either egg should be dropped and location has already been updated
|
||||
//or it should not move and this egg should be ignored entirely
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
//if the player has the egg in their inventory, it will stay there
|
||||
data.updateEggLocation(player);
|
||||
data.setEggOwner(player);
|
||||
|
||||
} else if (otherInv.contains(Material.DRAGON_EGG)) {
|
||||
|
||||
if (otherInv.getType() != InventoryType.PLAYER) { //TODO check how this affects player viewing own inventory (egg on head/offhand?)
|
||||
|
||||
if (otherInv.getHolder() instanceof Container || otherInv instanceof AbstractHorseInventory) { //not instanceof entity- chest llama but not wandering trader
|
||||
//this is a container (chest, furnace, hopper minecart, etc), so the egg will remain here when the inventory is closed
|
||||
data.updateEggLocation(otherInv);
|
||||
|
||||
|
||||
} else {
|
||||
//this is not a container (anvil, crafting table, villager, etc), so it will move back to the player's inventory
|
||||
//note- if the player's inventory is full, it will instead drop as an item, which will trigger the item drop event
|
||||
data.updateEggLocation(player);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onInventoryMove (InventoryMoveItemEvent event) {
|
||||
//called when an inventory item is moved between blocks (hoppers, dispensers, etc)
|
||||
//check if the item being moved is the egg
|
||||
if (isEgg(event.getItem())) {
|
||||
if (event.getDestination().firstEmpty() != -1 || event.getDestination().contains(Material.DRAGON_EGG)) {
|
||||
data.updateEggLocation(event.getDestination());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle the egg being placed as a block
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockPlace (BlockPlaceEvent event) {
|
||||
if (isEgg(event.getBlock())) {
|
||||
data.updateEggLocation(event.getBlock());
|
||||
data.setEggOwner(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being placed in an item frame
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onInteract(PlayerInteractEntityEvent event) {
|
||||
if (event.getRightClicked() instanceof ItemFrame) {
|
||||
PlayerInventory player_inv = event.getPlayer().getInventory();
|
||||
if (isEgg(player_inv.getItemInMainHand()) || isEgg(player_inv.getItemInOffHand())) {
|
||||
data.updateEggLocation(event.getRightClicked());
|
||||
data.setEggOwner(event.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg teleporting
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onSpread(BlockFromToEvent event) {
|
||||
if (isEgg(event.getBlock())) {
|
||||
data.updateEggLocation(event.getToBlock());
|
||||
|
||||
if (!config.getAccurateLocation()) {
|
||||
//TODO disable accuracy here
|
||||
console_log("The egg teleported, showing players the egg's location before teleport");
|
||||
} else {
|
||||
console_log("The egg teleported, showing players the egg's up-to-date location");
|
||||
}
|
||||
|
||||
if (config.resetOwnerOnTeleport()) {
|
||||
if (data.getEggOwner() != null) {
|
||||
announce(String.format("The dragon egg has teleported. %s is no longer the owner.", data.getEggOwner().getName()));
|
||||
data.resetEggOwner(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg as a falling block entity
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onFallingBlock(final EntityChangeBlockEvent event){
|
||||
//check if this is dealing with a falling block, since EntityChangeBlockEvent is generic
|
||||
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
|
||||
//if the falling block is the egg
|
||||
if (isEgg((FallingBlock)event.getEntity())) {
|
||||
|
||||
console_log("Gravity event involving dragon egg occured");
|
||||
|
||||
if (event.getBlock().getType() == Material.AIR) {
|
||||
//egg lands
|
||||
data.updateEggLocation(event.getBlock());
|
||||
|
||||
} else if (event.getBlock().getType() == Material.DRAGON_EGG) {
|
||||
//egg begins falling
|
||||
data.updateEggLocation(event.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the egg item takes damage, call eggDestroyed
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDamageEvent(EntityDamageEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity.getType().equals(EntityType.DROPPED_ITEM)) {
|
||||
ItemStack item = ((Item)entity).getItemStack();
|
||||
if (isEgg(item)) {
|
||||
//make sure item is destroyed to prevent dupes
|
||||
event.getEntity().remove();
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that the egg is destroyed if the egg item dies
|
||||
* Also respawns the egg when the dragon is killed
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
//if the egg item dies, notify that it has been destroyed
|
||||
if (event.getEntityType().equals(EntityType.DROPPED_ITEM)) {
|
||||
if (isEgg((ItemStack) event.getEntity())) {
|
||||
//remove just in case to prevent dupes
|
||||
event.getEntity().remove();
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
else if (event.getEntity().getType().equals(EntityType.ITEM_FRAME)
|
||||
|| event.getEntity().getType().equals(EntityType.GLOW_ITEM_FRAME)) {
|
||||
ItemFrame frame = (ItemFrame) event.getEntity();
|
||||
if (isEgg(frame.getItem())) {
|
||||
frame.setItem(null); //make sure the item is destroyed
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
//if the dragon is killed, respawn the egg
|
||||
else if (config.getRespawnEgg()) {
|
||||
if (data.getEggType() == Egg_Storage_Type.DNE) {
|
||||
//if the egg does not exist
|
||||
if (event.getEntityType().equals(EntityType.ENDER_DRAGON)) {
|
||||
//if the dragon is killed
|
||||
if (config.getEndWorld().getEnderDragonBattle().hasBeenPreviouslyKilled()) {
|
||||
//if the dragon has already been beaten
|
||||
spawnEggBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//stop portals from removing the egg
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onCreatePortal(EntityCreatePortalEvent event) {
|
||||
//not specific to any particular creation reason because multiple events could cause the egg to be removed (obby platform regen, gateway portal spawning, stronghold portal activation)
|
||||
boolean egg_affected=false;
|
||||
Location l = null;
|
||||
List<BlockState> blocks=event.getBlocks();
|
||||
console_log(String.format("blocks: %s",blocks.toString()));
|
||||
for (BlockState blockState : blocks) {
|
||||
console_log(String.format("Block update at %s: from %s to %s", blockState.getLocation(),
|
||||
blockState.getBlock().getType(), blockState.getType()));
|
||||
if (blockState.getBlock().getType().equals(Material.DRAGON_EGG)) {
|
||||
egg_affected = true;
|
||||
l = blockState.getLocation();
|
||||
//extra check to make sure egg is removed
|
||||
blockState.getBlock().setType(Material.AIR);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (egg_affected) {
|
||||
String entityName="Unknown entity";
|
||||
if (event.getEntity()!=null) {
|
||||
if (event.getEntity().getCustomName()!=null) {
|
||||
entityName=event.getEntity().getCustomName();
|
||||
}
|
||||
}
|
||||
console_log(String.format("%s tried to overwrite egg with a portal",entityName));
|
||||
data.resetEggOwner(false);
|
||||
if (l!=null) {
|
||||
EggRespawn.spawnEggItem(l, config, data);
|
||||
} else {
|
||||
console_log("Could not spawn egg item! Invalid block location.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Other event handlers
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onDespawn (ItemDespawnEvent event) {
|
||||
//if the egg is going to despawn, cancel it
|
||||
if (isEgg(event.getEntity().getItemStack())) {
|
||||
event.setCancelled(true);
|
||||
//set the age back to 1 so it doesn't try to despawn every tick
|
||||
event.getEntity().setTicksLived(1);
|
||||
console_log("Canceled egg despawn");
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||
if (!event.getKeepInventory() && event.getEntity().getInventory().contains(Material.DRAGON_EGG)) {
|
||||
data.resetEggOwner(false);
|
||||
|
||||
//change the death message
|
||||
String deathmsg = event.getDeathMessage();
|
||||
|
||||
if (deathmsg == null || deathmsg.isBlank()) {
|
||||
announce(String.format("%s died and lost the dragon egg!", event.getEntity().getDisplayName()));
|
||||
|
||||
} else {
|
||||
if (deathmsg.endsWith(".")) {
|
||||
deathmsg = deathmsg.substring(0, deathmsg.length() - 1);
|
||||
}
|
||||
event.setDeathMessage(String.format("%s and lost the dragon egg!", deathmsg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stop mushrooms from removing the egg
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onGrow(StructureGrowEvent event) {
|
||||
boolean destroy = false;
|
||||
if (event.getSpecies().equals(TreeType.RED_MUSHROOM)) {
|
||||
List<BlockState> blocks = event.getBlocks();
|
||||
for (BlockState blockState : blocks) {
|
||||
Block block = blockState.getBlock();
|
||||
if (isEgg(block)) {
|
||||
destroy = true;
|
||||
if (!config.getEggInvincible()) { //if egg will be replaced, make sure it gets removed
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} else {
|
||||
if (blockState instanceof Container) { //TODO exclude item frames, which aren't destroyed by this
|
||||
Container cont = (Container) blockState;
|
||||
if (cont.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
destroy = true;
|
||||
cont.getInventory().remove(Material.DRAGON_EGG); //make sure egg is removed from container
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (destroy) {
|
||||
if (config.getEggInvincible()) {
|
||||
event.setCancelled(true);
|
||||
Player p = event.getPlayer();
|
||||
if (p != null) {
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_LAND, 1, 1);
|
||||
p.sendMessage("Cannot grow mushroom: obstructed by dragon egg");
|
||||
p.setCooldown(Material.BONE_MEAL, 100);
|
||||
console_log(String.format("%s tried to mushroom the dragon egg", p.getName()));
|
||||
}
|
||||
} else {
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops players from holding the egg in their cursor then dragging to drop it into an ender chest or shulker box.
|
||||
*
|
||||
* Note: due to limitations with the API, this prevents dragging the egg when viewing an ender chest or shulker box,
|
||||
* even if the egg is only dragged over slots in the player's inventory.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onInventoryDragConsider(InventoryDragEvent event) {
|
||||
InventoryType inv = event.getInventory().getType(); //this only gets the currently viewed ("top") inventory, which is not necessairly where the items are dragged in/over
|
||||
if (event.getWhoClicked().getGameMode() != GameMode.CREATIVE) {
|
||||
if (inv.equals(InventoryType.ENDER_CHEST) || inv.equals(InventoryType.SHULKER_BOX)) {
|
||||
boolean holdEgg = isEgg(event.getOldCursor());
|
||||
if (holdEgg) {
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from dragging egg while viewing shulker/ender chest",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop players from storing the egg in an ender chest or shulker box.
|
||||
* Also stops the player from putting the egg into a bundle regardless of open inventory.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onInventoryMoveConsider(InventoryClickEvent event) {
|
||||
InventoryType inv = event.getInventory().getType();
|
||||
if (event.getWhoClicked().getGameMode() != GameMode.CREATIVE) {
|
||||
if (inv.equals(InventoryType.ENDER_CHEST) || inv.equals(InventoryType.SHULKER_BOX)) {
|
||||
boolean hoverEgg = isEgg(event.getCurrentItem());
|
||||
boolean holdEgg = isEgg(event.getCursor());
|
||||
Boolean clickedContainer = null;
|
||||
if (event.getClickedInventory() != null) {
|
||||
clickedContainer = event.getClickedInventory().equals(event.getInventory());
|
||||
}
|
||||
|
||||
//if the other inventory is an ender chest or shulker box
|
||||
if (hoverEgg || holdEgg) {
|
||||
//clicked on the egg or holding the egg with the cursor
|
||||
boolean cancel = false;
|
||||
|
||||
if (clickedContainer == null){
|
||||
logger.info(event.getAction().toString());
|
||||
} else if (clickedContainer) {
|
||||
//player clicked the container
|
||||
switch (event.getAction()) {
|
||||
case COLLECT_TO_CURSOR:
|
||||
case HOTBAR_MOVE_AND_READD:
|
||||
case MOVE_TO_OTHER_INVENTORY:
|
||||
case HOTBAR_SWAP:
|
||||
if (hoverEgg) {
|
||||
//the egg is on the current item so these are not allowed
|
||||
cancel = true;
|
||||
}
|
||||
//if the current item is not an egg, allow this action
|
||||
//(eg allow shift+clicking items out of the ender chest while cursor holding the egg)
|
||||
break;
|
||||
default:
|
||||
cancel = true; //no interaction is allowed in this case
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
//player clicked on own inventory
|
||||
//prevent any action that would move the egg into/from the ender chest (other than hotkey, which is prevented below)
|
||||
switch (event.getAction()) {
|
||||
case MOVE_TO_OTHER_INVENTORY:
|
||||
if(hoverEgg){ //prevent only if hovering over the egg, not if holding it
|
||||
cancel=true;
|
||||
}
|
||||
break;
|
||||
case COLLECT_TO_CURSOR:
|
||||
|
||||
cancel = true; //cancel these actions
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cancel) {
|
||||
//if the item clicked was the egg
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from moving egg to shulker/ender chest",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//don't allow hotkeying either
|
||||
if (event.getClick().equals(ClickType.NUMBER_KEY)) {
|
||||
ItemStack item = event.getWhoClicked().getInventory().getItem(event.getHotbarButton());
|
||||
if (item != null) {
|
||||
if (event.getClickedInventory().equals(event.getInventory())) {
|
||||
//make sure the destination is the ender chest
|
||||
//this allows hotkeying the egg around in the player's inventory
|
||||
if (isEgg(item)) {
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from hotkeying egg to shulker/ender chest",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//prevent using bundles on the egg in *any* inventory
|
||||
if(event.getCurrentItem() != null){
|
||||
if(event.getCursor()!=null){
|
||||
|
||||
ItemStack clicked=event.getCurrentItem();
|
||||
ItemStack cursor=event.getCursor();
|
||||
|
||||
if ((isEgg(cursor) && clicked.getType() == Material.BUNDLE)
|
||||
|| (isEgg(clicked) && cursor.getType() == Material.BUNDLE)) {
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from bundling the egg",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* stop players from pushing the egg into a shulker using a hopper/hopper minecart
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPushConsider (InventoryMoveItemEvent event) {
|
||||
//nice try, but it won't work
|
||||
if (event.getDestination().getType().equals(InventoryType.SHULKER_BOX)){
|
||||
if (isEgg(event.getItem())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Prevent egg destruction
|
||||
//TODO: figure out if this is still needed
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onConsiderEntityDamageEvent(EntityDamageEvent event) {
|
||||
if (config.getEggInvincible()) {
|
||||
Entity entity=event.getEntity();
|
||||
if (entity.getType().equals(EntityType.DROPPED_ITEM)) {
|
||||
if (isEgg((Item)entity)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Helper methods
|
||||
|
||||
//When a portal is updated, check if the egg will be replaced
|
||||
private void checkPortalBlocks() {
|
||||
//TODO there has to be a better way to do this
|
||||
//Check end platform
|
||||
Location l1=new Location(config.getEndWorld(),102,48,2);
|
||||
Location l2=new Location(config.getEndWorld(),98,51,-2);
|
||||
Location res=checkBlockMaterialFromLocation(config.getEndWorld(),Material.DRAGON_EGG,l1,l2);
|
||||
if (res!=null) {
|
||||
portalOverwriteEgg(res);
|
||||
}
|
||||
}
|
||||
|
||||
private void portalOverwriteEgg(Location res) {
|
||||
res.getBlock().setType(Material.AIR);
|
||||
console_log("Egg was overwritten with a portal");
|
||||
if (config.getEggInvincible()) {
|
||||
console_log("Spawning new egg");
|
||||
EggRespawn.spawnEggItem(res, config, data);
|
||||
} else {
|
||||
eggDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks various blocks for the given material
|
||||
* @param w world the position is in
|
||||
* @param m material to check
|
||||
* @param x1 starting x pos
|
||||
* @param x2 ending x pos
|
||||
* @param y1 starting y pos
|
||||
* @param y2 ending y pos
|
||||
* @param z1 starting z pos
|
||||
* @param z2 ending z pos
|
||||
* @return
|
||||
*/
|
||||
private static Location checkBlockMaterial(World w, Material m, int x1, int x2, int y1, int y2, int z1, int z2) {
|
||||
for (int x=x1; x<x2; x++) {
|
||||
for (int y=y1; y<y2; y++) {
|
||||
for (int z=z1; z<z2; z++) {
|
||||
if (w.getBlockAt(x, y, z).getType().equals(m)) {
|
||||
return new Location(w,x,y,z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Location checkBlockMaterialFromLocation(World w, Material m, Location l1, Location l2) {
|
||||
return checkBlockMaterial(w,m,l1.getBlockX(),l1.getBlockY(),l1.getBlockZ(),l2.getBlockX(),l2.getBlockY(),l2.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls CheckBlockMaterial with deltas
|
||||
*/
|
||||
private static Location checkDeltaBlockMaterial(World w, Material m, int x, int dx, int y, int dy, int z, int dz) {
|
||||
return (checkBlockMaterial(w, m, x, x+dx, y, y+dy, z, z+dz));
|
||||
}
|
||||
|
||||
private void makeEggInvulnerable(Entity egg_stack) {
|
||||
if (config.getEggInvincible()) {
|
||||
egg_stack.setInvulnerable(true);
|
||||
console_log("made drop invulnerable");
|
||||
}
|
||||
}
|
||||
|
||||
public void eggDestroyed() {
|
||||
announce("The dragon egg has been destroyed!");
|
||||
data.resetEggOwner(false);
|
||||
|
||||
if (config.getRespawnEgg()) {
|
||||
if (config.getRespawnImmediately()) {
|
||||
spawnEggBlock();
|
||||
} else {
|
||||
data.resetEggLocation();
|
||||
announce("It will respawn the next time the dragon is defeated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnEggBlock() {
|
||||
Block newEggLoc = config.getEndWorld().getEnderDragonBattle().getEndPortalLocation().add(0, 4, 0).getBlock();
|
||||
newEggLoc.setType(Material.DRAGON_EGG);
|
||||
data.updateEggLocation(newEggLoc);
|
||||
announce("The dragon egg has spawned in the end!");
|
||||
}
|
||||
|
||||
private boolean isEgg(ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return false;
|
||||
}
|
||||
return stack.getType().equals(Material.DRAGON_EGG);
|
||||
}
|
||||
|
||||
private boolean isEgg(Item item) {
|
||||
if (item == null) {
|
||||
return false;
|
||||
}
|
||||
return item.getItemStack().getType().equals(Material.DRAGON_EGG);
|
||||
}
|
||||
|
||||
private boolean isEgg(Block block) {
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
return block.getType().equals(Material.DRAGON_EGG);
|
||||
}
|
||||
|
||||
private boolean isEgg(FallingBlock block) {
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
return block.getBlockData().getMaterial().equals(Material.DRAGON_EGG);
|
||||
}
|
||||
|
||||
private ItemStack makeEgg() {
|
||||
return new ItemStack(Material.DRAGON_EGG);
|
||||
}
|
||||
|
||||
private void announce(String msg) {
|
||||
Announcement.announce(msg, logger);
|
||||
}
|
||||
|
||||
private void console_log(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package io.github.J0hnL0cke.egghunt.Controller;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
|
||||
public class EggRespawn {
|
||||
public static void spawnEggItem(Location loc, Configuration config, Data data){
|
||||
ItemStack egg=new ItemStack(Material.DRAGON_EGG);
|
||||
egg.setAmount(1);
|
||||
Item drop=loc.getWorld().dropItem(loc, egg);
|
||||
drop.setGravity(false);
|
||||
drop.setGlowing(true);
|
||||
drop.setVelocity(new Vector().setX(0).setY(0).setZ(0));
|
||||
if (config.getEggInvincible()) {
|
||||
drop.setInvulnerable(true);
|
||||
}
|
||||
data.updateEggLocation(drop);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Egg;
|
||||
|
||||
public class EventScheduler extends BukkitRunnable {
|
||||
|
||||
|
|
@ -52,7 +53,7 @@ public class EventScheduler extends BukkitRunnable {
|
|||
yPos = respawnLoc.getWorld().getMaxHeight() / 2;
|
||||
}
|
||||
respawnLoc.setY(yPos);
|
||||
EggRespawn.spawnEggItem(respawnLoc, config, data);
|
||||
Egg.spawnEggItem(respawnLoc, config, data); //do not need to update data with this location since item spawn event will be called
|
||||
} else {
|
||||
eggDestroyed();
|
||||
respawnEgg(respawnLoc);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,312 @@
|
|||
package io.github.J0hnL0cke.egghunt.Controller;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.inventory.AbstractHorseInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Egg;
|
||||
|
||||
/**
|
||||
* Listens for Bukkit events related to inventories
|
||||
*/
|
||||
public class InventoryListener implements Listener {
|
||||
|
||||
private Logger logger;
|
||||
private Configuration config;
|
||||
private Data data;
|
||||
|
||||
public InventoryListener(Logger logger, Configuration config, Data data) {
|
||||
this.logger = logger;
|
||||
this.config = config;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Track the player dropping the egg
|
||||
* TODO see if this always overlaps with item spawn event (also check when standing over hopper, etc)
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onItemDrop(PlayerDropItemEvent event) {
|
||||
|
||||
Item item = event.getItemDrop();
|
||||
ItemStack stack = item.getItemStack();
|
||||
|
||||
// Check if the dropped item is the egg
|
||||
if (Egg.isEgg(stack)) {
|
||||
data.setEggOwner(event.getPlayer());
|
||||
data.updateEggLocation(item);
|
||||
Egg.makeEggInvulnerable(event.getItemDrop(), config, logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being picked up by an entity
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPickupItem(EntityPickupItemEvent event) {
|
||||
// Check if item picked up is an egg
|
||||
if (Egg.isEgg(event.getItem())) {
|
||||
data.updateEggLocation(event.getEntity());
|
||||
if (event.getEntity() instanceof Player) {
|
||||
data.setEggOwner((Player) event.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being picked up by a container (hopper or hopper minecart)
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onHopperCollect(InventoryPickupItemEvent event) {
|
||||
|
||||
// Check if the dragon egg was picked up
|
||||
ItemStack item = event.getItem().getItemStack();
|
||||
|
||||
if (Egg.isEgg(item)) {
|
||||
//check if the inventory has open space
|
||||
//TODO test this with edge cases for hopper pull/push
|
||||
if (event.getInventory().firstEmpty() != -1 || event.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
data.updateEggLocation(event.getInventory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the player closes an inventory, check the player and the inventory for the egg.
|
||||
* This removes the need to check specifics about a player's clicks in an inventory
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onInventoryClose(InventoryCloseEvent event) {
|
||||
|
||||
Player player = (Player) event.getPlayer();
|
||||
Inventory otherInv = event.getInventory();
|
||||
|
||||
//force an egg in the ender chest to be dropped if enabled in config and if the player is not in creative
|
||||
if (otherInv.getType().equals(InventoryType.ENDER_CHEST)) {
|
||||
if (config.getDropEnderchestedEgg() && player.getGameMode() != GameMode.CREATIVE) {
|
||||
if (otherInv.contains(Material.DRAGON_EGG)) {
|
||||
ItemStack egg = otherInv.getItem(otherInv.first(Material.DRAGON_EGG));
|
||||
Location playerLoc = player.getLocation();
|
||||
otherInv.remove(egg);
|
||||
Item i = playerLoc.getWorld().dropItem(playerLoc, egg); //TODO use drop item function
|
||||
console_log(String.format(
|
||||
"Dropped the dragon egg on the ground since %s had it in their ender chest.",
|
||||
player.getName()));
|
||||
console_log(
|
||||
"Set ignore_echest_egg to \"true\" in the config file to disable this feature.");
|
||||
data.updateEggLocation(i);
|
||||
}
|
||||
}
|
||||
//whether the egg is dropped or not, ignore all other checking
|
||||
//since either egg should be dropped and location has already been updated
|
||||
//or it should not move and this egg should be ignored entirely
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
//if the player has the egg in their inventory, it will stay there
|
||||
data.updateEggLocation(player);
|
||||
data.setEggOwner(player);
|
||||
|
||||
} else if (otherInv.contains(Material.DRAGON_EGG)) {
|
||||
|
||||
if (otherInv.getType() != InventoryType.PLAYER) { //TODO check how this affects player viewing own inventory (egg on head/offhand?)
|
||||
|
||||
if (otherInv.getHolder() instanceof Container || otherInv instanceof AbstractHorseInventory) { //not instanceof entity- chest llama but not wandering trader
|
||||
//this is a container (chest, furnace, hopper minecart, etc), so the egg will remain here when the inventory is closed
|
||||
data.updateEggLocation(otherInv);
|
||||
|
||||
} else {
|
||||
//this is not a container (anvil, crafting table, villager, etc), so it will move back to the player's inventory
|
||||
//note- if the player's inventory is full, it will instead drop as an item, which will trigger the item drop event
|
||||
data.updateEggLocation(player);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the egg location when it is moved between blocks/entities (hoppers, dispensers, hopper minecarts, chest boats, etc)
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onInventoryMove(InventoryMoveItemEvent event) {
|
||||
//check if the item being moved is the egg
|
||||
if (Egg.isEgg(event.getItem())) {
|
||||
if (event.getDestination().firstEmpty() != -1 || event.getDestination().contains(Material.DRAGON_EGG)) {
|
||||
data.updateEggLocation(event.getDestination());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop players from holding the egg in their cursor then dragging to drop it into an ender chest or shulker box.
|
||||
*
|
||||
* Note: Due to limitations with the API, this prevents dragging the egg when viewing an ender chest or shulker box,
|
||||
* even if the egg is only dragged over slots in the player's inventory.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onInventoryDragConsider(InventoryDragEvent event) {
|
||||
InventoryType inv = event.getInventory().getType(); //this only gets the currently viewed ("top") inventory, which is not necessairly where the items are dragged in/over
|
||||
if (event.getWhoClicked().getGameMode() != GameMode.CREATIVE) {
|
||||
if (inv.equals(InventoryType.ENDER_CHEST) || inv.equals(InventoryType.SHULKER_BOX)) {
|
||||
boolean holdEgg = Egg.isEgg(event.getOldCursor());
|
||||
if (holdEgg) {
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from dragging egg while viewing shulker/ender chest",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop players from storing the egg in an ender chest or shulker box.
|
||||
* Also stops the player from putting the egg into a bundle regardless of open inventory.
|
||||
* TODO refactor into multiple smaller listeners
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onInventoryMoveConsider(InventoryClickEvent event) {
|
||||
InventoryType inv = event.getInventory().getType();
|
||||
if (event.getWhoClicked().getGameMode() != GameMode.CREATIVE) {
|
||||
if (inv.equals(InventoryType.ENDER_CHEST) || inv.equals(InventoryType.SHULKER_BOX)) {
|
||||
boolean hoverEgg = Egg.isEgg(event.getCurrentItem());
|
||||
boolean holdEgg = Egg.isEgg(event.getCursor());
|
||||
Boolean clickedContainer = null;
|
||||
if (event.getClickedInventory() != null) {
|
||||
clickedContainer = event.getClickedInventory().equals(event.getInventory());
|
||||
}
|
||||
|
||||
//if the other inventory is an ender chest or shulker box
|
||||
if (hoverEgg || holdEgg) {
|
||||
//clicked on the egg or holding the egg with the cursor
|
||||
boolean cancel = false;
|
||||
|
||||
if (clickedContainer == null){
|
||||
logger.info(event.getAction().toString());
|
||||
} else if (clickedContainer) {
|
||||
//player clicked the container
|
||||
switch (event.getAction()) {
|
||||
case COLLECT_TO_CURSOR:
|
||||
case HOTBAR_MOVE_AND_READD:
|
||||
case MOVE_TO_OTHER_INVENTORY:
|
||||
case HOTBAR_SWAP:
|
||||
if (hoverEgg) {
|
||||
//the egg is on the current item so these are not allowed
|
||||
cancel = true;
|
||||
}
|
||||
//if the current item is not an egg, allow this action
|
||||
//(eg allow shift+clicking items out of the ender chest while cursor holding the egg)
|
||||
break;
|
||||
default:
|
||||
cancel = true; //no interaction is allowed in this case
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
//player clicked on own inventory
|
||||
//prevent any action that would move the egg into/from the ender chest (other than hotkey, which is prevented below)
|
||||
switch (event.getAction()) {
|
||||
case MOVE_TO_OTHER_INVENTORY:
|
||||
if(hoverEgg){ //prevent only if hovering over the egg, not if holding it
|
||||
cancel=true;
|
||||
}
|
||||
break;
|
||||
case COLLECT_TO_CURSOR:
|
||||
|
||||
cancel = true; //cancel these actions
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cancel) {
|
||||
//if the item clicked was the egg
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from moving egg to shulker/ender chest",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//don't allow hotkeying either
|
||||
if (event.getClick().equals(ClickType.NUMBER_KEY)) {
|
||||
ItemStack item = event.getWhoClicked().getInventory().getItem(event.getHotbarButton());
|
||||
if (item != null) {
|
||||
if (event.getClickedInventory().equals(event.getInventory())) {
|
||||
//make sure the destination is the ender chest
|
||||
//this allows hotkeying the egg around in the player's inventory
|
||||
if (Egg.isEgg(item)) {
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from hotkeying egg to shulker/ender chest",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//prevent using bundles on the egg in *any* inventory
|
||||
if(event.getCurrentItem() != null){
|
||||
if(event.getCursor()!=null){
|
||||
|
||||
ItemStack clicked=event.getCurrentItem();
|
||||
ItemStack cursor=event.getCursor();
|
||||
|
||||
if ((Egg.isEgg(cursor) && clicked.getType() == Material.BUNDLE)
|
||||
|| (Egg.isEgg(clicked) && cursor.getType() == Material.BUNDLE)) {
|
||||
event.setCancelled(true);
|
||||
console_log(String.format("Stopped %s from bundling the egg",
|
||||
event.getWhoClicked().getName()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop players from pushing the egg into a shulker using a hopper/hopper minecart
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPushConsider(InventoryMoveItemEvent event) {
|
||||
//nice try, but it won't work
|
||||
if (event.getDestination().getType().equals(InventoryType.SHULKER_BOX)) {
|
||||
if (Egg.isEgg(event.getItem())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void console_log(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
package io.github.J0hnL0cke.egghunt.Controller;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.world.WorldSaveEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Egg;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Listens to miscellaneous Bukkit events
|
||||
*/
|
||||
public class MiscListener implements Listener {
|
||||
|
||||
private Logger logger;
|
||||
private Configuration config;
|
||||
private Data data;
|
||||
|
||||
|
||||
public MiscListener(Logger logger, Configuration config, Data data) {
|
||||
this.logger = logger;
|
||||
this.config = config;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data when the server autosaves.
|
||||
* Need to do this because a server crash could roll back the server data but not the plugin.
|
||||
* In this case data loss is beneficial, because being in sync with server's reality is more important.
|
||||
* TODO test this
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onAutosave(WorldSaveEvent event) {
|
||||
//TODO: don't save data until an autosave happens
|
||||
data.saveData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop egg if a player logs off with it in their inventory.
|
||||
* TODO check if item spawn and item drop events overlap, and check which can be replaced
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onLogoff(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
// Check if the player has a dragon egg
|
||||
if (player.getInventory().contains(Material.DRAGON_EGG)) {
|
||||
|
||||
// Set owner and remove
|
||||
data.setEggOwner(player); //TODO is this necessary? player will likely already be owner
|
||||
player.getInventory().remove(Material.DRAGON_EGG);
|
||||
|
||||
// Drop it on the floor and set its location
|
||||
//TODO use drop egg method in EggRespawn
|
||||
Item egg_drop = event.getPlayer().getWorld().dropItem(player.getLocation(),
|
||||
new ItemStack(Material.DRAGON_EGG));
|
||||
data.updateEggLocation(egg_drop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Track the egg droping as an item.
|
||||
* Note: No handler to check if the falling egg entity drops an item, so we have to check every item spawn
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onItemSpawn(ItemSpawnEvent event) {
|
||||
// Check if the spawned item is the egg
|
||||
Item item = event.getEntity();
|
||||
|
||||
if (Egg.isEgg(item)) {
|
||||
data.updateEggLocation(item);
|
||||
Egg.makeEggInvulnerable(event.getEntity(), config, logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being placed as a block
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockPlace (BlockPlaceEvent event) {
|
||||
if (Egg.isEgg(event.getBlock())) {
|
||||
data.updateEggLocation(event.getBlock());
|
||||
data.setEggOwner(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg being placed in an item frame
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onInteract(PlayerInteractEntityEvent event) {
|
||||
if (event.getRightClicked() instanceof ItemFrame) {
|
||||
PlayerInventory player_inv = event.getPlayer().getInventory();
|
||||
if (Egg.isEgg(player_inv.getItemInMainHand()) || Egg.isEgg(player_inv.getItemInOffHand())) {
|
||||
data.updateEggLocation(event.getRightClicked());
|
||||
data.setEggOwner(event.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg teleporting
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onSpread(BlockFromToEvent event) {
|
||||
if (Egg.isEgg(event.getBlock())) {
|
||||
data.updateEggLocation(event.getToBlock());
|
||||
|
||||
if (!config.getAccurateLocation()) {
|
||||
//TODO disable accuracy here
|
||||
console_log("The egg teleported, showing players the egg's location before teleport");
|
||||
} else {
|
||||
console_log("The egg teleported, showing players the egg's up-to-date location");
|
||||
}
|
||||
|
||||
if (config.resetOwnerOnTeleport()) {
|
||||
if (data.getEggOwner() != null) {
|
||||
announce(String.format("The dragon egg has teleported. %s is no longer the owner.", data.getEggOwner().getName()));
|
||||
data.resetEggOwner(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the egg as a falling block entity
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onFallingBlock(final EntityChangeBlockEvent event){
|
||||
//check if this is dealing with a falling block, since EntityChangeBlockEvent is generic
|
||||
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
|
||||
//if the falling block is the egg
|
||||
if (Egg.isEgg((FallingBlock)event.getEntity())) {
|
||||
|
||||
console_log("Gravity event involving dragon egg occured");
|
||||
|
||||
if (event.getBlock().getType() == Material.AIR) {
|
||||
//egg lands
|
||||
data.updateEggLocation(event.getBlock());
|
||||
|
||||
} else if (event.getBlock().getType() == Material.DRAGON_EGG) {
|
||||
//egg begins falling
|
||||
data.updateEggLocation(event.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Other event handlers
|
||||
|
||||
/**
|
||||
* Modify the player death message if they are holding the egg when they die
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||
if (!event.getKeepInventory() && event.getEntity().getInventory().contains(Material.DRAGON_EGG)) {
|
||||
data.resetEggOwner(false);
|
||||
|
||||
//change the death message
|
||||
String deathmsg = event.getDeathMessage();
|
||||
|
||||
if (deathmsg == null || deathmsg.isBlank()) {
|
||||
announce(String.format("%s died and lost the dragon egg!", event.getEntity().getDisplayName()));
|
||||
|
||||
} else {
|
||||
if (deathmsg.endsWith(".")) {
|
||||
deathmsg = deathmsg.substring(0, deathmsg.length() - 1);
|
||||
}
|
||||
event.setDeathMessage(String.format("%s and lost the dragon egg!", deathmsg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Helper methods
|
||||
private void announce(String msg) {
|
||||
Announcement.announce(msg, logger);
|
||||
}
|
||||
|
||||
private void console_log(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -169,7 +169,7 @@ public class Data {
|
|||
String.format("%s has claimed the dragon egg!", Bukkit.getOfflinePlayer(owner).getName()), logger);
|
||||
Player p = Bukkit.getPlayer(playerUUID);
|
||||
if (p != null) { //make sure player is online
|
||||
Announcement.claimEggEffects(p);
|
||||
Announcement.ShowEggClaimEffects(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
107
src/main/java/io/github/J0hnL0cke/egghunt/Model/Egg.java
Normal file
107
src/main/java/io/github/J0hnL0cke/egghunt/Model/Egg.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
package io.github.J0hnL0cke.egghunt.Model;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Provides methods related to the dragon egg
|
||||
*/
|
||||
public class Egg {
|
||||
|
||||
private static Material egg = Material.DRAGON_EGG;
|
||||
|
||||
/**
|
||||
* Makes the given entity invulnerable if enabled in the config
|
||||
*/
|
||||
public static void makeEggInvulnerable(Entity entity, Configuration config, Logger logger) {
|
||||
if (config.getEggInvincible()) {
|
||||
entity.setInvulnerable(true);
|
||||
logger.info("made drop invulnerable");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns the dragon egg in the end world specified by the given config.
|
||||
* @return The new egg block.
|
||||
*/
|
||||
public static Block respawnEgg(Configuration config) {
|
||||
Block newEggLoc = config.getEndWorld().getEnderDragonBattle().getEndPortalLocation().add(0, 4, 0).getBlock();
|
||||
newEggLoc.setType(Material.DRAGON_EGG);
|
||||
return newEggLoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns a new egg item at the given location, sets it to invincible if enabled in the given config.
|
||||
* This should trigger the item drop event, so it should not be necessary to immediately update the data file with the returned item.
|
||||
* @return the egg item that was spawned
|
||||
*/
|
||||
public static Item spawnEggItem(Location loc, Configuration config, Data data){
|
||||
ItemStack egg=new ItemStack(Material.DRAGON_EGG);
|
||||
egg.setAmount(1);
|
||||
Item drop=loc.getWorld().dropItem(loc, egg);
|
||||
drop.setGravity(false);
|
||||
drop.setGlowing(true);
|
||||
drop.setVelocity(new Vector().setX(0).setY(0).setZ(0));
|
||||
if (config.getEggInvincible()) {
|
||||
drop.setInvulnerable(true);
|
||||
}
|
||||
return drop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given ItemStack is the dragon egg. Also returns false if the provided stack is null.
|
||||
* @param stack ItemStack to check
|
||||
* @return True if the stack material is a dragon egg, otherwise false
|
||||
*/
|
||||
public static boolean isEgg(ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return false;
|
||||
}
|
||||
return stack.getType().equals(egg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given Item is the dragon egg. Also returns false if the provided item is null.
|
||||
* @param item Item to check
|
||||
* @return True if the item material is a dragon egg, otherwise false
|
||||
*/
|
||||
public static boolean isEgg(Item item) {
|
||||
if (item == null) {
|
||||
return false;
|
||||
}
|
||||
return item.getItemStack().getType().equals(egg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given Block is the dragon egg. Also returns false if the provided block is null.
|
||||
* @param block Block to check
|
||||
* @return True if the block material is a dragon egg, otherwise false
|
||||
*/
|
||||
public static boolean isEgg(Block block) {
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
return block.getType().equals(egg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given FallingBlock is the dragon egg. Also returns false if the provided block is null.
|
||||
* @param block FallingBlock to check
|
||||
* @return True if the block material is a dragon egg, otherwise false
|
||||
*/
|
||||
public static boolean isEgg(FallingBlock block) {
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
return block.getBlockData().getMaterial().equals(egg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,12 +4,15 @@ import java.util.logging.Logger;
|
|||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Controller.CommandHandler;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.EggHuntListener;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.EggDestroyListener;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.MiscListener;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.EventScheduler;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.InventoryListener;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Persistence.ConfigFileDAO;
|
||||
|
|
@ -21,15 +24,13 @@ public final class egghunt extends JavaPlugin {
|
|||
Data data;
|
||||
CommandHandler commandHandler;
|
||||
|
||||
EventScheduler schedule;
|
||||
EggHuntListener listener;
|
||||
BukkitTask belowWorldTask;
|
||||
Logger logger;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
logger = getLogger();
|
||||
log("onEnable has been invoked, starting EggHunt.");
|
||||
log("Enabling EggHunt...");
|
||||
saveDefaultConfig();
|
||||
|
||||
//create model instances using dependency injection
|
||||
|
|
@ -37,18 +38,24 @@ public final class egghunt extends JavaPlugin {
|
|||
data = new Data(DataFileDAO.getDataDAO(this), getLogger());
|
||||
|
||||
//create controller instances
|
||||
listener = new EggHuntListener(getLogger(), config, data);
|
||||
schedule = new EventScheduler(config, data, logger);
|
||||
MiscListener miscListener = new MiscListener(getLogger(), config, data);
|
||||
InventoryListener inventoryListener = new InventoryListener(logger, config, data);
|
||||
EggDestroyListener destroyListener = new EggDestroyListener(logger, config, data);
|
||||
EventScheduler scheduler = new EventScheduler(config, data, logger);
|
||||
commandHandler = new CommandHandler(data);
|
||||
|
||||
//register event handlers
|
||||
log("registering event listeners.");
|
||||
getServer().getPluginManager().registerEvents(listener, this);
|
||||
|
||||
log("Registering event listeners...");
|
||||
PluginManager manager = getServer().getPluginManager();
|
||||
manager.registerEvents(miscListener, this);
|
||||
manager.registerEvents(inventoryListener, this);
|
||||
manager.registerEvents(destroyListener, this);
|
||||
|
||||
//schedule tasks
|
||||
//TODO: disable task when not in use
|
||||
log("Scheduling below world task");
|
||||
belowWorldTask = schedule.runTaskTimer(this, 20, 20);
|
||||
log("Scheduling below world task...");
|
||||
belowWorldTask = scheduler.runTaskTimer(this, 20, 20);
|
||||
|
||||
log("Done!");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue