diff --git a/pom.xml b/pom.xml index b303012..07b87b1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ betterbox.mine.game BetterElo - 4.4.29-SNAPSHOT + 4.4.52-SNAPSHOT jar BetterElo diff --git a/src/main/java/betterbox/mine/game/betterelo/BetterElo.java b/src/main/java/betterbox/mine/game/betterelo/BetterElo.java index 48c511b..57ee304 100644 --- a/src/main/java/betterbox/mine/game/betterelo/BetterElo.java +++ b/src/main/java/betterbox/mine/game/betterelo/BetterElo.java @@ -117,7 +117,7 @@ public void onEnable() { customMobsFileManager = new CustomMobsFileManager(folderPath,this, pluginLogger); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: calling customMobsFileManager.loadSpawners()"); customMobsFileManager.loadSpawners(); - customMobs = new CustomMobs(pluginLogger,this,customMobsFileManager, fileRewardManager); + customMobs = new CustomMobs(pluginLogger,this,customMobsFileManager, fileRewardManager,this ); pluginLogger.log(PluginLogger.LogLevel.INFO,"Starting spawners scheduler..."); customMobs.startSpawnerScheduler(); @@ -126,7 +126,7 @@ public void onEnable() { betterRanksCheaters = new BetterRanksCheaters(this,pluginLogger); CheaterCheckScheduler cheaterCheckScheduler = new CheaterCheckScheduler(this, betterRanksCheaters, getServer().getScheduler(), pluginLogger); // Rejestracja listenera eventów - event = new Event(dataManager, pluginLogger,this,betterRanksCheaters,configManager,this,customMobs,fileRewardManager,guiManager); + event = new Event(dataManager, pluginLogger,this,betterRanksCheaters,configManager,this,customMobs,fileRewardManager,guiManager,customMobsFileManager); getServer().getPluginManager().registerEvents(event, this); getCommand("be").setExecutor(new BetterEloCommand(this, dataManager, guiManager, pluginLogger, this, configManager,event,PKDB, customMobs, customMobsFileManager)); pluginLogger.log(PluginLogger.LogLevel.DEBUG,"BetterElo: onEnable: Plugin BetterElo został włączony pomyślnie."); @@ -610,6 +610,13 @@ public void killAllCustomMobs() { pluginLogger.log(PluginLogger.LogLevel.INFO, "BetterElo.killAllCustomMobs killed "+killedMobCount+" custom mobs."); } public void removeAndKillAllCustomMobs() { + for (CustomMobs.CustomMob customMob : customMobsMap.values()) { + // Sprawdzanie, czy encja jest nadal żywa przed próbą jej zabicia + if (customMob.entity != null && !customMob.entity.isDead()) { + customMob.entity.remove(); // Usuwa encję z świata + + } + } for (CustomMobs.CustomMob customMob : customMobsMap.values()) { // Sprawdzanie, czy encja jest nadal żywa przed próbą jej zabicia if (customMob.entity != null && !customMob.entity.isDead()) { @@ -645,6 +652,7 @@ public void run() { customMobs.decreaseMobCount(entry.getValue().spawnerName); iterator.remove(); String spawnerName = entry.getValue().spawnerName; + customMobs.spawnedMobsMap.remove(entry.getKey().getUniqueId()); if(!entry.getKey().isValid()){ @@ -665,7 +673,7 @@ public void run() { } } } - }.runTaskTimer(this, 0L, 20L * 60); // Uruchom co 1 minutę (20 ticków = 1 sekunda) + }.runTaskTimer(this, 0L, 20L * 10); // Uruchom co 1 minutę (20 ticków = 1 sekunda) } } diff --git a/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java b/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java index 47e78a0..09cc18c 100644 --- a/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java +++ b/src/main/java/betterbox/mine/game/betterelo/BetterEloCommand.java @@ -267,6 +267,11 @@ public boolean onCommand(CommandSender sender, Command command, String label, St break; case 2: switch (args[0].toLowerCase()) { + case "forcespawn": + if(sender.isOp()||sender.hasPermission("betterelo.forcespawn")){ + customMobs.spawnerForceSpawn(args[1]); + } + break; case "droptable": if(sender.isOp()||sender.hasPermission("betterelo.droptable")){ handleCreateDropTable(sender,args[1]); diff --git a/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java b/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java index 042eb29..f255f1b 100644 --- a/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java +++ b/src/main/java/betterbox/mine/game/betterelo/CustomMobs.java @@ -29,50 +29,52 @@ public class CustomMobs { private Map customMobsMap = new HashMap<>(); private final PluginLogger pluginLogger; private final JavaPlugin plugin; + private final BetterElo betterElo; private final FileRewardManager fileRewardManager; private final CustomMobsFileManager fileManager; private static final Random random = new Random(); private BukkitTask spawnerTask; public Map spawnerLastSpawnTimes = new HashMap<>(); // Mapa przechowująca czas ostatniego respa mobów z każdego spawnera + public Map spawnedMobsMap = new HashMap<>(); static class CustomMob { String mobName, dropTableName, spawnerName; boolean dropEMKS; EntityType entityType; LivingEntity entity; - ItemStack helmet, chestplate, leggings, boots,weapon; + ItemStack helmet, chestplate, leggings, boots, weapon; //HashMap< Double,ItemStack> dropTable; List dropTable; double armor, speed, attackDamage, EMKSchance; - int hp,attackSpeed,defense; + int hp, attackSpeed, defense; Map customMetadata; // Nowe pole do przechowywania niestandardowych metadanych JavaPlugin plugin; CustomMobsFileManager dropFileManager; - CustomMob(JavaPlugin plugin,CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots,ItemStack weapon, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, Boolean dropEMKS, double EMKSchance, int defense) { + CustomMob(JavaPlugin plugin, CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots, ItemStack weapon, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, Boolean dropEMKS, double EMKSchance, int defense) { this.plugin = plugin; this.dropEMKS = dropEMKS; this.EMKSchance = EMKSchance; this.mobName = mobName; this.entity = entity; - if(weapon!=null){ + if (weapon != null) { this.weapon = weapon; - }else{ - plugin.getLogger().warning(mobName+" does not have weapon set. Setting AIR"); + } else { + plugin.getLogger().warning(mobName + " does not have weapon set. Setting AIR"); this.weapon = new ItemStack(Material.AIR); } this.entityType = entityType; - if(helmet!=null) { + if (helmet != null) { this.helmet = helmet; } - if(chestplate!=null) { + if (chestplate != null) { this.chestplate = chestplate; } - if(leggings!=null) { + if (leggings != null) { this.leggings = leggings; } - if(boots!=null) { + if (boots != null) { this.boots = boots; } this.dropFileManager = dropFileManager; @@ -88,7 +90,8 @@ static class CustomMob { this.customMetadata = customMetadata; //setupMob(); } - CustomMob(JavaPlugin plugin,CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, Boolean dropEMKS, double EMKSchance, int defense) { + + CustomMob(JavaPlugin plugin, CustomMobsFileManager dropFileManager, String mobName, EntityType entityType, double armor, int hp, double speed, double attackDamage, int attackSpeed, Map customMetadata, String dropTableName, Boolean dropEMKS, double EMKSchance, int defense) { this.plugin = plugin; this.dropEMKS = dropEMKS; this.EMKSchance = EMKSchance; @@ -119,17 +122,18 @@ public void spawnMob(Location location) { setupMob(); // Teraz wywołujemy setupMob() po stworzeniu encji ((BetterElo) plugin).registerCustomMob(this.entity, this); } + public CustomMob cloneForSpawn(Location spawnLocation, String mobType) { CustomMob newMob = null; - if (mobType.equals("SKELETON")|| mobType.equals("ZOMBIE")) { - newMob = new CustomMob(this.plugin, this.dropFileManager, this.mobName, this.entityType, + if (mobType.equals("SKELETON") || mobType.equals("ZOMBIE")) { + newMob = new CustomMob(this.plugin, this.dropFileManager, this.mobName, this.entityType, this.helmet.clone(), this.chestplate.clone(), this.leggings.clone(), this.boots.clone(), this.weapon.clone(), this.armor, this.hp, this.speed, this.attackDamage, this.attackSpeed, new HashMap<>(this.customMetadata), this.dropTableName, this.dropEMKS, this.EMKSchance, this.defense); newMob.spawnMob(spawnLocation); - }else{ + } else { newMob = new CustomMob(this.plugin, this.dropFileManager, this.mobName, this.entityType, this.armor, this.hp, this.speed, this.attackDamage, this.attackSpeed, new HashMap<>(this.customMetadata), this.dropTableName, this.dropEMKS, this.EMKSchance, this.defense); @@ -150,10 +154,10 @@ private void setupMob() { entity.getEquipment().setLeggings(leggings); entity.getEquipment().setBoots(boots); entity.setPersistent(true); - if(weapon!=null){ + if (weapon != null) { entity.getEquipment().setItemInMainHand(weapon); - }else{ - plugin.getLogger().warning(mobName+" does not have weapon set. Setting AIR"); + } else { + plugin.getLogger().warning(mobName + " does not have weapon set. Setting AIR"); entity.getEquipment().setItemInMainHand(new ItemStack(Material.AIR)); } entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(hp); @@ -172,44 +176,46 @@ private void setupMob() { entity.setMetadata("armor", new FixedMetadataValue(plugin, armor)); entity.setMetadata("defense", new FixedMetadataValue(plugin, defense)); } + public String getMobName() { return this.mobName; } - } - - public CustomMobs(PluginLogger pluginLogger, JavaPlugin plugin, CustomMobsFileManager fileManager,FileRewardManager fileRewardManager){ + public CustomMobs(PluginLogger pluginLogger, JavaPlugin plugin, CustomMobsFileManager fileManager, FileRewardManager fileRewardManager, BetterElo betterElo) { this.plugin = plugin; + this.betterElo = betterElo; this.pluginLogger = pluginLogger; this.fileManager = fileManager; this.fileRewardManager = fileRewardManager; loadCustomMobs(); } + public void spawnModifiedZombie(Player player, String mobName, int mobCount) { - pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS,"CustomMobs.spawnModifiedZombie called, player: "+player.getName()+", mobName: "+mobName+", mobCount: "+mobCount); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnModifiedZombie called, player: " + player.getName() + ", mobName: " + mobName + ", mobCount: " + mobCount); Location playerLocation = player.getLocation(); //World world = player.getWorld(); - for (int i=0;i values = mob.getMetadata("MobName"); MetadataValue value = values.get(0); String customName = value.asString(); Component nameComponent; - nameComponent = Component.text(customName, NamedTextColor.DARK_RED) - .append(Component.text(" HP: " + Math.round(mob.getHealth()) + "/" + Math.round(mob.getMaxHealth()), NamedTextColor.WHITE)); + nameComponent = Component.text(customName, NamedTextColor.DARK_RED) + .append(Component.text(" HP: " + Math.round(mob.getHealth()) + "/" + Math.round(mob.getMaxHealth()), NamedTextColor.WHITE)); mob.customName(nameComponent); @@ -219,7 +225,7 @@ public void updateCustomMobName(LivingEntity mob) { public static String dropAverageDamage() { // Używamy funkcji wykładniczej do zmniejszenia prawdopodobieństwa wyższych wartości double x = -Math.log(random.nextDouble()) / 10.0; // Dostosuj parametr 10.0, aby zmienić rozkład - //double y = random. + //double y = random. int bonus = (int) Math.round(x * 60); // Skalowanie wyniku // Ograniczamy wartość bonusu do maksymalnie 60% @@ -230,7 +236,7 @@ public static String dropAverageDamage() { public void spawnCustomMobFromSpawner() { Map spawnersData = fileManager.spawnersData; - pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnCustomMobFromSpawner called. Loaded spawners: "+spawnersData); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnCustomMobFromSpawner called. Loaded spawners: " + spawnersData); // Sprawdzenie, czy istnieją spawnerzy w pliku if (spawnersData.isEmpty()) { pluginLogger.log(PluginLogger.LogLevel.ERROR, "No spawners found in spawners.yml."); @@ -240,14 +246,24 @@ public void spawnCustomMobFromSpawner() { long currentTime = System.currentTimeMillis(); for (Map.Entry entry : spawnersData.entrySet()) { - pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner checking spawner: "+entry); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner checking spawner: " + entry); String spawnerName = entry.getKey(); CustomMobsFileManager.SpawnerData spawnerData = entry.getValue(); Location location = getLocationFromString(spawnerData.location); + while (location.getBlock().getType() != Material.AIR) { + location.add(0, 1, 0); // Zwiększ y o 1 + if (location.getBlockY() > location.getWorld().getMaxHeight()) { + // Jeśli przekraczamy maksymalną wysokość, przerwij pętlę, aby uniknąć pętli nieskończonej + System.out.println("Reached the top of the world without finding an AIR block."); + break; + } + } + location.add(0, 1, 0); + // Sprawdzenie cooldownu if (!canSpawnMobs(spawnerName, fileManager.getSpawnerCooldown(spawnerName))) { - pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Spawner " + spawnerName + " is on cooldown. Current spawnedMobCount: "+spawnerData.spawnedMobCount); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Spawner " + spawnerName + " is on cooldown. Current spawnedMobCount: " + spawnerData.spawnedMobCount); continue; // Skip spawning if on cooldown } @@ -261,19 +277,95 @@ public void spawnCustomMobFromSpawner() { int remainingSlots = Math.max(0, maxMobs - spawnerData.spawnedMobCount); String mobName = fileManager.getSpawnerMobName(spawnerName); //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner "+spawnerName+", maxMobs: "+maxMobs+", remaining slots: "+remainingSlots); - if(remainingSlots==0){ - pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner 0 remaining slots for "+spawnerName); + if (remainingSlots == 0) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner 0 remaining slots for " + spawnerName); continue; } + int mobsToSpawn = Math.min(mobCount, remainingSlots); int spawnedMobs = 0; - pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner "+spawnerName+", maxMobs: "+maxMobs+", remaining slots: "+remainingSlots+", mobsToSpawn: "+mobsToSpawn+", spawnerData.spawnedMobCount: "+spawnerData.spawnedMobCount); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner " + spawnerName + ", maxMobs: " + maxMobs + ", remaining slots: " + remainingSlots + ", mobsToSpawn: " + mobsToSpawn + ", spawnerData.spawnedMobCount: " + spawnerData.spawnedMobCount); for (int i = 0; i < mobsToSpawn; i++) { - spawnCustomMob(location,spawnerName,mobName); + spawnCustomMob(location, spawnerName, mobName); + spawnerData.spawnedMobCount++; + spawnedMobs++; + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner spawnedMobs: " + spawnedMobs); + // Ustawianie czasu ostatniego respa mobów z tego spawnera + spawnerLastSpawnTimes.put(spawnerName, currentTime); + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid world specified for spawner " + spawnerName); + } + } else { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid location specified for spawner " + spawnerName); + } + } + } + + public void spawnerForceSpawn(String spawnerName) { + //pluginLogger.log(PluginLogger.LogLevel.INFO, "CustomMobs.spawnerForceSpawn called with " + spawnerName+" spawnedMobsMap"+spawnedMobsMap.toString()); + + Map spawnersData = fileManager.spawnersData; + if (spawnedMobsMap == null || spawnedMobsMap.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.WARNING, "CustomMobs.spawnerForceSpawn. The spawnedMobsMap is empty or null."); + }else { + try { + + Iterator> iterator = spawnedMobsMap.entrySet().iterator(); + //CustomMob customMob = betterElo.getCustomMobFromEntity(entity) ; + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn. Checking key " + entry.getKey() + " with value " + entry.getValue()); + if (spawnerName.equals(entry.getValue())) { + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn. " + spawnerName + " matching key " + entry.getKey() + ", value " + entry.getValue()); + Entity entity = Bukkit.getServer().getEntity(entry.getKey()); + if (entity != null && !entity.isDead()) { + entity.remove(); // Usuwa encję z świata + + iterator.remove(); // Bezpieczne usuwanie wpisu podczas iteracji + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn. Removing living mob from spawner" + spawnerName); + } + } + } + } catch (Exception e) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnerForceSpawn exception: " + e.getMessage()); + } + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn called. Loaded spawners: " + spawnersData); + // Sprawdzenie, czy istnieją spawnerzy w pliku + if (spawnersData.isEmpty()) { + pluginLogger.log(PluginLogger.LogLevel.ERROR, "No spawners found in spawners.yml."); + return; + } + + long currentTime = System.currentTimeMillis(); + + for (Map.Entry entry : spawnersData.entrySet()) { + if(!entry.getKey().equals(spawnerName)){ + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn checking spawner: " + entry); + continue; + } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn spawner: " + spawnerName+" found."); + CustomMobsFileManager.SpawnerData spawnerData = entry.getValue(); + Location location = getLocationFromString(spawnerData.location); + + + // Spawnowanie zombiaków na podanej lokalizacji + if (location != null) { + World world = location.getWorld(); + if (world != null) { + int mobCount = spawnerData.mobCount; + + String mobName = fileManager.getSpawnerMobName(spawnerName); + //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner "+spawnerName+", maxMobs: "+maxMobs+", remaining slots: "+remainingSlots); + int spawnedMobs = 0; + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn " + spawnerName + ", spawnerData.spawnedMobCount: " + spawnerData.spawnedMobCount); + for (int i = 0; i < mobCount; i++) { + spawnCustomMob(location, spawnerName, mobName); spawnerData.spawnedMobCount++; spawnedMobs++; } - pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnZombieFromSpawner spawnedMobs: "+spawnedMobs); + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn spawnedMobs: " + spawnedMobs); // Ustawianie czasu ostatniego respa mobów z tego spawnera spawnerLastSpawnTimes.put(spawnerName, currentTime); } else { @@ -282,10 +374,11 @@ public void spawnCustomMobFromSpawner() { } else { pluginLogger.log(PluginLogger.LogLevel.ERROR, "Invalid location specified for spawner " + spawnerName); } + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "CustomMobs.spawnerForceSpawn spawnedMobsMap"+spawnedMobsMap.toString()); } } - private Location getLocationFromString(String locationString) { + public Location getLocationFromString(String locationString) { try { String[] parts = locationString.split(","); if (parts.length == 4) { @@ -414,6 +507,14 @@ public CustomMob getCustomMob(String mobName) { // Zwróć customowego moba na podstawie nazwy return customMobsMap.get(mobName); } + public Entity getEntityForCustomMob(CustomMob customMob) { + // Sprawdzenie, czy przypisana encja do moba istnieje + if (customMob != null && customMob.entity != null) { + return customMob.entity; // Zwróć encję, jeśli jest już przypisana + } + // W przypadku braku encji, możemy zwrócić null lub rozważyć inne działanie, np. logowanie + return null; // Zwróć null, jeśli encja nie jest ustawiona + } public void spawnCustomMob(Location location, String spawnerName, String mobName) { pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob called, mobName: " + mobName+", spawnerName: "+spawnerName+", location: "+location); @@ -426,6 +527,12 @@ public void spawnCustomMob(Location location, String spawnerName, String mobName //newMob.dropTable = fileManager.loadCustomDrops(newMob.dropTableName); pluginLogger.log(PluginLogger.LogLevel.DROP, "CustomMobs.spawnCustomMob newMob.dropTablename: "+newMob.dropTableName+", newMob.dropTable: "+newMob.dropTable); pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobs.spawnCustomMob newMob.spawnerName: "+newMob.spawnerName); + try{ + spawnedMobsMap.put(newMob.entity.getUniqueId(), spawnerName); + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "Mob spawned with UUID: " + newMob.entity.getUniqueId() + ", spawnerName:" + newMob.spawnerName); + }catch (Exception e){ + pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnCustomMob exception: "+e.getMessage()); + } } else { pluginLogger.log(PluginLogger.LogLevel.ERROR, "CustomMobs.spawnCustomMob failed, mob not found: " + mobName); } diff --git a/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java b/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java index fff97b1..4bfed10 100644 --- a/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java +++ b/src/main/java/betterbox/mine/game/betterelo/CustomMobsFileManager.java @@ -38,6 +38,7 @@ public CustomMobsFileManager(String folderPath, JavaPlugin plugin, PluginLogger // Klasa wewnętrzna do przechowywania danych spawnera static class SpawnerData { String spawnerName; + int maxDistance; String location; String mobName; int cooldown; @@ -45,18 +46,29 @@ static class SpawnerData { int spawnedMobCount; // Counter for spawned mobs int maxMobs; - SpawnerData(String spawnerName, String location, String mobName, int cooldown, int mobCount, int maxMobs) { + SpawnerData(String spawnerName, String location, String mobName, int cooldown, int mobCount, int maxMobs, int maxDistance) { this.spawnerName = spawnerName; this.location = location; this.mobName = mobName; this.cooldown = cooldown; this.mobCount = mobCount; this.maxMobs = maxMobs; + this.maxDistance = maxDistance; this.spawnedMobCount = 0; // Initialize the spawned mob counter to 0 } public int getSpawnedMobCount() { return this.spawnedMobCount; } + public int getMaxMobs() { + return this.maxMobs; + } + public int getMobsPerSpawn() { + return this.mobCount; + } + public int getCooldown() { + return this.cooldown; + } + public int getMaxDistance() {return this.maxDistance;} } public class DropItem { private double dropChance; @@ -156,8 +168,11 @@ public void loadSpawners() { int cooldown = spawnerSection.getInt("cooldown"); int mobCount = spawnerSection.getInt("mobsPerSpawn"); int maxMobs = spawnerSection.getInt("maxMobs"); + //default 20 blocks + int maxDistance = 20; + maxDistance=spawnerSection.getInt("maxDistance"); // Zapisywanie danych spawnera do struktury w pamięci - spawnersData.put(key, new SpawnerData(key,location, mobName, cooldown,mobCount, maxMobs)); + spawnersData.put(key, new SpawnerData(key,location, mobName, cooldown,mobCount, maxMobs,maxDistance)); pluginLogger.log(PluginLogger.LogLevel.INFO, "Spawner "+key+" with mobName: "+mobName+", location: ("+location+"), cooldown: "+cooldown+", mobsPerSpawn: "+mobCount+", maxMobs: "+maxMobs+" loaded!"); } } @@ -182,6 +197,19 @@ public void saveSpawner(Location location, String spawnerName, String mobName, i } } + public int getMaxDistance(String spawnerName){ + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + //pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Spawner '" + spawnerName + "' spawnerData.maxDistance: "+spawnerData.maxDistance); + return spawnerData.maxDistance; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Spawner '" + spawnerName + "' not found."); + return 20; // or any other default value that indicates an error + } + } public String getSpawnerMobName(String spawnerName){ if (spawnersData.containsKey(spawnerName)) { // Retrieve the SpawnerData object corresponding to the spawnerName @@ -194,6 +222,18 @@ public String getSpawnerMobName(String spawnerName){ return null; // or any other default value that indicates an error } } + public String getSpawnerLocation(String spawnerName){ + if (spawnersData.containsKey(spawnerName)) { + // Retrieve the SpawnerData object corresponding to the spawnerName + SpawnerData spawnerData = spawnersData.get(spawnerName); + // Return the cooldown value + return spawnerData.location; + } else { + // If the spawnerName is not found, log an error and return a default value or throw an exception + pluginLogger.log(PluginLogger.LogLevel.ERROR, "Spawner '" + spawnerName + "' not found."); + return null; // or any other default value that indicates an error + } + } public int getSpawnerCooldown(String spawnerName) { // Check if the spawnerName exists in the spawnersData map if (spawnersData.containsKey(spawnerName)) { @@ -246,7 +286,7 @@ public CustomMobs.CustomMob loadCustomMob(JavaPlugin plugin, FileRewardManager d ItemStack leggings=null; ItemStack boots=null; ItemStack weapon=null; - + pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob entityTypeString: "+entityTypeString); if (entityTypeString.equals("SKELETON")||entityTypeString.equals("ZOMBIE")) {// Wczytanie wyposażenia z pliku pluginLogger.log(PluginLogger.LogLevel.CUSTOM_MOBS, "CustomMobsFileManager.loadCustomMob mob is ZOMBIE or SKELETON"); helmet = loadItemStack(mobData, "equipment.helmet"); diff --git a/src/main/java/betterbox/mine/game/betterelo/Event.java b/src/main/java/betterbox/mine/game/betterelo/Event.java index 40be049..73a6654 100644 --- a/src/main/java/betterbox/mine/game/betterelo/Event.java +++ b/src/main/java/betterbox/mine/game/betterelo/Event.java @@ -55,13 +55,14 @@ public class Event implements Listener { private HashMap lastZephyrUsage = new HashMap<>(); private HashMap lastFlameUsage = new HashMap<>(); private CustomMobs customMobs; + private CustomMobsFileManager customMobsFileManager; private GuiManager guiManager; private FileRewardManager fileRewardManager; private int deathEventCounter; private final Random random = new Random(); //public final long cooldownMillis = 1500; // 1.5s - public Event(DataManager dataManager, PluginLogger pluginLogger, JavaPlugin plugin, BetterRanksCheaters cheaters, ExtendedConfigManager configManager, BetterElo betterElo, CustomMobs customMobs, FileRewardManager fileRewardManager, GuiManager guiManager) { + public Event(DataManager dataManager, PluginLogger pluginLogger, JavaPlugin plugin, BetterRanksCheaters cheaters, ExtendedConfigManager configManager, BetterElo betterElo, CustomMobs customMobs, FileRewardManager fileRewardManager, GuiManager guiManager, CustomMobsFileManager customMobsFileManager) { this.dataManager = dataManager; this.fileRewardManager = fileRewardManager; this.pluginLogger = pluginLogger; @@ -70,6 +71,7 @@ public Event(DataManager dataManager, PluginLogger pluginLogger, JavaPlugin plug this.cheaters = cheaters; this.configManager = configManager; this.customMobs = customMobs; + this.customMobsFileManager = customMobsFileManager; this.guiManager = guiManager; Bukkit.getPluginManager().registerEvents(this, plugin); } @@ -193,23 +195,23 @@ private Player getLastAttacker(Player victim) { @EventHandler(priority = EventPriority.LOWEST) public void onPlayerDeath(PlayerDeathEvent event) { - if(deathEventCounter==1){ - pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath event already handled!"); + Player victim = event.getEntity(); + + if (victim.hasMetadata("handledDeath")) { + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath event already handled! killer: "+victim.getName()); return; } - deathEventCounter=1; + victim.setMetadata("handledDeath", new FixedMetadataValue(plugin, true)); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> victim.removeMetadata("handledDeath", plugin), 1L); + pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.handleKillEvent added handledDeath metadata to "+victim.getName()); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { - Player victim = event.getEntity(); + Player killer = victim.getKiller(); - if (killer.hasMetadata("handledDeath")) { - pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.onPlayerDeath event already handled! killer: "+victim.getName()); - return; - } - deathEventCounter=0; + if (!cheaters.getCheatersList().contains(victim.getName()) && !cheaters.getCheatersList().contains(killer.getName())) { pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: onPlayerDeath: victim: " + victim + " killer: " + killer); @@ -293,9 +295,7 @@ public void onPlayerDeath(PlayerDeathEvent event) { killer.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo] " + ChatColor.DARK_RED + "Your Elo difference in the Event ranking is too big! No reward for this one."); } } - killer.setMetadata("handledDeath", new FixedMetadataValue(plugin, true)); - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> killer.removeMetadata("handledDeath", plugin), 2L); - pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event.handleKillEvent added handledDeath metadata to "+killer.getName()); + } else { @@ -324,7 +324,7 @@ private void notifyPlayersAboutPoints(Player killer, Player victim, double point victim.sendMessage(ChatColor.GOLD + "" + ChatColor.BOLD + "[BetterElo]" + ChatColor.RED + "You have lost "+ChatColor.DARK_RED + "" + ChatColor.BOLD +df.format(pointsEarned)+" Elo"); } private void notifyPlayerAboutPoints(Player player, double pointsEarned, Double blockReward) { - pluginLogger.log(PluginLogger.LogLevel.KILL_EVENT, "Event: notifyPlayersAboutPoints called with parameters: "+player+" "+pointsEarned); + pluginLogger.log(PluginLogger.LogLevel.DEBUG, "Event: notifyPlayersAboutPoints called with parameters: "+player+" "+pointsEarned); DecimalFormat df = new DecimalFormat("#.##"); Duration fadeIn = Duration.ofMillis(300); // czas pojawiania się @@ -1574,6 +1574,42 @@ public void onInventoryClose(InventoryCloseEvent event) { } } } + @EventHandler + public void onEntityMove(EntityMoveEvent event) { + Entity entity = event.getEntity(); + CustomMobs.CustomMob customMob = null; + customMob = betterElo.getCustomMobFromEntity(entity); + + if (customMob != null) { + Location entityLocation = entity.getLocation(); + String spawnerLocationString = customMobsFileManager.getSpawnerLocation(customMob.spawnerName); + Location spawnerLocation = customMobs.getLocationFromString(spawnerLocationString); + + int maxDistance = customMobsFileManager.getMaxDistance(customMob.spawnerName); + if(maxDistance==0){ + maxDistance=20; + } + if (spawnerLocation==null){ + return; + } + if (entityLocation.distance(spawnerLocation) > maxDistance) { + // Teleportacja entity z powrotem do spawnerLocation + pluginLogger.log(PluginLogger.LogLevel.SPAWNERS, "Event.onEntityMove teleporting mob: "+customMob.mobName); + while (spawnerLocation.getBlock().getType() != Material.AIR) { + spawnerLocation.add(0, 1, 0); // Zwiększ y o 1 + if (spawnerLocation.getBlockY() > spawnerLocation.getWorld().getMaxHeight()) { + // Jeśli przekraczamy maksymalną wysokość, przerwij pętlę, aby uniknąć pętli nieskończonej + System.out.println("Reached the top of the world without finding an AIR block."); + break; + } + } + spawnerLocation.add(0, 1, 0); + entity.teleport(spawnerLocation); + } + + + } + }