EpicHoppers/src/main/java/com/songoda/epichoppers/hopper/Hopper.java

362 lines
12 KiB
Java

package com.songoda.epichoppers.hopper;
import com.songoda.core.compatibility.CompatibleParticleHandler;
import com.songoda.core.compatibility.CompatibleSound;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.EconomyManager;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.api.events.HopperAccessEvent;
import com.songoda.epichoppers.gui.GUIOverview;
import com.songoda.epichoppers.hopper.levels.Level;
import com.songoda.epichoppers.hopper.teleport.TeleportTrigger;
import com.songoda.epichoppers.player.PlayerData;
import com.songoda.epichoppers.settings.Settings;
import com.songoda.epichoppers.utils.CostType;
import com.songoda.epichoppers.utils.Methods;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Created by songoda on 3/14/2017.
*/
public class Hopper {
// Id for database use.
private int id;
private final Location location;
private Level level = EpicHoppers.getInstance().getLevelManager().getLowestLevel();
private UUID lastPlayerOpened = null;
private UUID placedBy = null;
private final List<Location> linkedBlocks = new ArrayList<>();
private Filter filter = new Filter();
private TeleportTrigger teleportTrigger = TeleportTrigger.DISABLED;
private int transferTick = 0;
private int syncId = -1;
private Player activePlayer;
private final Map<String, Object> moduleCache = new HashMap<>();
public Hopper(Location location) {
this.location = location;
}
public void overview(GuiManager guiManager, Player player) {
if (lastPlayerOpened != null
&& lastPlayerOpened != player.getUniqueId()
&& Bukkit.getPlayer(lastPlayerOpened) != null) {
Bukkit.getPlayer(lastPlayerOpened).closeInventory();
}
HopperAccessEvent accessEvent = new HopperAccessEvent(player, this);
Bukkit.getPluginManager().callEvent(accessEvent);
if (accessEvent.isCancelled()) {
return;
}
if (placedBy == null) placedBy = player.getUniqueId();
EpicHoppers instance = EpicHoppers.getInstance();
if (!player.hasPermission("epichoppers.overview")) return;
setActivePlayer(player);
guiManager.showGUI(player, new GUIOverview(instance, this, player));
}
public void forceClose() {
if (activePlayer != null)
activePlayer.closeInventory();
}
public void dropItems() {
Inventory inventory = ((InventoryHolder) location.getBlock().getState()).getInventory();
World world = location.getWorld();
for (ItemStack itemStack : inventory.getContents()) {
if (itemStack == null || itemStack.getType() == Material.AIR) {
continue;
}
world.dropItemNaturally(location, itemStack);
}
}
public void upgrade(Player player, CostType type) {
EpicHoppers plugin = EpicHoppers.getInstance();
if (!plugin.getLevelManager().getLevels().containsKey(this.level.getLevel() + 1)) return;
Level level = plugin.getLevelManager().getLevel(this.level.getLevel() + 1);
int cost = type == CostType.ECONOMY ? level.getCostEconomy() : level.getCostExperience();
if (type == CostType.ECONOMY) {
if (!EconomyManager.isEnabled()) {
player.sendMessage("Economy not enabled.");
return;
}
if (!EconomyManager.hasBalance(player, cost)) {
plugin.getLocale().getMessage("event.upgrade.cannotafford").sendPrefixedMessage(player);
return;
}
EconomyManager.withdrawBalance(player, cost);
upgradeFinal(level, player);
} else if (type == CostType.EXPERIENCE) {
if (player.getLevel() >= cost || player.getGameMode() == GameMode.CREATIVE) {
if (player.getGameMode() != GameMode.CREATIVE) {
player.setLevel(player.getLevel() - cost);
}
upgradeFinal(level, player);
} else {
plugin.getLocale().getMessage("event.upgrade.cannotafford").sendPrefixedMessage(player);
}
}
}
private void upgradeFinal(Level level, Player player) {
EpicHoppers plugin = EpicHoppers.getInstance();
this.level = level;
plugin.getDataManager().updateHopper(this);
syncName();
if (plugin.getLevelManager().getHighestLevel() != level) {
plugin.getLocale().getMessage("event.upgrade.success")
.processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
} else {
plugin.getLocale().getMessage("event.upgrade.maxed")
.processPlaceholder("level", level.getLevel()).sendPrefixedMessage(player);
}
Location loc = location.clone().add(.5, .5, .5);
if (!Settings.UPGRADE_PARTICLE_TYPE.getString().trim().isEmpty()) {
CompatibleParticleHandler.spawnParticles(
CompatibleParticleHandler.ParticleType.getParticle(Settings.UPGRADE_PARTICLE_TYPE.getString()),
loc, 100, .5, .5, .5);
}
if (plugin.getLevelManager().getHighestLevel() != level) {
player.playSound(player.getLocation(), CompatibleSound.ENTITY_PLAYER_LEVELUP.getSound(), 0.6F, 15.0F);
} else {
player.playSound(player.getLocation(), CompatibleSound.ENTITY_PLAYER_LEVELUP.getSound(), 2F, 25.0F);
player.playSound(player.getLocation(), CompatibleSound.BLOCK_NOTE_BLOCK_CHIME.getSound(), 2F, 25.0F);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> player.playSound(player.getLocation(), CompatibleSound.BLOCK_NOTE_BLOCK_CHIME.getSound(), 1.2F, 35.0F), 5L);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> player.playSound(player.getLocation(), CompatibleSound.BLOCK_NOTE_BLOCK_CHIME.getSound(), 1.8F, 35.0F), 10L);
}
}
private void syncName() {
org.bukkit.block.Hopper hopper = (org.bukkit.block.Hopper) location.getBlock().getState();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_10))
hopper.setCustomName(Methods.formatName(level.getLevel()));
hopper.update(true);
}
public void timeout(Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
syncId = Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> {
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() != null && playerData.getLastHopper() == this) {
instance.getLocale().getMessage("event.hopper.synctimeout").sendPrefixedMessage(player);
playerData.setSyncType(null);
}
}, Settings.LINK_TIMEOUT.getLong() * level.getLinkAmount());
}
public void link(Block toLink, boolean filtered, Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
if (location.getWorld().equals(toLink.getLocation().getWorld())
&& !player.hasPermission("EpicHoppers.Override")
&& !player.hasPermission("EpicHoppers.Admin")
&& location.distance(toLink.getLocation()) > level.getRange()) {
instance.getLocale().getMessage("event.hopper.syncoutofrange").sendPrefixedMessage(player);
return;
}
if (linkedBlocks.contains(toLink.getLocation())) {
instance.getLocale().getMessage("event.hopper.already").sendPrefixedMessage(player);
return;
}
if (!filtered) {
this.linkedBlocks.add(toLink.getLocation());
instance.getDataManager().createLink(this, toLink.getLocation(), LinkType.REGULAR);
} else {
this.filter.setEndPoint(toLink.getLocation());
instance.getDataManager().createLink(this, toLink.getLocation(), LinkType.REJECT);
instance.getLocale().getMessage("event.hopper.syncsuccess").sendPrefixedMessage(player);
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
return;
}
this.lastPlayerOpened = player.getUniqueId();
if (level.getLinkAmount() > 1) {
if (linkedBlocks.size() >= level.getLinkAmount()) {
instance.getLocale().getMessage("event.hopper.syncdone").sendPrefixedMessage(player);
cancelSync(player);
return;
}
instance.getLocale().getMessage("event.hopper.syncsuccessmore")
.processPlaceholder("amount", level.getLinkAmount() - linkedBlocks.size())
.sendPrefixedMessage(player);
return;
}
instance.getLocale().getMessage("event.hopper.syncsuccess").sendPrefixedMessage(player);
cancelSync(player);
}
/**
* Ticks a hopper to determine when it can transfer items next
*
* @param maxTick The maximum amount the hopper can be ticked before next transferring items
* @param allowLooping If true, the hopper is allowed to transfer items if the tick is also valid
* @return true if the hopper should transfer an item, otherwise false
*/
public boolean tryTick(int maxTick, boolean allowLooping) {
this.transferTick++;
if (this.transferTick >= maxTick) {
if (allowLooping) {
this.transferTick = 0;
return true;
} else {
this.transferTick = maxTick;
}
}
return false;
}
public Location getLocation() {
return location.clone();
}
public Block getBlock() {
return location.getBlock();
}
public World getWorld() {
return location.getWorld();
}
public int getX() {
return location.getBlockX();
}
public int getY() {
return location.getBlockY();
}
public int getZ() {
return location.getBlockZ();
}
public Level getLevel() {
return level;
}
public void setLevel(Level level) {
this.level = level;
}
public UUID getPlacedBy() {
return placedBy;
}
public void setPlacedBy(UUID placedBy) {
this.placedBy = placedBy;
}
public UUID getLastPlayerOpened() {
return lastPlayerOpened;
}
public void setLastPlayerOpened(UUID uuid) {
lastPlayerOpened = uuid;
}
public TeleportTrigger getTeleportTrigger() {
return teleportTrigger;
}
public void setTeleportTrigger(TeleportTrigger teleportTrigger) {
this.teleportTrigger = teleportTrigger;
}
public List<Location> getLinkedBlocks() {
return new ArrayList<>(linkedBlocks);
}
public void addLinkedBlock(Location location, LinkType type) {
if (type == LinkType.REGULAR)
linkedBlocks.add(location);
else
filter.setEndPoint(location);
}
public void removeLinkedBlock(Location location) {
this.linkedBlocks.remove(location);
}
public void clearLinkedBlocks() {
this.linkedBlocks.clear();
}
public Filter getFilter() {
return filter;
}
public void setFilter(Filter filter) {
this.filter = filter;
}
public Object getDataFromModuleCache(String key) {
return this.moduleCache.getOrDefault(key, null);
}
public void addDataToModuleCache(String key, Object data) {
this.moduleCache.put(key, data);
}
public boolean isDataCachedInModuleCache(String key) {
return this.moduleCache.containsKey(key);
}
public void removeDataFromModuleCache(String key) {
this.moduleCache.remove(key);
}
public void clearModuleCache() {
this.moduleCache.clear();
}
public void cancelSync(Player player) {
Bukkit.getScheduler().cancelTask(syncId);
EpicHoppers.getInstance().getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Player getActivePlayer() {
return activePlayer;
}
public void setActivePlayer(Player activePlayer) {
this.activePlayer = activePlayer;
}
}