package me.loganb1max.minionsplus.manager; import com.google.gson.*; import lombok.Getter; import me.loganb1max.minionsplus.MinionsPlus; import me.loganb1max.minionsplus.menu.MinionMenu; import me.loganb1max.minionsplus.model.Minion; import me.loganb1max.minionsplus.model.minions.MinerMinion; import me.loganb1max.minionsplus.util.ItemUtil; import me.loganb1max.minionsplus.util.Text; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.ArmorStand; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerArmorStandManipulateEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.scheduler.BukkitTask; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.HashSet; import java.util.Objects; import java.util.Set; public class MinionManager implements Listener { private final MinionsPlus plugin; private final BukkitTask animationTask; private final BukkitTask tickTask; @Getter private Set minions = new HashSet<>(); public MinionManager(final MinionsPlus plugin) { this.plugin = plugin; this.animationTask = Bukkit.getScheduler().runTaskTimer(this.plugin, () -> this.minions.forEach(Minion::animationTick), 1, 1); final int actionSpeed = this.plugin.getConfig().getInt("Action-Speed", 20); this.tickTask = Bukkit.getScheduler().runTaskTimer(this.plugin, () -> this.minions.forEach(Minion::tick), actionSpeed, actionSpeed); Bukkit.getPluginManager().registerEvents(this, this.plugin); loadMinions(); } public void close() { this.animationTask.cancel(); this.tickTask.cancel(); HandlerList.unregisterAll(this); saveMinions(); } private void loadMinions() { final File dataFile = new File(this.plugin.getDataFolder(), "minions.json"); if (!dataFile.exists()) return; final Gson gson = new Gson(); try (final BufferedReader reader = Files.newBufferedReader(dataFile.toPath(), StandardCharsets.UTF_8)) { JsonObject data = gson.fromJson(reader, JsonObject.class); JsonArray minions = data.get("minions").getAsJsonArray(); for (JsonElement el : minions) { try { Minion minion = Minion.deserialize(this.plugin, el); this.minions.add(minion); } catch (Exception e) { this.plugin.getLogger().severe("Failed to load minion."); e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } } private void saveMinions() { final File dataFile = new File(this.plugin.getDataFolder(), "minions.json"); final Gson gson = new Gson(); try (final BufferedWriter writer = Files.newBufferedWriter(dataFile.toPath(), StandardCharsets.UTF_8)) { JsonObject data = new JsonObject(); JsonArray minions = new JsonArray(); for (Minion minion : this.minions) { try { minions.add(minion.serialize()); } catch (Exception e) { this.plugin.getLogger().severe("Failed to save minion: " + minion.getOwnerName() + " : " + minion.getName()); e.printStackTrace(); } } data.add("minions", minions); writer.write(gson.toJson(data)); } catch (IOException e) { e.printStackTrace(); } } @EventHandler(priority = EventPriority.HIGHEST) public void onDamage(final EntityDamageEvent e) { if (!(e.getEntity() instanceof ArmorStand)) return; if (this.minions.stream().map(Minion::getId).filter(Objects::nonNull).anyMatch(uuid -> uuid.equals(e.getEntity().getUniqueId()))) { e.setCancelled(true); } } @EventHandler(priority = EventPriority.HIGHEST) public void onRightClick(final PlayerArmorStandManipulateEvent e) { this.minions.stream().filter(minion -> minion.getId().equals(e.getRightClicked().getUniqueId())).findFirst().ifPresent(minion -> { e.setCancelled(true); if (!minion.getOwner().equals(e.getPlayer().getUniqueId())) { e.getPlayer().sendMessage(Text.color("&cOnly the owner of the minion can interact with it.")); return; } if (e.getPlayer().isSneaking()) { minion.despawn(e.getPlayer()); return; } new MinionMenu(minion, e.getPlayer()); }); } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlace(PlayerInteractEvent e) { if (!e.hasItem() || !Minion.isMinion(e.getItem())) return; e.setCancelled(true); if (!e.hasBlock()) return; final Location loc = e.getClickedBlock().getRelative(e.getBlockFace()).getLocation().add(0.5, 0, 0.5); final Minion minion = Minion.of(e.getItem(), loc); minion.spawn(loc); ItemUtil.consumeItem(e.getPlayer().getInventory(), 1, e.getItem()); } }