diff --git a/.github/README.md b/.github/README.md index 560338605..1d7157335 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,50 +1,30 @@ -![](https://images.plugily.xyz/banner/display.php?id=VillageDefense) - -# Village Defense [![Maven Repository](https://maven.plugily.xyz/api/badge/latest/releases/plugily/projects/villagedefense?color=40c14a&name=Maven&prefix=v)](https://maven.plugily.xyz/#/releases/plugily/projects/villagedefense) [![JavaDoc Repository](https://maven.plugily.xyz/api/badge/latest/releases/plugily/projects/villagedefense?color=40c14a&name=JavaDoc&prefix=v)](https://maven.plugily.xyz/javadoc/releases/plugily/projects/villagedefense/latest) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=Plugily-Projects_Village_Defense&metric=sqale_rating)](https://sonarcloud.io/summary/overall?id=Plugily-Projects_Village_Defense) [![Discord](https://img.shields.io/discord/345628548716822530.svg?color=7289DA&style=for-the-badge&logo=discord)](https://discord.plugily.xyz) [![Patreon]( https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://patreon.com/plugily) - -Village Defense is a Minecraft minigame designed for small and big servers. This minigame is unique and very -configurable, 100% free and open source! - -The goal is to protect Villagers from hordes of undead Creatures. However, the game isn't that easy. There are more and -more zombies every wave and more types of them come in higher waves. There is no wave limit so try to survive as long as -you can! - -Have fun using it! Leave a good rating if you really like it. - -## Want to contribute in this project? - -[**🉑 Code Contributions**](https://github.com/Plugily-Projects/Village_Defense/blob/master/.github/CONTRIBUTING.md) -[**💣 Issues Reporting (Discord)**](https://discordapp.com/invite/UXzUdTP) -[**❤ Make Donation**](https://www.paypal.me/plugilyprojects) - -# Credits - -## Open Source Libraries - -| Library | Author | License | -|------------------------------------------------------------------|--------------------------------------------------------|------------------------------------------------------------------------------------| -| [MiniGamesBox](https://github.com/Plugily-Projects/MiniGamesBox) | [Plugily Projets](https://github.com/Plugily-Projects) | [GPLv3](https://github.com/Plugily-Projects/MiniGamesBox/blob/master/LICENSE.md) | -| [ScoreboardLib](https://github.com/TigerHix/ScoreboardLib/) | [TigerHix](https://github.com/TigerHix) | [LGPLv3](https://github.com/TigerHix/ScoreboardLib/blob/master/LICENSE) | -| [HikariCP](https://github.com/brettwooldridge/HikariCP) | [brettwooldridge](https://github.com/brettwooldridge) | [Apache License 2.0](https://github.com/brettwooldridge/HikariCP/blob/dev/LICENSE) | -| [bStats](https://github.com/Bastian/bStats-Metrics) | [Bastian](https://github.com/Bastian) | [LGPLv3](https://github.com/Bastian/bStats-Metrics/blob/master/LICENSE) | -| [Commons Box](https://github.com/Plajer/Commons-Box) | [Plajer](https://github.com/Plajer) | [GPLv3](https://github.com/Plajer/Commons-Box/blob/master/LICENSE.md) | - -## Open Source Licenses - -#### JetBrains - -jetbrains logo - -Thanks to JetBrains for Open Source Program license for open source development. - -#### Code Whale - -jetbrains logo - -Thanks to Code Whale for Open Source license for POEditor project. - -## Contributors - -[List of all contributors here](https://plajer.xyz/contributors/villagedefense.html) - - +# Village Defense Gold + +A hard fork created to implement many new exciting features into Village Defense 4.0.0. + +Formerly known as Village Defense 5.0.0 update this hard fork now focuses on personal upgrades to the codebase with new +gameplay stuff and other features. + +**No support and maintenance obligations are provided for this hard fork as it's only intended for private/limited group +use only.** +**Feel free to compile sources yourself and edit the plugin accordingly to your needs** + +Depends on [MinigamesBoxGold](https://github.com/Plajer/MinigamesBoxGold) + +### List of features done and planned for this version: + +* **Opinionated design choices and hardcoded values and options** +* Many QoL and gameplay loop and pacing improvements +* Drastically improved Look and Feel (sounds & effects) +* Many fixes including ally pets targeting villagers/other pets/players +* Kits balance changes +* Revamped powerups +* Revamped entity upgrades (including hidden & special upgrades) +* Mid-wave special events (shop offer, rotten flesh trader, pinata etc.) +* Arena personal records +* Enemies spawn system revamp +* New and more enjoyable enemies +* Shop auto armor equip +* Bosses between every game state (wave 15, wave 30, wave 50) +* Engineer kit - replacement for Builder kit but with Turrets +* Weekly random challenges \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index ee0f49901..30168cf46 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,19 +33,31 @@ repositories { maven(uri("https://maven.plugily.xyz/snapshots")) maven(uri("https://repo.citizensnpcs.co/")) maven(uri("https://repo.maven.apache.org/maven2/")) + maven(uri("https://repo.dmulloy2.net/repository/public/")) } dependencies { - implementation("plugily.projects:MiniGamesBox-Classic:1.2.0-SNAPSHOT36") { isTransitive = false } - compileOnly("org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT") + implementation(files("lib/box-classic.jar")) + implementation(files("lib/box-db.jar")) + implementation(files("lib/box-inv.jar")) + implementation(files("lib/box-utils.jar")) + implementation("org.openjdk.nashorn:nashorn-core:15.1") + implementation("io.github.skytasul:glowingentities:1.3.2") + compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") compileOnly("org.jetbrains:annotations:24.0.1") + + compileOnly("com.mojang:authlib:3.11.50") + compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0") compileOnly(files("lib/spigot/1.8.8-R0.1.jar")) + + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") } group = "plugily.projects" -version = "4.6.1-SNAPSHOT79" +version = "5.0.1-SNAPSHOT6" description = "VillageDefense" java { withJavadocJar() @@ -73,6 +85,12 @@ tasks { options.encoding = "UTF-8" } + compileJava { + options.encoding = "UTF-8" + targetCompatibility = JavaVersion.VERSION_17.toString() + sourceCompatibility = JavaVersion.VERSION_17.toString() + } + } publishing { diff --git a/src/main/java/plugily/projects/villagedefense/Main.java b/src/main/java/plugily/projects/villagedefense/Main.java index 3b82dbbad..1e9281678 100644 --- a/src/main/java/plugily/projects/villagedefense/Main.java +++ b/src/main/java/plugily/projects/villagedefense/Main.java @@ -1,24 +1,25 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense; -import org.bukkit.Bukkit; +import fr.skytasul.glowingentities.GlowingEntities; +import lombok.Getter; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPluginLoader; @@ -27,6 +28,7 @@ import plugily.projects.minigamesbox.classic.handlers.setup.SetupInventory; import plugily.projects.minigamesbox.classic.handlers.setup.categories.PluginSetupCategoryManager; import plugily.projects.minigamesbox.classic.utils.configuration.ConfigUtils; +import plugily.projects.minigamesbox.classic.utils.misc.MiscUtils; import plugily.projects.minigamesbox.classic.utils.services.metrics.Metrics; import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; import plugily.projects.villagedefense.arena.Arena; @@ -35,43 +37,32 @@ import plugily.projects.villagedefense.arena.ArenaRegistry; import plugily.projects.villagedefense.arena.ArenaUtils; import plugily.projects.villagedefense.arena.managers.enemy.spawner.EnemySpawnerRegistry; -import plugily.projects.villagedefense.arena.managers.enemy.spawner.EnemySpawnerRegistryLegacy; +import plugily.projects.villagedefense.arena.powerup.PowerupEvents; import plugily.projects.villagedefense.boot.AdditionalValueInitializer; import plugily.projects.villagedefense.boot.MessageInitializer; import plugily.projects.villagedefense.boot.PlaceholderInitializer; import plugily.projects.villagedefense.commands.arguments.ArgumentsRegistry; import plugily.projects.villagedefense.creatures.CreatureUtils; import plugily.projects.villagedefense.creatures.DoorBreakListener; +import plugily.projects.villagedefense.events.EntityUpgradeListener; import plugily.projects.villagedefense.events.PluginEvents; -import plugily.projects.villagedefense.handlers.powerup.PowerupHandler; +import plugily.projects.villagedefense.handlers.hologram.NewHologramManager; import plugily.projects.villagedefense.handlers.setup.SetupCategoryManager; -import plugily.projects.villagedefense.handlers.upgrade.EntityUpgradeMenu; -import plugily.projects.villagedefense.handlers.upgrade.upgrades.Upgrade; -import plugily.projects.villagedefense.handlers.upgrade.upgrades.UpgradeBuilder; -import plugily.projects.villagedefense.kits.free.KnightKit; -import plugily.projects.villagedefense.kits.free.LightTankKit; -import plugily.projects.villagedefense.kits.level.ArcherKit; -import plugily.projects.villagedefense.kits.level.GolemFriendKit; -import plugily.projects.villagedefense.kits.level.HardcoreKit; -import plugily.projects.villagedefense.kits.level.HealerKit; -import plugily.projects.villagedefense.kits.level.LooterKit; -import plugily.projects.villagedefense.kits.level.MediumTankKit; -import plugily.projects.villagedefense.kits.level.PuncherKit; -import plugily.projects.villagedefense.kits.level.RunnerKit; -import plugily.projects.villagedefense.kits.level.TerminatorKit; -import plugily.projects.villagedefense.kits.level.WorkerKit; -import plugily.projects.villagedefense.kits.level.ZombieFinderKit; -import plugily.projects.villagedefense.kits.premium.BlockerKit; -import plugily.projects.villagedefense.kits.premium.CleanerKit; -import plugily.projects.villagedefense.kits.premium.DogFriendKit; -import plugily.projects.villagedefense.kits.premium.HeavyTankKit; -import plugily.projects.villagedefense.kits.premium.MedicKit; -import plugily.projects.villagedefense.kits.premium.NakedKit; -import plugily.projects.villagedefense.kits.premium.PremiumHardcoreKit; -import plugily.projects.villagedefense.kits.premium.ShotBowKit; -import plugily.projects.villagedefense.kits.premium.TeleporterKit; -import plugily.projects.villagedefense.kits.premium.TornadoKit; -import plugily.projects.villagedefense.kits.premium.WizardKit; +import plugily.projects.villagedefense.handlers.upgrade.EntityUpgradeHandlerEvents; +import plugily.projects.villagedefense.handlers.upgrade.NewEntityUpgradeManager; +import plugily.projects.villagedefense.kits.BuilderKit; +import plugily.projects.villagedefense.kits.CleanerKit; +import plugily.projects.villagedefense.kits.CrusaderKit; +import plugily.projects.villagedefense.kits.KnightKit; +import plugily.projects.villagedefense.kits.MedicKit; +import plugily.projects.villagedefense.kits.PetsFriend; +import plugily.projects.villagedefense.kits.ShotBowKit; +import plugily.projects.villagedefense.kits.TerminatorKit; +import plugily.projects.villagedefense.kits.TornadoKit; +import plugily.projects.villagedefense.kits.WizardKit; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.user.VDUserManager; +import plugily.projects.villagedefense.utils.ProtocolUtils; import java.io.File; import java.util.logging.Level; @@ -82,11 +73,16 @@ */ public class Main extends PluginMain { - private FileConfiguration entityUpgradesConfig; - private EnemySpawnerRegistryLegacy enemySpawnerRegistry; + private @Getter FileConfiguration entityUpgradesConfig; + private @Getter EnemySpawnerRegistry enemySpawnerRegistry; + private @Getter NewEntityUpgradeManager entityUpgradeManager; + private @Getter NewHologramManager newHologramManager; + private @Getter VDUserManager vdUserManager; + private @Getter GlowingEntities glowingEntities; + + private ArgumentsRegistry argumentsRegistry; private ArenaRegistry arenaRegistry; private ArenaManager arenaManager; - private ArgumentsRegistry argumentsRegistry; @TestOnly public Main() { @@ -103,6 +99,9 @@ public void onEnable() { long start = System.currentTimeMillis(); MessageInitializer messageInitializer = new MessageInitializer(this); super.onEnable(); + /*if(!validateStartup()) { + return; + }*/ getDebugger().debug("[System] [Plugin] Initialization start"); new PlaceholderInitializer(this); messageInitializer.registerMessages(); @@ -113,33 +112,46 @@ public void onEnable() { getDebugger().debug("[System] [Plugin] Initialization finished took {0}ms", System.currentTimeMillis() - start); } + private boolean validateStartup() { + if (ServerVersion.Version.isCurrentLower(ServerVersion.Version.v1_12_R1)) { + MiscUtils.sendLineBreaker(this.getName()); + getMessageUtils().thisVersionIsNotSupported(); + MiscUtils.sendVersionInformation(this, this.getName(), this.getDescription()); + getDebugger().sendConsoleMsg(getPluginMessagePrefix() + "&cYour server version is not supported by " + this.getDescription().getName() + "!"); + getDebugger().sendConsoleMsg(getPluginMessagePrefix() + "&cSadly, we must shut off. Maybe you consider changing your server version?"); + MiscUtils.sendLineBreaker(this.getName()); + getServer().getPluginManager().disablePlugin(this); + return false; + } + return true; + } + public void initializePluginClasses() { addFileName("powerups"); addFileName("creatures"); Arena.init(this); ArenaUtils.init(this); + KitHelper.init(this); + ProtocolUtils.init(this); new ArenaEvents(this); + new PowerupEvents(this); + vdUserManager = new VDUserManager(this); arenaManager = new ArenaManager(this); arenaRegistry = new ArenaRegistry(this); arenaRegistry.registerArenas(); getSignManager().loadSigns(); getSignManager().updateSigns(); argumentsRegistry = new ArgumentsRegistry(this); - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_8_R3)) { - enemySpawnerRegistry = new EnemySpawnerRegistryLegacy(this); - } else { - enemySpawnerRegistry = new EnemySpawnerRegistry(this); - } - if(getConfigPreferences().getOption("UPGRADES")) { - entityUpgradesConfig = ConfigUtils.getConfig(this, "entity_upgrades"); - Upgrade.init(this); - UpgradeBuilder.init(this); - new EntityUpgradeMenu(this); - } + enemySpawnerRegistry = new EnemySpawnerRegistry(this); + entityUpgradesConfig = ConfigUtils.getConfig(this, "entity_upgrades"); + entityUpgradeManager = new NewEntityUpgradeManager(this); + newHologramManager = new NewHologramManager(this); new DoorBreakListener(this); CreatureUtils.init(this); - new PowerupHandler(this); new PluginEvents(this); + new EntityUpgradeListener(this); + new EntityUpgradeHandlerEvents(this); + this.glowingEntities = new GlowingEntities(this); addPluginMetrics(); } @@ -147,13 +159,12 @@ public void addKits() { long start = System.currentTimeMillis(); getDebugger().debug("Adding kits..."); addFileName("kits"); - Class[] classKitNames = new Class[]{KnightKit.class, LightTankKit.class, ZombieFinderKit.class, ArcherKit.class, PuncherKit.class, HealerKit.class, LooterKit.class, RunnerKit.class, - MediumTankKit.class, WorkerKit.class, GolemFriendKit.class, TerminatorKit.class, HardcoreKit.class, CleanerKit.class, TeleporterKit.class, HeavyTankKit.class, ShotBowKit.class, - DogFriendKit.class, PremiumHardcoreKit.class, TornadoKit.class, BlockerKit.class, MedicKit.class, NakedKit.class, WizardKit.class}; - for(Class kitClass : classKitNames) { + Class[] classKitNames = new Class[]{KnightKit.class, BuilderKit.class, TornadoKit.class, ShotBowKit.class, MedicKit.class, + CleanerKit.class, PetsFriend.class, TerminatorKit.class, CrusaderKit.class, WizardKit.class}; + for (Class kitClass : classKitNames) { try { kitClass.getDeclaredConstructor().newInstance(); - } catch(Exception e) { + } catch (Exception e) { getLogger().log(Level.SEVERE, "Fatal error while registering existing game kit! Report this error to the developer!"); getLogger().log(Level.SEVERE, "Cause: " + e.getMessage() + " (kitClass " + kitClass.getName() + ")"); e.printStackTrace(); @@ -162,23 +173,16 @@ public void addKits() { getDebugger().debug("Kit adding finished took {0}ms", System.currentTimeMillis() - start); } + private void addPluginMetrics() { getMetrics().addCustomChart(new Metrics.SimplePie("hooked_addons", () -> { - if(getServer().getPluginManager().getPlugin("VillageDefense-Enhancements") != null) { + if (getServer().getPluginManager().getPlugin("VillageDefense-Enhancements") != null) { return "Enhancements"; } return "None"; })); } - public FileConfiguration getEntityUpgradesConfig() { - return entityUpgradesConfig; - } - - public EnemySpawnerRegistryLegacy getEnemySpawnerRegistry() { - return enemySpawnerRegistry; - } - @Override public ArenaRegistry getArenaRegistry() { return arenaRegistry; @@ -198,4 +202,5 @@ public ArenaManager getArenaManager() { public PluginSetupCategoryManager getSetupCategoryManager(SetupInventory setupInventory) { return new SetupCategoryManager(setupInventory); } + } diff --git a/src/main/java/plugily/projects/villagedefense/api/event/player/VillagePlayerEntityUpgradeEvent.java b/src/main/java/plugily/projects/villagedefense/api/event/player/VillagePlayerEntityUpgradeEvent.java index b4bde5b77..a1a976106 100644 --- a/src/main/java/plugily/projects/villagedefense/api/event/player/VillagePlayerEntityUpgradeEvent.java +++ b/src/main/java/plugily/projects/villagedefense/api/event/player/VillagePlayerEntityUpgradeEvent.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.api.event.player; @@ -23,7 +23,7 @@ import org.bukkit.event.HandlerList; import plugily.projects.minigamesbox.classic.api.event.PlugilyEvent; import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.handlers.upgrade.upgrades.Upgrade; +import plugily.projects.villagedefense.handlers.upgrade.EntityUpgrade; /** * @author Plajer @@ -31,15 +31,16 @@ *

* Called when player upgrades an entity. */ +@Deprecated public class VillagePlayerEntityUpgradeEvent extends PlugilyEvent { private static final HandlerList HANDLERS = new HandlerList(); private final Entity entity; private final Player player; - private final Upgrade appliedUpgrade; + private final EntityUpgrade appliedUpgrade; private final int tier; - public VillagePlayerEntityUpgradeEvent(Arena eventArena, Entity entity, Player player, Upgrade appliedUpgrade, int tier) { + public VillagePlayerEntityUpgradeEvent(Arena eventArena, Entity entity, Player player, EntityUpgrade appliedUpgrade, int tier) { super(eventArena); this.entity = entity; this.player = player; @@ -63,7 +64,7 @@ public Entity getEntity() { /** * @return upgrade that was applied to entity */ - public Upgrade getAppliedUpgrade() { + public EntityUpgrade getAppliedUpgrade() { return appliedUpgrade; } diff --git a/src/main/java/plugily/projects/villagedefense/arena/Arena.java b/src/main/java/plugily/projects/villagedefense/arena/Arena.java index 4c8313647..c4ae4d72e 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/Arena.java +++ b/src/main/java/plugily/projects/villagedefense/arena/Arena.java @@ -1,56 +1,63 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena; +import org.bukkit.DyeColor; import org.bukkit.Location; +import org.bukkit.attribute.Attribute; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.IronGolem; import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Villager; import org.bukkit.entity.Wolf; +import org.bukkit.metadata.FixedMetadataValue; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import plugily.projects.minigamesbox.classic.arena.ArenaState; import plugily.projects.minigamesbox.classic.arena.PluginArena; import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.misc.MiscUtils; import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.assist.AssistHandler; import plugily.projects.villagedefense.arena.managers.CreatureTargetManager; import plugily.projects.villagedefense.arena.managers.EnemySpawnManager; import plugily.projects.villagedefense.arena.managers.ScoreboardManager; import plugily.projects.villagedefense.arena.managers.ShopManager; import plugily.projects.villagedefense.arena.managers.maprestorer.MapRestorerManager; -import plugily.projects.villagedefense.arena.managers.maprestorer.MapRestorerManagerLegacy; +import plugily.projects.villagedefense.arena.midwave.MidWaveEvent; import plugily.projects.villagedefense.arena.states.EndingState; import plugily.projects.villagedefense.arena.states.InGameState; import plugily.projects.villagedefense.arena.states.RestartingState; import plugily.projects.villagedefense.arena.states.StartingState; import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.creatures.v1_9_UP.CustomCreature; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; import java.util.logging.Level; import java.util.stream.Collectors; @@ -66,15 +73,18 @@ public class Arena extends PluginArena { private final List wolves = new ArrayList<>(); private final List villagers = new ArrayList<>(); private final List ironGolems = new ArrayList<>(); + private final List specialEntities = new ArrayList<>(); private final List droppedFleshes = new ArrayList<>(); private final List spawnedEntities = new ArrayList<>(); private MapRestorerManager mapRestorerManager; + private MidWaveEvent midWaveEvent; private final Map> spawnPoints = new EnumMap<>(SpawnPoint.class); private ShopManager shopManager; private EnemySpawnManager enemySpawnManager; private CreatureTargetManager creatureTargetManager; + private AssistHandler assistHandler; private boolean fighting = false; @@ -84,11 +94,8 @@ public Arena(String id) { shopManager = new ShopManager(this); enemySpawnManager = new EnemySpawnManager(this); creatureTargetManager = new CreatureTargetManager(this); - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_16_R1)) { - mapRestorerManager = new MapRestorerManagerLegacy(this); - } else { - mapRestorerManager = new MapRestorerManager(this); - } + mapRestorerManager = new MapRestorerManager(this); + assistHandler = new AssistHandler(plugin); setMapRestorerManager(mapRestorerManager); setScoreboardManager(new ScoreboardManager(this)); @@ -129,6 +136,10 @@ public CreatureTargetManager getCreatureTargetManager() { return creatureTargetManager; } + public AssistHandler getAssistHandler() { + return assistHandler; + } + public void clearVillagers() { for(Entity entity : plugin.getBukkitHelper().getNearbyEntities(getStartLocation(), 50)) { if(!(entity instanceof Villager)) { @@ -234,34 +245,58 @@ public void setWave(int wave) { public void spawnVillager(Location location) { Villager villager = CreatureUtils.getCreatureInitializer().spawnVillager(location); - villager.setCustomNameVisible(getPlugin().getConfigPreferences().getOption("NAME_VISIBILITY_VILLAGER")); - villager.setCustomName(CreatureUtils.getRandomVillagerName()); + villager.setCustomNameVisible(true); + String name = CreatureUtils.getRandomVillagerName(); + villager.setMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA, new FixedMetadataValue(plugin, name)); + villager.setCustomName(CreatureUtils.getHealthNameTag(villager)); + villager.setVillagerLevel(5); + villager.setVillagerType(Villager.Type.values()[ThreadLocalRandom.current().nextInt(Villager.Type.values().length)]); + villager.setProfession(Villager.Profession.values()[ThreadLocalRandom.current().nextInt(Villager.Profession.values().length)]); addVillager(villager); } - public void spawnWolf(Location location, Player player) { + @Nullable + public Creature spawnWolf(Location location, Player player) { if(!canSpawnMobForPlayer(player, EntityType.WOLF)) { - return; + return null; } + return spawnWolfForce(location, player); + } + @Nullable + public Creature spawnWolfForce(Location location, Player player) { Wolf wolf = CreatureUtils.getCreatureInitializer().spawnWolf(location); + wolf.setMetadata("VD_OWNER_UUID", new FixedMetadataValue(getPlugin(), player.getUniqueId().toString())); + wolf.setMetadata("VD_ALIVE_SINCE_WAVE", new FixedMetadataValue(getPlugin(), getWave())); wolf.setOwner(player); - wolf.setCustomNameVisible(getPlugin().getConfigPreferences().getOption("NAME_VISIBILITY_WOLF")); - wolf.setCustomName(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_NAME").asKey().player(player).build()); + wolf.setCustomNameVisible(true); + wolf.setCollarColor(DyeColor.values()[ThreadLocalRandom.current().nextInt(DyeColor.values().length)]); + wolf.setCustomName(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_NAME").asKey().integer(0).player(player).build()); new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_SPAWN").asKey().player(player).sendPlayer(); addWolf(wolf); + return wolf; } - public void spawnGolem(Location location, Player player) { + @Nullable + public Creature spawnGolem(Location location, Player player) { if(!canSpawnMobForPlayer(player, EntityType.IRON_GOLEM)) { - return; + return null; } + return spawnGolemForce(location, player); + } + @Nullable + public Creature spawnGolemForce(Location location, Player player) { IronGolem ironGolem = CreatureUtils.getCreatureInitializer().spawnGolem(location); - ironGolem.setCustomNameVisible(getPlugin().getConfigPreferences().getOption("NAME_VISIBILITY_GOLEM")); - ironGolem.setCustomName(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_NAME").asKey().player(player).build()); + ironGolem.setMetadata("VD_OWNER_UUID", new FixedMetadataValue(getPlugin(), player.getUniqueId().toString())); + ironGolem.setMetadata("VD_ALIVE_SINCE_WAVE", new FixedMetadataValue(getPlugin(), getWave())); + ironGolem.setCustomNameVisible(true); + ironGolem.setCustomName(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_NAME").asKey().integer(0).player(player).build()); + ironGolem.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(150.0); new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_SPAWN").asKey().player(player).sendPlayer(); addIronGolem(ironGolem); + MiscUtils.getEntityAttribute(ironGolem, Attribute.GENERIC_MOVEMENT_SPEED).ifPresent(ai -> ai.setBaseValue(0.25)); + return ironGolem; } protected void addWolf(Wolf wolf) { @@ -274,60 +309,29 @@ public boolean canSpawnMobForPlayer(Player player, EntityType type) { return false; } int globalEntityLimit = 0; - int entityLimit = 0; - String spawnedName = ""; switch(type) { case WOLF: - entityLimit = plugin.getPermissionsManager().getPermissionCategoryValue("PLAYER_SPAWN_LIMIT_WOLVES", player); - spawnedName = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_NAME").asKey().player(player).build(); globalEntityLimit = plugin.getConfig().getInt("Limit.Spawn.Wolves", 20); break; case IRON_GOLEM: - entityLimit = plugin.getPermissionsManager().getPermissionCategoryValue("PLAYER_SPAWN_LIMIT_GOLEMS", player); - spawnedName = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_NAME").asKey().player(player).build(); globalEntityLimit = plugin.getConfig().getInt("Limit.Spawn.Golems", 15); break; default: break; } - plugin.getDebugger().debug("SpawnMobCheck for {0} and mob {1}, globalLimit {2}, playerLimit {3}", player.getName(), type, globalEntityLimit, entityLimit); - String finalSpawnedName = spawnedName; + plugin.getDebugger().debug("SpawnMobCheck for {0} and mob {1}, globalLimit {2}", player.getName(), type, globalEntityLimit); List entities = new ArrayList<>(spawnedEntities); if(plugin.getConfigPreferences().getOption("LIMIT_ENTITY_BUY_AFTER_DEATH")) { List entityList = entities.stream().filter(entity -> entity.getType() == type).collect(Collectors.toList()); - entityList = entityList.stream().filter(Entity::isDead).collect(Collectors.toList()); + entityList = entityList.stream().filter(en -> !en.isDead()).collect(Collectors.toList()); long spawnedAmount = entityList.size(); if(spawnedAmount >= globalEntityLimit) { - sendMobLimitReached(player, globalEntityLimit); - return false; - } - - long spawnedPlayerAmount = entityList.stream().filter(entity -> Objects.equals(entity.getCustomName(), finalSpawnedName)).count(); - if(spawnedPlayerAmount >= entityLimit) { - sendMobLimitReached(player, entityLimit); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_MOB_LIMIT_REACHED").asKey().player(player).integer(globalEntityLimit).sendPlayer(); return false; } } - boolean finalReturn = false; - switch(type) { - case WOLF: - finalReturn = entityLimit > 0 && wolves.size() < entityLimit; - break; - case IRON_GOLEM: - finalReturn = entityLimit > 0 && ironGolems.size() < entityLimit; - break; - default: - break; - } - if(!finalReturn) { - sendMobLimitReached(player, entityLimit); - } - return finalReturn; - } - - private void sendMobLimitReached(Player player, int entityLimit) { - new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_MOB_LIMIT_REACHED").asKey().player(player).integer(entityLimit).sendPlayer(); + return true; } /** @@ -360,6 +364,16 @@ public List getVillagers() { return villagers; } + /** + * Get special alive entities. + * + * @return alive special entities + */ + @NotNull + public List getSpecialEntities() { + return specialEntities; + } + public boolean checkLevelUpRottenFlesh() { String rottenFleshLevelOption = "ROTTEN_FLESH_LEVEL"; int rottenFleshLevel = getArenaOption(rottenFleshLevelOption); @@ -393,6 +407,14 @@ public MapRestorerManager getMapRestorerManager() { return mapRestorerManager; } + public MidWaveEvent getMidWaveEvent() { + return midWaveEvent; + } + + public void setMidWaveEvent(MidWaveEvent midWaveEvent) { + this.midWaveEvent = midWaveEvent; + } + @NotNull public List getZombieSpawns() { return spawnPoints.getOrDefault(SpawnPoint.ZOMBIE, new ArrayList<>()); @@ -411,11 +433,21 @@ protected void addIronGolem(IronGolem ironGolem) { public void removeIronGolem(IronGolem ironGolem) { ironGolem.remove(); ironGolems.remove(ironGolem); + spawnedEntities.remove(ironGolem); } public void removeWolf(Wolf wolf) { wolf.remove(); wolves.remove(wolf); + spawnedEntities.remove(wolf); + } + + public void addSpecialEntity(LivingEntity livingEntity) { + specialEntities.add(livingEntity); + } + + public void removeSpecialEntity(LivingEntity entity) { + specialEntities.remove(entity); } public enum SpawnPoint { diff --git a/src/main/java/plugily/projects/villagedefense/arena/ArenaEvents.java b/src/main/java/plugily/projects/villagedefense/arena/ArenaEvents.java index ba37599f8..c42bb8f9e 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/ArenaEvents.java +++ b/src/main/java/plugily/projects/villagedefense/arena/ArenaEvents.java @@ -1,27 +1,30 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.IronGolem; import org.bukkit.entity.LivingEntity; @@ -33,9 +36,12 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; import plugily.projects.minigamesbox.classic.arena.ArenaState; @@ -46,7 +52,14 @@ import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyEntityPickupItemEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.handlers.upgrade.EntityUpgrade; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; /** * @author Plajer @@ -63,38 +76,145 @@ public ArenaEvents(Main plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); } + @EventHandler + public void onWolfTeleport(EntityTeleportEvent event) { + if (!(event.getEntity() instanceof Wolf wolf)) { + return; + } + if (!wolf.hasMetadata("VD_OWNER_UUID")) { + return; + } + if (wolf.hasMetadata("VD_TELEPORT_OVERRIDE_TEMP")) { + return; + } + //is a VD entity, cancel no matter what, unless overridden + event.setCancelled(true); + } + + @EventHandler + public void onPlayerFocusAdjust(EntityTargetLivingEntityEvent event) { + if (!(event.getTarget() instanceof Player)) { + return; + } + Player player = (Player) event.getTarget(); + if (!plugin.getArenaRegistry().isInArena(player)) { + return; + } + User user = plugin.getUserManager().getUser(player); + //cancel targeting of spectators or being targeted by ally pets + if (user.isSpectator() || event.getEntity() instanceof Wolf || event.getEntity() instanceof IronGolem) { + event.setCancelled(true); + } + } + + @EventHandler + public void onAllyFocusAdjust(EntityTargetLivingEntityEvent event) { + if (event.getTarget() instanceof Player) { + //prevent ally pets targeting players + if (event.getEntity() instanceof Wolf || event.getEntity() instanceof IronGolem) { + //cancel no matter which wolf/golem targets player, naively assume it's the same arena entity + if (plugin.getArenaRegistry().isInArena((Player) event.getTarget())) { + event.setCancelled(true); + } + } + } else if (event.getTarget() instanceof Wolf || event.getTarget() instanceof IronGolem) { + //prevent ally pets targeting ally pets + if (event.getEntity() instanceof Wolf || event.getEntity() instanceof IronGolem) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + List allies = new ArrayList<>(); + allies.addAll(arena.getWolves()); + allies.addAll(arena.getIronGolems()); + if (allies.contains(event.getEntity()) && allies.contains(event.getTarget())) { + event.setCancelled(true); + return; + } + } + } + } else if (event.getTarget() instanceof Villager villager) { + //prevent ally pets targeting villagers + if (event.getEntity() instanceof Wolf || event.getEntity() instanceof IronGolem) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + List allies = new ArrayList<>(); + allies.addAll(arena.getWolves()); + allies.addAll(arena.getIronGolems()); + if (allies.contains(event.getEntity()) && arena.getVillagers().contains(villager)) { + event.setCancelled(true); + return; + } + } + } + } + } + //override WorldGuard build deny flag where villagers cannot be damaged @EventHandler(priority = EventPriority.HIGHEST) public void onVillagerDamage(EntityDamageByEntityEvent e) { - if(e.getEntityType() != EntityType.VILLAGER || !(e.getDamager() instanceof Creature)) { + if (e.getEntityType() != EntityType.VILLAGER || !(e.getDamager() instanceof Creature)) { return; } - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(arena.getVillagers().contains(e.getEntity()) && arena.getEnemies().contains(e.getDamager())) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (arena.getVillagers().contains(e.getEntity()) && arena.getEnemies().contains(e.getDamager())) { e.setCancelled(false); + e.getEntity().setCustomName(CreatureUtils.getHealthNameTagPreDamage((Creature) e.getEntity(), e.getFinalDamage())); + XSound.ENTITY_VILLAGER_HURT.play(e.getEntity().getLocation(), 10.0f, 1.0f); + + doApplyDamageGlowingWarning(e.getDamager(), arena); break; } } } + private void doApplyDamageGlowingWarning(Entity target, Arena arena) { + String GLOWING_TARGET_METADATA = "VD_RECENT_VILLAGER_DAMAGE_GLOW"; + target.setMetadata(GLOWING_TARGET_METADATA, new FixedMetadataValue(plugin, true)); + new BukkitRunnable() { + boolean toggle = false; + int tick = 0; + + @Override + public void run() { + if (target.isDead() || tick >= 60) { + try { + target.removeMetadata(GLOWING_TARGET_METADATA, plugin); + for (Player player : arena.getPlayers()) { + plugin.getGlowingEntities().unsetGlowing(target, player); + } + } catch (Exception ignored) { + } + cancel(); + return; + } + try { + for (Player player : arena.getPlayers()) { + plugin.getGlowingEntities().setGlowing(target, player, toggle ? ChatColor.YELLOW : ChatColor.RED); + } + } catch (Exception ignored) { + } + toggle = !toggle; + tick += 10; + } + }.runTaskTimer(plugin, 0, 10); + } + + //todo apply kills for golem by VD_OWNER_UUID detection @EventHandler public void onDieEntity(EntityDamageByEntityEvent e) { - if(!(e.getDamager() instanceof Wolf && e.getEntity() instanceof Creature)) { + if (!(e.getDamager() instanceof Wolf && e.getEntity() instanceof Creature)) { return; } - if(e.getDamage() >= ((Creature) e.getEntity()).getHealth()) { + if (e.getDamage() >= ((Creature) e.getEntity()).getHealth()) { //trick to get non player killer of zombie - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(arena.getEnemies().contains(e.getEntity())) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (arena.getEnemies().contains(e.getEntity())) { org.bukkit.entity.AnimalTamer owner = ((Wolf) e.getDamager()).getOwner(); - if(owner instanceof Player) { //prevent offline player cast error + if (owner instanceof Player) { //prevent offline player cast error Player player = (Player) owner; - if(plugin.getArenaRegistry().getArena(player) != null) { + if (plugin.getArenaRegistry().getArena(player) != null) { plugin.getUserManager().addStat(player, plugin.getStatsStorage().getStatisticType("KILLS")); plugin.getUserManager().addExperience(player, 2 * arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); } @@ -110,16 +230,16 @@ public void onDieEntity(EntityDamageByEntityEvent e) { public void onItemDrop(ItemSpawnEvent e) { org.bukkit.entity.Item item = e.getEntity(); - if(item.getItemStack().getType() != Material.ROTTEN_FLESH) { + if (item.getItemStack().getType() != Material.ROTTEN_FLESH) { return; } Location itemLoc = item.getLocation(); - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { Location start = arena.getStartLocation(); - if(itemLoc.getWorld() != start.getWorld() || itemLoc.distance(start) > 150) { + if (itemLoc.getWorld() != start.getWorld() || itemLoc.distance(start) > 150) { continue; } @@ -129,42 +249,74 @@ public void onItemDrop(ItemSpawnEvent e) { @EventHandler public void onEntityDamage(EntityDamageEvent event) { - if(event.getEntityType() != EntityType.IRON_GOLEM && event.getEntityType() != EntityType.WOLF) + if (event.getEntityType() != EntityType.IRON_GOLEM && event.getEntityType() != EntityType.WOLF) return; - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - switch(event.getEntityType()) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + switch (event.getEntityType()) { case IRON_GOLEM: - if(!arena.getIronGolems().contains(event.getEntity())) { + if (!arena.getIronGolems().contains(event.getEntity())) { continue; } - IronGolem ironGolem = (IronGolem) event.getEntity(); - - if(ironGolem.getHealth() <= event.getDamage()) { + if (ironGolem.getHealth() <= event.getDamage()) { event.setCancelled(true); event.setDamage(0); + + int totalLevel = 0; + for (EntityUpgrade entityUpgrade : plugin.getEntityUpgradeManager().getRegisteredUpgrades()) { + if (entityUpgrade.getApplicableEntity() == ironGolem.getType() && ironGolem.hasMetadata(entityUpgrade.getMetadataKey())) { + totalLevel++; + } + } + UUID ownerUUID = null; + if (ironGolem.hasMetadata("VD_OWNER_UUID")) { + ownerUUID = UUID.fromString(ironGolem.getMetadata("VD_OWNER_UUID").get(0).asString()); + } + + if (ownerUUID != null) { + Player playerOwner = plugin.getServer().getPlayer(ownerUUID); + + int totalKills = 0; + if (ironGolem.hasMetadata("VD_ENTITY_KILLS")) { + totalKills = ironGolem.getMetadata("VD_ENTITY_KILLS").get(0).asInt(); + } + if (playerOwner != null) + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_DEATH").asKey().integer(totalLevel).value(String.valueOf(totalKills)).player(playerOwner).sendPlayer(); + } + arena.removeIronGolem(ironGolem); } return; case WOLF: - if(!arena.getWolves().contains(event.getEntity())) { + if (!arena.getWolves().contains(event.getEntity())) { continue; } - Wolf wolf = (Wolf) event.getEntity(); - - if(wolf.getHealth() <= event.getDamage()) { + if (wolf.getHealth() <= event.getDamage()) { event.setCancelled(true); event.setDamage(0); - java.util.UUID ownerUUID = (wolf.getOwner() != null) ? wolf.getOwner().getUniqueId() : null; + int totalLevel = 0; + for (EntityUpgrade entityUpgrade : plugin.getEntityUpgradeManager().getRegisteredUpgrades()) { + if (entityUpgrade.getApplicableEntity() == wolf.getType() && wolf.hasMetadata(entityUpgrade.getMetadataKey())) { + totalLevel++; + } + } + UUID ownerUUID = (wolf.getOwner() != null) ? wolf.getOwner().getUniqueId() : null; + if (ownerUUID == null && wolf.hasMetadata("VD_OWNER_UUID")) { + ownerUUID = UUID.fromString(wolf.getMetadata("VD_OWNER_UUID").get(0).asString()); + } - if(ownerUUID != null) { + if (ownerUUID != null) { Player playerOwner = plugin.getServer().getPlayer(ownerUUID); + int totalKills = 0; + if (wolf.hasMetadata("VD_ENTITY_KILLS")) { + totalKills = wolf.getMetadata("VD_ENTITY_KILLS").get(0).asInt(); + } - if(playerOwner != null) - new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_DEATH").asKey().player(playerOwner).sendPlayer(); + if (playerOwner != null) + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_DEATH").asKey().integer(totalLevel).value(String.valueOf(totalKills)).player(playerOwner).sendPlayer(); } arena.removeWolf(wolf); @@ -177,14 +329,14 @@ public void onEntityDamage(EntityDamageEvent event) { } @EventHandler - public void onDieEntity(EntityDeathEvent event) { + public void onVillagerDeath(EntityDeathEvent event) { LivingEntity entity = event.getEntity(); - if(!(entity instanceof Creature)) { + if (!(entity instanceof Creature)) { return; } - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(event.getEntityType() == EntityType.VILLAGER) { - if(!arena.getVillagers().contains(entity)) { + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (event.getEntityType() == EntityType.VILLAGER) { + if (!arena.getVillagers().contains(entity)) { continue; } arena.getStartLocation().getWorld().strikeLightningEffect(entity.getLocation()); @@ -192,37 +344,20 @@ public void onDieEntity(EntityDeathEvent event) { plugin.getRewardsHandler().performReward(null, arena, plugin.getRewardsHandler().getRewardType("VILLAGER_DEATH")); plugin.getHolidayManager().applyHolidayDeathEffects(entity); new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_DIED").asKey().arena(arena).sendArena(); - } else { - if(!arena.getEnemies().contains(entity)) { - continue; - } - arena.removeEnemy((Creature) entity); - arena.changeArenaOptionBy("TOTAL_KILLED_ZOMBIES", 1); - - Player killer = entity.getKiller(); - Arena killerArena = plugin.getArenaRegistry().getArena(killer); - - if(killerArena != null) { - plugin.getUserManager().addStat(killer, plugin.getStatsStorage().getStatisticType("KILLS")); - plugin.getUserManager().addExperience(killer, 2 * arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); - plugin.getRewardsHandler().performReward(killer, plugin.getRewardsHandler().getRewardType("ZOMBIE_KILL")); - plugin.getPowerupRegistry().spawnPowerup(entity.getLocation(), killerArena); - } } - break; } } @EventHandler(priority = EventPriority.HIGH) public void onPlayerDie(PlayerDeathEvent e) { Arena arena = plugin.getArenaRegistry().getArena(e.getEntity()); - if(arena == null) { + if (arena == null) { return; } final Player player = e.getEntity(); - if(player.isDead()) { + if (player.isDead()) { player.setHealth(VersionUtils.getMaxHealth(player)); } plugin.getRewardsHandler().performReward(player, arena, plugin.getRewardsHandler().getRewardType("PLAYER_DEATH")); @@ -230,14 +365,14 @@ public void onPlayerDie(PlayerDeathEvent e) { e.getDrops().clear(); e.setDroppedExp(0); plugin.getHolidayManager().applyHolidayDeathEffects(player); - player.spigot().respawn(); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> player.spigot().respawn(), 1); plugin.getServer().getScheduler().runTask(plugin, () -> { - if(arena.getArenaState() == ArenaState.STARTING) { + if (arena.getArenaState() == ArenaState.STARTING) { VersionUtils.teleport(player, arena.getStartLocation()); return; } - if(arena.getArenaState() == ArenaState.ENDING || arena.getArenaState() == ArenaState.RESTARTING) { + if (arena.getArenaState() == ArenaState.ENDING || arena.getArenaState() == ArenaState.RESTARTING) { player.getInventory().clear(); player.setFlying(false); player.setAllowFlight(false); @@ -273,12 +408,12 @@ private void sendSpectatorActionBar(User user, Arena arena) { new BukkitRunnable() { @Override public void run() { - if(arena.getArenaState() == ArenaState.ENDING || !user.isSpectator()) { + if (arena.getArenaState() == ArenaState.ENDING || !user.isSpectator()) { cancel(); return; } Player player = user.getPlayer(); - if(player == null) { + if (player == null) { cancel(); } else { VersionUtils.sendActionBar(player, new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_RESPAWN_ON_NEXT").asKey().player(player).arena(arena).build()); @@ -291,14 +426,14 @@ public void run() { @EventHandler(priority = EventPriority.HIGHEST) public void onRespawn(PlayerRespawnEvent e) { Arena arena = plugin.getArenaRegistry().getArena(e.getPlayer()); - if(arena == null) { + if (arena == null) { return; } Player player = e.getPlayer(); player.setAllowFlight(true); player.setFlying(true); User user = plugin.getUserManager().getUser(player); - if(!user.isSpectator()) { + if (!user.isSpectator()) { user.setSpectator(true); player.setGameMode(GameMode.SURVIVAL); player.removePotionEffect(PotionEffectType.NIGHT_VISION); @@ -312,7 +447,7 @@ public void onRespawn(PlayerRespawnEvent e) { private void modifyUserOrbs(User user) { int deathValue = plugin.getConfig().getInt("Orbs.Death.Value", 50); int current = user.getStatistic("ORBS"); - switch(getOrbDeathType()) { + switch (getOrbDeathType()) { case KEEP: return; case AMOUNT: @@ -339,15 +474,15 @@ private enum OrbDeathType { @EventHandler public void onPickup(PlugilyEntityPickupItemEvent e) { - if(e.getEntity().getType() != EntityType.PLAYER || e.getItem().getItemStack().getType() != Material.ROTTEN_FLESH) { + if (e.getEntity().getType() != EntityType.PLAYER || e.getItem().getItemStack().getType() != Material.ROTTEN_FLESH) { return; } Player player = (Player) e.getEntity(); Arena arena = plugin.getArenaRegistry().getArena(player); - if(arena == null) { + if (arena == null) { return; } - if(plugin.getUserManager().getUser(player).isSpectator()) { + if (plugin.getUserManager().getUser(player).isSpectator()) { e.setCancelled(true); } arena.removeDroppedFlesh(e.getItem()); diff --git a/src/main/java/plugily/projects/villagedefense/arena/ArenaManager.java b/src/main/java/plugily/projects/villagedefense/arena/ArenaManager.java index afd40fff2..075e86b1a 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/ArenaManager.java +++ b/src/main/java/plugily/projects/villagedefense/arena/ArenaManager.java @@ -1,26 +1,33 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena; import org.bukkit.Bukkit; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Creature; import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Wolf; +import org.bukkit.metadata.FixedMetadataValue; import org.jetbrains.annotations.NotNull; import plugily.projects.minigamesbox.classic.arena.PluginArena; import plugily.projects.minigamesbox.classic.arena.PluginArenaManager; @@ -28,10 +35,24 @@ import plugily.projects.minigamesbox.classic.handlers.language.TitleBuilder; import plugily.projects.minigamesbox.classic.user.User; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.api.event.wave.VillageWaveEndEvent; import plugily.projects.villagedefense.api.event.wave.VillageWaveStartEvent; -import plugily.projects.villagedefense.kits.level.GolemFriendKit; +import plugily.projects.villagedefense.arena.assist.AssistHandler; +import plugily.projects.villagedefense.arena.midwave.MidWaveEvent; +import plugily.projects.villagedefense.arena.midwave.PinataZombieEvent; +import plugily.projects.villagedefense.arena.midwave.RottenOfferEvent; +import plugily.projects.villagedefense.arena.midwave.ShopOfferEvent; +import plugily.projects.villagedefense.arena.record.RecordsManager; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.handlers.upgrade.EntityUpgrade; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; /** * @author Plajer @@ -40,11 +61,20 @@ */ public class ArenaManager extends PluginArenaManager { + public static final int DEFAULT_VILLAGER_HEAL_POWER = 2; + public static final int DEFAULT_PET_HEAL_POWER = 3; + private final Main plugin; + private final List midWaveEvents = new ArrayList<>(); + private final RecordsManager recordsManager; public ArenaManager(Main plugin) { super(plugin); this.plugin = plugin; + this.midWaveEvents.add(new ShopOfferEvent(plugin)); + this.midWaveEvents.add(new RottenOfferEvent(plugin)); + this.midWaveEvents.add(new PinataZombieEvent(plugin)); + this.recordsManager = new RecordsManager(plugin); } @Override @@ -57,10 +87,23 @@ public void additionalSpectatorSettings(Player player, PluginArena arena) { @Override public void leaveAttempt(@NotNull Player player, @NotNull PluginArena arena) { - if(plugin.getUserManager().getUser(player).getKit() instanceof GolemFriendKit) { - ((Arena) arena).getIronGolems().stream().filter(ironGolem -> ironGolem.getCustomName().contains(player.getName())) - .forEach(IronGolem::remove); - } + player.removeMetadata(AssistHandler.ASSIST_CONTAINER_METADATA, plugin); + Arena gameArena = (Arena) arena; + List pets = new ArrayList<>(); + pets.addAll(gameArena.getIronGolems()); + pets.addAll(gameArena.getWolves()); + pets + .stream() + .filter(Objects::nonNull) + .filter(pet -> pet.hasMetadata("VD_OWNER_UUID")) + .filter(pet -> UUID.fromString(pet.getMetadata("VD_OWNER_UUID").get(0).asString()).equals(player.getUniqueId())) + .forEach(pet -> { + if(pet instanceof IronGolem) { + gameArena.removeIronGolem((IronGolem) pet); + } else { + gameArena.removeWolf((Wolf) pet); + } + }); super.leaveAttempt(player, arena); } @@ -76,14 +119,30 @@ public void stopGame(boolean quickStop, @NotNull PluginArena arena) { } user.setStatistic("HIGHEST_WAVE", wave); } - if(plugin.getConfigPreferences().getOption("LIMIT_WAVE_UNLIMITED") && wave >= plugin.getConfig().getInt("Limit.Wave.Game-End", 25)) { + recordsManager.registerAndAnnounceRecord(player, (Arena) arena); + if (wave == 50) { plugin.getUserManager().addStat(user, plugin.getStatsStorage().getStatisticType("WINS")); + XSound.UI_TOAST_CHALLENGE_COMPLETE.play(player, 1, 1.5f); + for (int i = 0; i < 5; i++) { + Bukkit.getScheduler().runTaskLater(plugin, () -> XSound.ENTITY_VILLAGER_YES.play(player), 10 * (i * 2)); + } + XSound.ENTITY_VILLAGER_YES.play(player); } else { plugin.getUserManager().addStat(user, plugin.getStatsStorage().getStatisticType("LOSES")); + XSound.ENTITY_VILLAGER_NO.play(player); } plugin.getUserManager().addExperience(player, wave); } } + List allEntities = new ArrayList<>(); + Arena gameArena = ((Arena) arena); + allEntities.addAll(gameArena.getEnemies()); + allEntities.addAll(gameArena.getIronGolems()); + allEntities.addAll(gameArena.getWolves()); + allEntities.addAll(gameArena.getVillagers()); + for(LivingEntity entity : allEntities) { + entity.setAI(false); + } super.stopGame(quickStop, arena); } @@ -108,7 +167,9 @@ public void endWave(@NotNull Arena arena) { if(!user.isSpectator() && !user.isPermanentSpectator()) { Player player = user.getPlayer(); plugin.getRewardsHandler().performReward(player, arena, plugin.getRewardsHandler().getRewardType("END_WAVE")); + user.getKit().reStock(player); } + XSound.ENTITY_VILLAGER_YES.play(user.getPlayer()); } arena.setTimer(plugin.getConfig().getInt("Time-Manager.Cooldown-Before-Next-Wave", 25)); @@ -118,6 +179,8 @@ public void endWave(@NotNull Arena arena) { Bukkit.getPluginManager().callEvent(new VillageWaveEndEvent(arena, arena.getWave())); refreshAllPlayers(arena); + refreshAllies(arena); + removeAllAssists(arena); if(plugin.getConfigPreferences().getOption("RESPAWN_AFTER_WAVE")) { ArenaUtils.bringDeathPlayersBack(arena); @@ -126,23 +189,129 @@ public void endWave(@NotNull Arena arena) { for(Player player : arena.getPlayersLeft()) { plugin.getUserManager().addExperience(player, 5); } + + doCheckNewShopOffers(arena); + doApplySecretUpgrades(arena); + prepareMidWaveEvent(arena); + doRetreatPets(arena); + } + + private void doCheckNewShopOffers(Arena arena) { + if (!arena.getShopManager().getNewOffersAtWaves().contains(arena.getWave())) { + return; + } + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_NEW_OFFERS_AVAILABLE").asKey().arena(arena).sendArena(); + } + + private void prepareMidWaveEvent(Arena arena) { + for (MidWaveEvent event : midWaveEvents) { + //70% chance to attempt to trigger + if (ThreadLocalRandom.current().nextInt(0, 100) >= 30) { + if (!event.canTrigger(arena)) { + continue; + } + event.initiate(arena); + arena.setMidWaveEvent(event); + return; + } + } + } + + private void doRetreatPets(Arena arena) { + List toMove = arena.getIronGolems(); + //repeated calls so mobs don't lose focus randomly + for (int i = 0; i < 5; i++) { + Bukkit.getScheduler().runTaskLater(plugin, () -> { + for (Mob mob : toMove) { + mob.getPathfinder().moveTo(arena.getStartLocation(), 1.25); + } + }, i * 20); + } + for (Wolf wolf : arena.getWolves()) { + wolf.setMetadata("VD_TELEPORT_OVERRIDE_TEMP", new FixedMetadataValue(plugin, true)); + wolf.teleport(arena.getStartLocation()); + wolf.removeMetadata("VD_TELEPORT_OVERRIDE_TEMP", plugin); + } + } + + private void doApplySecretUpgrades(Arena arena) { + List toUpgrade = new ArrayList<>(); + toUpgrade.addAll(arena.getWolves()); + toUpgrade.addAll(arena.getIronGolems()); + for (LivingEntity livingEntity : toUpgrade) { + if (!livingEntity.hasMetadata("VD_ALIVE_SINCE_WAVE")) { + continue; + } + int wave = livingEntity.getMetadata("VD_ALIVE_SINCE_WAVE").get(0).asInt(); + for (EntityUpgrade upgrade : plugin.getEntityUpgradeManager().getRegisteredUpgrades()) { + if (upgrade.isHidden() && upgrade.getSurviveWaves() >= arena.getWave() - wave) { + if (livingEntity.hasMetadata(upgrade.getMetadataKey())) { + break; + } + Player player = Bukkit.getPlayer(UUID.fromString(livingEntity.getMetadata("VD_OWNER_UUID").get(0).asString())); + plugin.getEntityUpgradeManager().applyUpgradeWithVisuals(livingEntity, player, upgrade); + } + } + } } private void refreshAllPlayers(Arena arena) { int waveStat = arena.getWave() * 10; - String feelRefreshed = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_FEEL_REFRESHED").asKey().build(); - String formatted = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_NEXT_IN").asKey().arena(arena).integer(arena.getTimer()).build(); - + String nextWave = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_NEXT_IN").asKey().arena(arena).integer(arena.getTimer()).build(); for(Player player : arena.getPlayers()) { - player.sendMessage(formatted); - player.sendMessage(feelRefreshed); - player.setHealth(VersionUtils.getMaxHealth(player)); + int healPower = (int) Math.ceil(VersionUtils.getMaxHealth(player) * 0.25); //25% of max health rounded up + player.sendMessage(nextWave); + player.setHealth(Math.min(player.getHealth() + healPower, VersionUtils.getMaxHealth(player))); plugin.getUserManager().getUser(player).adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), waveStat); } } + private void refreshAllies(Arena arena) { + int healPower = DEFAULT_VILLAGER_HEAL_POWER; //1 heart + for(Villager villager : arena.getVillagers()) { + villager.setHealth(Math.min(villager.getHealth() + healPower, VersionUtils.getMaxHealth(villager))); + villager.setCustomName(CreatureUtils.getHealthNameTag(villager)); + } + healPower = DEFAULT_PET_HEAL_POWER; //1.5 hearts + List pets = new ArrayList<>(); + pets.addAll(arena.getWolves()); + pets.addAll(arena.getIronGolems()); + for(LivingEntity pet : pets) { + //double heal for golems + double multiplier = getRefreshBonus(pet); + pet.setHealth(Math.min(pet.getHealth() + (healPower * multiplier), VersionUtils.getMaxHealth(pet))); + } + } + + private double getRefreshBonus(LivingEntity livingEntity) { + double defaultHeal = livingEntity instanceof IronGolem ? 2.0 : 1.0; + String prefix = livingEntity instanceof IronGolem ? "GOLEM_" : "WOLF_"; + for (int i = 3; i > 0; i--) { + EntityUpgrade heal = plugin.getEntityUpgradeManager().getUpgrade(prefix + "HEALTH_AND_REGEN_" + i); + if (livingEntity.hasMetadata(heal.getMetadataKey())) { + defaultHeal += heal.getUpgradeData().getOrDefault("regen", 0.0); + break; + } + } + EntityUpgrade willToSurvive = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_SURVIVOR"); + if (livingEntity.hasMetadata(willToSurvive.getMetadataKey())) { + defaultHeal += livingEntity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue() * 0.1; + } + return defaultHeal; + } + + private void removeAllAssists(Arena arena) { + List allEntities = new ArrayList<>(); + allEntities.addAll(arena.getPlayers()); + allEntities.addAll(arena.getWolves()); + allEntities.addAll(arena.getIronGolems()); + for(LivingEntity livingEntity : allEntities) { + livingEntity.removeMetadata(AssistHandler.ASSIST_CONTAINER_METADATA, plugin); + } + } + /** * Starts wave in game. * Calls VillageWaveStartEvent event @@ -169,7 +338,7 @@ public void startWave(@NotNull Arena arena) { arena.setArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER", multiplier); plugin.getDebugger().debug("[{0}] Detected abnormal wave ({1})! Applying zombie limit and difficulty multiplier to {2} | ZombiesAmount: {3} | MaxZombies: {4}", - arena.getId(), wave, arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER"), zombiesAmount, maxzombies); + arena.getId(), wave, arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER"), zombiesAmount, maxzombies); zombiesAmount = maxzombies; } @@ -191,13 +360,14 @@ public void startWave(@NotNull Arena arena) { for(User user : plugin.getUserManager().getUsers(arena)) { Player player = user.getPlayer(); - if(!user.isSpectator()) { - user.getKit().reStock(player); - } plugin.getRewardsHandler().performReward(player, arena, plugin.getRewardsHandler().getRewardType("START_WAVE")); new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_STARTED").asKey().arena(arena).integer(wave).player(player).sendPlayer(); } + if (arena.getMidWaveEvent() != null) { + arena.getMidWaveEvent().cleanup(arena); + arena.setMidWaveEvent(null); + } plugin.getDebugger().debug("[{0}] Wave start event finished took {1}ms", arena.getId(), System.currentTimeMillis() - start); } diff --git a/src/main/java/plugily/projects/villagedefense/arena/ArenaRegistry.java b/src/main/java/plugily/projects/villagedefense/arena/ArenaRegistry.java index 09b053663..c6849e924 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/ArenaRegistry.java +++ b/src/main/java/plugily/projects/villagedefense/arena/ArenaRegistry.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena; @@ -80,18 +80,15 @@ public boolean additionalValidatorChecks(ConfigurationSection section, PluginAre } } - ConfigurationSection doorSection = section.getConfigurationSection(id + ".doors"); - if(doorSection != null) { - for(String string : doorSection.getKeys(false)) { - ((Arena) arena).getMapRestorerManager().addDoor(LocationSerializer.getLocation(doorSection.getString(string + ".location")), - (byte) doorSection.getInt(string + ".byte")); - } + List doorSection = section.getStringList(id + ".doors"); + for(String location : doorSection) { + ((Arena) arena).getMapRestorerManager().addDoor(LocationSerializer.getLocation(location)); } if(arena.getStartLocation().getWorld().getDifficulty() == Difficulty.PEACEFUL) { plugin.getDebugger().sendConsoleMsg(new MessageBuilder("VALIDATOR_INVALID_ARENA_CONFIGURATION").asKey().value("THERE IS A WRONG " + - "DIFFICULTY -> SET IT TO ANOTHER ONE THAN PEACEFUL - WE SET IT TO EASY").arena(arena).build()); + "DIFFICULTY -> SET IT TO ANOTHER ONE THAN PEACEFUL - WE SET IT TO EASY").arena(arena).build()); arena.getStartLocation().getWorld().setDifficulty(Difficulty.EASY); } return true; @@ -124,4 +121,5 @@ public boolean additionalValidatorChecks(ConfigurationSection section, PluginAre } return arenas; } + } diff --git a/src/main/java/plugily/projects/villagedefense/arena/assist/AssistContainer.java b/src/main/java/plugily/projects/villagedefense/arena/assist/AssistContainer.java new file mode 100644 index 000000000..b461116e5 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/assist/AssistContainer.java @@ -0,0 +1,173 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.assist; + +import org.bukkit.entity.LivingEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.StringJoiner; +import java.util.UUID; + +/** + * Metadata container that includes every player + * that assisted in killing an enemy and their + * kill participation (damage/buffing the killer/other) + *

+ * While assists for enemies are always counted, + * assists for players are only counted if time_millis parameter + * is no more than 10 seconds from actual time. + *

+ * Data is stored in the following way: + * uuid,assist_type,value,time_millis|uuid,assist_type,value,time_millis + * + * @author Plajer + *

+ * Created at 29.08.2023 + */ +public class AssistContainer { + + private final List data; + + public AssistContainer() { + this.data = new ArrayList<>(); + } + + public AssistContainer(List data) { + this.data = data; + } + + public static AssistContainer deserialize(String text) { + if(text.isBlank()) { + return new AssistContainer(new ArrayList<>()); + } + List assistData = new ArrayList<>(); + String[] serialized = text.split("\\|"); + for(String assistSerialized : serialized) { + String[] values = assistSerialized.split(","); + assistData.add(new AssistData(UUID.fromString(values[0]), AssistData.AssistType.valueOf(values[1].toUpperCase()), + Double.parseDouble(values[2]), Long.parseLong(values[3]))); + } + return new AssistContainer(assistData); + } + + public List getData() { + return data; + } + + public void updateAssist(LivingEntity entity, AssistData.AssistType type) { + updateAssist(entity, type, 0); + } + + public void updateAssist(LivingEntity entity, AssistData.AssistType type, double value) { + Optional optional = data.stream().filter(a -> a.getUuid().equals(entity.getUniqueId())).findFirst(); + if(optional.isEmpty()) { + data.add(new AssistData(entity.getUniqueId(), type, value, System.currentTimeMillis())); + return; + } + AssistData assistData = optional.get(); + //damage has the highest assist reward, override if any damage is given + if(assistData.getType() != type && type == AssistData.AssistType.DAMAGE) { + assistData.setType(type); + assistData.setValue(value); + assistData.setTimeMillis(System.currentTimeMillis()); + return; + } + //on damage, increase total value of assist + if(type == AssistData.AssistType.DAMAGE) { + assistData.setValue(assistData.getValue() + value); + } + //update time for any type of assist be it buff or damage + assistData.setTimeMillis(System.currentTimeMillis()); + } + + public String serialize() { + StringJoiner joiner = new StringJoiner("|"); + for(AssistData assistData : data) { + joiner.add(assistData.toString()); + } + return joiner.toString(); + } + + public static class AssistData { + + private final UUID uuid; + private AssistType type; + private double value; + private long timeMillis; + + public AssistData(UUID uuid, AssistType type, double value, long timeMillis) { + this.uuid = uuid; + this.type = type; + this.value = value; + this.timeMillis = timeMillis; + } + + public UUID getUuid() { + return uuid; + } + + public AssistType getType() { + return type; + } + + public void setType(AssistType type) { + this.type = type; + } + + public double getValue() { + return value; + } + + public void setValue(double value) { + this.value = value; + } + + public long getTimeMillis() { + return timeMillis; + } + + public void setTimeMillis(long timeMillis) { + this.timeMillis = timeMillis; + } + + @Override + public String toString() { + return uuid.toString() + "," + type.name() + "," + value + "," + timeMillis; + } + + public enum AssistType { + /** + * Assisting ally did damage to killed enemy + */ + DAMAGE, + /** + * Assisting ally did buff ally that killed the enemy + */ + BUFF, + /** + * Assisting ally did debuff enemy that was killed by ally + */ + DEBUFF + } + + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/assist/AssistHandler.java b/src/main/java/plugily/projects/villagedefense/arena/assist/AssistHandler.java new file mode 100644 index 000000000..41aba3a8b --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/assist/AssistHandler.java @@ -0,0 +1,211 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.assist; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.metadata.FixedMetadataValue; +import plugily.projects.villagedefense.Main; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Class dedicated to handle metadata for players who buff + * or help their allies in any other way. + * This class is a middleman between sharing orbs on enemy death + * both for the killer and all assisting players (including + * allies that buffed the killer) + * + * @author Plajer + *

+ * Created at 29.08.2023 + */ +public class AssistHandler { + + public static final String ASSIST_CONTAINER_METADATA = "VD_ASSIST_CONTAINER"; + private Main plugin; + + public AssistHandler(Main plugin) { + this.plugin = plugin; + } + + public void doRegisterDamageOnEnemy(LivingEntity source, Creature target, double damage) { + AssistContainer container = new AssistContainer(); + if(target.hasMetadata(ASSIST_CONTAINER_METADATA)) { + container = AssistContainer.deserialize(target.getMetadata(ASSIST_CONTAINER_METADATA).get(0).asString()); + } + container.updateAssist(source, AssistContainer.AssistData.AssistType.DAMAGE, damage); + target.setMetadata(ASSIST_CONTAINER_METADATA, new FixedMetadataValue(plugin, container.serialize())); + } + + public void doRegisterDebuffOnEnemy(LivingEntity source, Creature target) { + AssistContainer container = new AssistContainer(); + if(target.hasMetadata(ASSIST_CONTAINER_METADATA)) { + container = AssistContainer.deserialize(target.getMetadata(ASSIST_CONTAINER_METADATA).get(0).asString()); + } + container.updateAssist(source, AssistContainer.AssistData.AssistType.DEBUFF); + target.setMetadata(ASSIST_CONTAINER_METADATA, new FixedMetadataValue(plugin, container.serialize())); + } + + public void doRegisterBuffOnAlly(LivingEntity source, LivingEntity target) { + AssistContainer container = new AssistContainer(); + if(target.hasMetadata(ASSIST_CONTAINER_METADATA)) { + container = AssistContainer.deserialize(target.getMetadata(ASSIST_CONTAINER_METADATA).get(0).asString()); + } + container.updateAssist(source, AssistContainer.AssistData.AssistType.BUFF); + target.setMetadata(ASSIST_CONTAINER_METADATA, new FixedMetadataValue(plugin, container.serialize())); + } + + /** + * Distribute orb from killed enemy to all people that assisted the killer. + * Distribution map is a map of player and their percentage contribution. + *

+ * If killer is a pet, owner will receive 100% of kill participation + * unless the pet was assisted by any other ally. + *

+ * If killer is a player, player will receive 100% of kill participation + * unless they were assisted by any other ally. + *

+ * Moreover, deadEnemy is checked for any debuffs it received as well + * so assist is split between people that applied debuffs as well. + * + * @param killer the entity that killed deadEnemy + * @param deadEnemy enemy that died in the event + * @return map of percentage distribution of orbs given by deadEnemy + */ + public Map doDistributeAssistRewards(LivingEntity killer, Creature deadEnemy) { + Player killerOwner = getRealKiller(killer); + if(killerOwner == null) { + plugin.getDebugger().debug("No owner of " + killer.getType() + " found, cannot distribute orb assists."); + return new HashMap<>(); + } + Map damageDone = new LinkedHashMap<>(); + List otherAssists = new ArrayList<>(); + //enemy was debuffed or attacked by someone, check it + if(deadEnemy.hasMetadata(ASSIST_CONTAINER_METADATA)) { + AssistContainer debuffers = AssistContainer.deserialize(deadEnemy.getMetadata(ASSIST_CONTAINER_METADATA).get(0).asString()); + List assistData = debuffers.getData(); + for(AssistContainer.AssistData data : assistData) { + Player assister = getAssisterByUuid(data.getUuid()); + if(assister == null || assister.equals(killerOwner)) { + continue; + } + //only count indirect (debuffs) or damage to the enemy + switch(data.getType()) { + case DAMAGE: + Entity entity = Bukkit.getEntity(data.getUuid()); + damageDone.put(assister, data.getValue()); + break; + case DEBUFF: + otherAssists.add(assister); + break; + } + } + } + //check if killer (either pet or player) has any assist buffs + if(killer.hasMetadata(ASSIST_CONTAINER_METADATA)) { + AssistContainer assisters = AssistContainer.deserialize(killer.getMetadata(ASSIST_CONTAINER_METADATA).get(0).asString()); + List assistData = assisters.getData(); + for(AssistContainer.AssistData data : assistData) { + Player assister = getAssisterByUuid(data.getUuid()); + if(assister == null || data.getType() != AssistContainer.AssistData.AssistType.BUFF) { + continue; + } + //only count buffs (within 10 seconds) to the killer + if(System.currentTimeMillis() - data.getTimeMillis() <= 10000) { + otherAssists.add(assister); + } + } + } + return doDistributeMap(killerOwner, damageDone, otherAssists); + } + + //aims to get owner of the wolf/golem or player if applicable + private Player getRealKiller(LivingEntity killer) { + Player realKiller = null; + if(killer instanceof Player) { + realKiller = (Player) killer; + } else if(killer instanceof Wolf || killer instanceof IronGolem && killer.hasMetadata("VD_OWNER_UUID")) { + realKiller = Bukkit.getPlayer(UUID.fromString(killer.getMetadata("VD_OWNER_UUID").get(0).asString())); + } + return realKiller; + } + + //aims to get the owner of the assisting wolf/golem or player if applicable + private Player getAssisterByUuid(UUID uuid) { + Entity entity = Bukkit.getEntity(uuid); + if(entity == null) { + return null; + } + if(entity instanceof Player) { + return (Player) entity; + } + if(!entity.hasMetadata("VD_OWNER_UUID")) { + return null; + } + return Bukkit.getPlayer(UUID.fromString(entity.getMetadata("VD_OWNER_UUID").get(0).asString())); + } + + //50% / 50% split between killer and assisters + //and 50% split based on damage contribution (weighted) + //and 50% split based on other assists (split evenly) + private Map doDistributeMap(Player killer, Map damage, List otherAssists) { + double total = 100.0; + Map shares = new HashMap<>(); + double killerShare = 50.0; + if(damage.isEmpty() && otherAssists.isEmpty()) { + killerShare = 100.0; + } + shares.put(killer, killerShare); + double totalDamageShare = 0.0; + for(Map.Entry entry : damage.entrySet()) { + double damageDealt = 1.0; + if(entry.getValue() > 0) { + damageDealt = entry.getValue(); + } + totalDamageShare += damageDealt; + } + double assistSplit = 0.5; + //if either is empty then assist should be shared 50/50 not 50/(25/25) + if(damage.isEmpty() || otherAssists.isEmpty()) { + assistSplit = 1.0; + } + for(Map.Entry entry : damage.entrySet()) { + double damageShare = (entry.getValue() / totalDamageShare) * assistSplit * (total - killerShare); + shares.put(entry.getKey(), damageShare); + } + + double otherAssistsShare = assistSplit * (total - killerShare); + for(Player player : otherAssists) { + shares.put(player, otherAssistsShare / otherAssists.size()); + } + return shares; + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/CreatureTargetManager.java b/src/main/java/plugily/projects/villagedefense/arena/managers/CreatureTargetManager.java index 892bb95d3..a88c65c3b 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/CreatureTargetManager.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/CreatureTargetManager.java @@ -1,20 +1,20 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers; @@ -33,7 +33,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.Random; /** * @author Tigerpanzer_02 @@ -95,7 +94,7 @@ public void unTargetCreature(Creature creature) { } public CustomCreature getCustomCreatureFromCreature(Creature creature) { - List metadataValueList = creature.getMetadata("PlugilyProjects-VillageDefense-Name"); + List metadataValueList = creature.getMetadata(CustomCreature.CREATURE_ID_METADATA); if(metadataValueList.isEmpty()) { plugin.getDebugger().debug("Arena {0} Couldn't find creature meta data", arena.getId()); return null; diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/EnemySpawnManager.java b/src/main/java/plugily/projects/villagedefense/arena/managers/EnemySpawnManager.java index 7442e710c..ff9ef537f 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/EnemySpawnManager.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/EnemySpawnManager.java @@ -1,35 +1,35 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; import org.bukkit.Location; import org.bukkit.entity.Creature; import org.bukkit.entity.Villager; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; import plugily.projects.villagedefense.arena.Arena; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + /** * @author Plajer *

diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/ShopManager.java b/src/main/java/plugily/projects/villagedefense/arena/managers/ShopManager.java index b1e754063..1a2de6093 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/ShopManager.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/ShopManager.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers; @@ -25,20 +25,24 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; import plugily.projects.minigamesbox.classic.user.User; import plugily.projects.minigamesbox.classic.utils.configuration.ConfigUtils; import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; import plugily.projects.minigamesbox.classic.utils.serialization.LocationSerializer; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; import plugily.projects.minigamesbox.inventory.normal.NormalFastInv; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.arena.Arena; -import java.util.function.Consumer; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; @@ -47,48 +51,38 @@ */ public class ShopManager { + public static final String SHOP_OFFER_METADATA = "VD_SHOP_SPECIAL_OFFER"; + + private final String defaultOrbsName; + private final String defaultWaveLockName = "wave_lock"; private final String defaultGolemItemName; private final String defaultWolfItemName; + private final String itemLockedMessage; + private final String specialOfferMessage; + private final Set newOffersAtWaves = new HashSet<>(); private final Main plugin; private final FileConfiguration config; private final Arena arena; - private NormalFastInv gui; - private Consumer openMenuConsumer; + private boolean shopValidated = false; public ShopManager(Arena arena) { plugin = arena.getPlugin(); config = ConfigUtils.getConfig(plugin, "arenas"); this.arena = arena; + defaultOrbsName = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_CURRENCY").asKey().build(); defaultGolemItemName = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_GOLEM_ITEM", false).asKey().build(); defaultWolfItemName = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_WOLF_ITEM", false).asKey().build(); + itemLockedMessage = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_ITEM_LOCKED").asKey().build(); + specialOfferMessage = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_SPECIAL_OFFER").asKey().build(); if(config.isSet("instances." + arena.getId() + ".shop")) { - registerShop(); - } - openMenuConsumer = player -> { - if(plugin.getArenaRegistry().getArena(player) == null) { - return; + validateShop(); + if (shopValidated) { + loadShopChestWaveAnnouncements(); } - if(gui == null) { - new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_NOT_DEFINED").asKey().player(player).sendPlayer(); - return; - } - gui.open(player); - }; - } - - public NormalFastInv getShop() { - return gui; - } - - public void setShop(NormalFastInv gui) { - this.gui = gui; - } - - public void setOpenMenuConsumer(@NotNull Consumer openMenuConsumer) { - this.openMenuConsumer = openMenuConsumer; + } } /** @@ -109,119 +103,224 @@ public String getDefaultWolfItemName() { return defaultWolfItemName; } - public void openShop(Player player) { - if(openMenuConsumer != null) { - openMenuConsumer.accept(player); + public Set getNewOffersAtWaves() { + return newOffersAtWaves; + } + + private void loadShopChestWaveAnnouncements() { + ItemStack[] contents = ((Chest) LocationSerializer.getLocation(config.getString("instances." + arena.getId() + ".shop")) + .getBlock().getState()).getInventory().getContents(); + for (ItemStack itemStack : contents) { + if (itemStack == null || itemStack.getType() == Material.REDSTONE_BLOCK) { + continue; + } + ItemMeta meta = itemStack.getItemMeta(); + //seek for wave limit + if (meta != null && meta.hasLore()) { + for (String line : ComplementAccessor.getComplement().getLore(meta)) { + if (line.contains(defaultWaveLockName)) { + newOffersAtWaves.add(parseNumberSafely(line)); + } + } + } } } - private void registerShop() { - if(!validateShop()) { + public void openShop(Player player, Villager source) { + User user = plugin.getUserManager().getUser(player); + if (user == null || user.getArena() == null) { + return; + } + if (!shopValidated) { + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_NOT_DEFINED").asKey().player(player).sendPlayer(); return; } + boolean hasSpecialOffer = source.hasMetadata(SHOP_OFFER_METADATA); + NormalFastInv gui = doGenerateShop(user, hasSpecialOffer); + gui.open(player); + } + + private NormalFastInv doGenerateShop(User user, boolean hasSpecialOffer) { ItemStack[] contents = ((Chest) LocationSerializer.getLocation(config.getString("instances." + arena.getId() + ".shop")) - .getBlock().getState()).getInventory().getContents(); - gui = new NormalFastInv(plugin.getBukkitHelper().serializeInt(contents.length), new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_GUI").asKey().build()); + .getBlock().getState()).getInventory().getContents(); + NormalFastInv gui = new NormalFastInv(plugin.getBukkitHelper().serializeInt(contents.length), new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_GUI").asKey().build()); + gui.getInventory().setMaxStackSize(plugin.getConfig().getInt("Limit.Wave.Game-End", 127)); gui.addClickHandler(inventoryClickEvent -> inventoryClickEvent.setCancelled(true)); for(int slot = 0; slot < contents.length; slot++) { ItemStack itemStack = contents[slot]; if(itemStack == null || itemStack.getType() == Material.REDSTONE_BLOCK) { continue; } + //we do not want to override our real chest contents + itemStack = itemStack.clone(); + + int orbsRequired = 0; + int waveRequired = 0; - String costString = ""; ItemMeta meta = itemStack.getItemMeta(); - //seek for item price + //seek for price or wave limit if(meta != null && meta.hasLore()) { - for(String s : ComplementAccessor.getComplement().getLore(meta)) { - if(s.contains(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_CURRENCY").asKey().build()) || s.contains("orbs")) { - costString = ChatColor.stripColor(s).replaceAll("&[0-9a-zA-Z]", "").replaceAll("[^0-9]", ""); - break; + for (String line : ComplementAccessor.getComplement().getLore(meta)) { + if (line.contains(defaultOrbsName) || line.contains("orbs")) { + orbsRequired = parseNumberSafely(line); + } else if (line.contains(defaultWaveLockName)) { + waveRequired = parseNumberSafely(line); } } } - - int cost; - try { - cost = Integer.parseInt(costString); - } catch(NumberFormatException e) { - plugin.getDebugger().debug(Level.WARNING, "No price set for shop item in arena {0} skipping item!", arena.getId()); + if (orbsRequired == -1 || waveRequired == -1) { + plugin.getDebugger().debug(Level.WARNING, "Invalid or no price/wave unlock value set for shop item in arena {0} skipping item!", arena.getId()); continue; } + int currentWave = ((Arena) user.getArena()).getWave(); + if (hasSpecialOffer) { + orbsRequired = (int) (orbsRequired - (orbsRequired * 0.1)); + } + final int finalOrbs = orbsRequired; + final int finalWaveLimit = waveRequired; + if (meta != null && meta.hasLore()) { + List newLore = meta.getLore() + .stream() + .map(lore -> { + if (lore.contains(defaultWaveLockName)) { + lore = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_WAVE_LOCK").asKey().integer(finalWaveLimit).build(); + } + if (lore.contains(defaultOrbsName) || lore.contains("orbs")) { + lore = ChatColor.GOLD + "" + finalOrbs + " " + defaultOrbsName; + } + return lore; + }) + .collect(Collectors.toList()); + if (hasSpecialOffer) { + newLore.add(specialOfferMessage); + } + ComplementAccessor.getComplement().setLore(meta, newLore); + if (currentWave < waveRequired) { + itemStack.setType(XMaterial.BARRIER.parseMaterial()); + itemStack.setAmount(finalWaveLimit); + meta.setDisplayName(itemLockedMessage); + } + itemStack.setItemMeta(meta); + } + final ItemStack finalStack = itemStack; gui.setItem(slot, itemStack, event -> { - Player player = (Player) event.getWhoClicked(); - - if(!arena.getPlayers().contains(player)) { + Player player = user.getPlayer(); + int orbs = user.getStatistic("ORBS"); + if (currentWave < finalWaveLimit) { + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_WAVE_STILL_LOCKED").asKey().integer(finalWaveLimit).player(player).sendPlayer(); + XSound.ENTITY_VILLAGER_NO.play(player); return; } - - User user = plugin.getUserManager().getUser(player); - int orbs = user.getStatistic("ORBS"); - - if(cost > orbs) { + if (orbs < finalOrbs) { new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_NOT_ENOUGH_CURRENCY").asKey().player(player).sendPlayer(); + XSound.ENTITY_VILLAGER_NO.play(player); return; } - - if(ItemUtils.isItemStackNamed(itemStack)) { - String name = ComplementAccessor.getComplement().getDisplayName(itemStack.getItemMeta()); + if (ItemUtils.isItemStackNamed(finalStack)) { + String name = ComplementAccessor.getComplement().getDisplayName(finalStack.getItemMeta()); if(name.contains(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_GOLEM_ITEM", false).asKey().build()) - || name.contains(defaultGolemItemName)) { + || name.contains(defaultGolemItemName)) { if(!arena.canSpawnMobForPlayer(player, EntityType.IRON_GOLEM)) { + XSound.ENTITY_VILLAGER_NO.play(player); return; } arena.spawnGolem(arena.getStartLocation(), player); - adjustOrbs(user, cost); + adjustOrbs(user, finalOrbs); return; } if(name.contains(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_WOLF_ITEM", false).asKey().build()) - || name.contains(defaultWolfItemName)) { + || name.contains(defaultWolfItemName)) { if(!arena.canSpawnMobForPlayer(player, EntityType.WOLF)) { + XSound.ENTITY_VILLAGER_NO.play(player); return; } arena.spawnWolf(arena.getStartLocation(), player); - adjustOrbs(user, cost); + adjustOrbs(user, finalOrbs); return; } } - ItemStack stack = itemStack.clone(); + ItemStack stack = finalStack.clone(); ItemMeta itemMeta = stack.getItemMeta(); - if(itemMeta != null) { - if(itemMeta.hasLore()) { - ComplementAccessor.getComplement().setLore(itemMeta, ComplementAccessor.getComplement().getLore(itemMeta).stream().filter(lore -> - !lore.contains(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_CURRENCY").asKey().build())) - .collect(Collectors.toList())); - } - + if (itemMeta != null && itemMeta.hasLore()) { + List updatedLore = ComplementAccessor.getComplement() + .getLore(itemMeta) + .stream() + .filter(lore -> !lore.contains(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_CURRENCY").asKey().build())) + .filter(lore -> !lore.contains(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_WAVE_LOCK").asKey().integer(finalWaveLimit).build())) + .filter(lore -> !lore.contains(specialOfferMessage)) + .collect(Collectors.toList()); + ComplementAccessor.getComplement().setLore(itemMeta, updatedLore); stack.setItemMeta(itemMeta); } - player.getInventory().addItem(stack); - adjustOrbs(user, cost); + applyOrGiveItem(player, stack); + adjustOrbs(user, finalOrbs); }); } + return gui; + } + + private int parseNumberSafely(String text) { + String stripped = ChatColor.stripColor(text).replaceAll("&[0-9a-zA-Z]", "").replaceAll("[^0-9]", ""); + try { + return Integer.parseInt(stripped); + } catch (NumberFormatException e) { + return -1; + } + } + + private void applyOrGiveItem(Player player, ItemStack itemStack) { + Material type = itemStack.getType(); + if (type == Material.LEATHER_HELMET || type == Material.CHAINMAIL_HELMET || type == Material.IRON_HELMET || type == Material.GOLDEN_HELMET + || type == Material.DIAMOND_HELMET || type == Material.NETHERITE_HELMET || type == Material.TURTLE_HELMET) { + player.getInventory().setHelmet(itemStack); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_AUTO_ARMOR_EQUIPPED").asKey().player(player).sendPlayer(); + return; + } + if (type == Material.LEATHER_CHESTPLATE || type == Material.CHAINMAIL_CHESTPLATE || type == Material.IRON_CHESTPLATE || type == Material.GOLDEN_CHESTPLATE + || type == Material.DIAMOND_CHESTPLATE || type == Material.NETHERITE_CHESTPLATE) { + player.getInventory().setChestplate(itemStack); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_AUTO_ARMOR_EQUIPPED").asKey().player(player).sendPlayer(); + return; + } + if (type == Material.LEATHER_LEGGINGS || type == Material.CHAINMAIL_LEGGINGS || type == Material.IRON_LEGGINGS || type == Material.GOLDEN_LEGGINGS + || type == Material.DIAMOND_LEGGINGS || type == Material.NETHERITE_LEGGINGS) { + player.getInventory().setLeggings(itemStack); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_AUTO_ARMOR_EQUIPPED").asKey().player(player).sendPlayer(); + return; + } + if (type == Material.LEATHER_BOOTS || type == Material.CHAINMAIL_BOOTS || type == Material.IRON_BOOTS || type == Material.GOLDEN_BOOTS + || type == Material.DIAMOND_BOOTS || type == Material.NETHERITE_BOOTS) { + player.getInventory().setBoots(itemStack); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_SHOP_AUTO_ARMOR_EQUIPPED").asKey().player(player).sendPlayer(); + return; + } + player.getInventory().addItem(itemStack); } private void adjustOrbs(User user, int cost) { user.adjustStatistic("ORBS", -cost); arena.changeArenaOptionBy("TOTAL_ORBS_SPENT", cost); + XSound.ENTITY_VILLAGER_YES.play(user.getPlayer()); } - private boolean validateShop() { + private void validateShop() { String shop = config.getString("instances." + arena.getId() + ".shop", ""); if(!shop.contains(",")) { plugin.getDebugger().debug(Level.WARNING, "There is no shop for arena {0}! Aborting registering shop!", arena.getId()); - return false; + this.shopValidated = false; + return; } Location location = LocationSerializer.getLocation(shop); if(location.getWorld() == null || !(location.getBlock().getState() instanceof Chest)) { plugin.getDebugger().debug(Level.WARNING, "Shop failed to load, invalid location for location {0}", LocationSerializer.locationToString(location)); - return false; + this.shopValidated = false; + return; } - return true; + this.shopValidated = true; } } diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistry.java b/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistry.java index b4462a273..79f85cc1f 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistry.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistry.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers.enemy.spawner; @@ -23,18 +23,26 @@ import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; import plugily.projects.minigamesbox.classic.utils.configuration.ConfigUtils; -import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.arena.managers.spawner.EnemySpawner; import plugily.projects.villagedefense.creatures.v1_9_UP.CustomCreature; import plugily.projects.villagedefense.creatures.v1_9_UP.CustomCreatureEvents; import plugily.projects.villagedefense.creatures.v1_9_UP.CustomRideableCreature; import plugily.projects.villagedefense.creatures.v1_9_UP.Equipment; import plugily.projects.villagedefense.creatures.v1_9_UP.Rate; +import plugily.projects.villagedefense.creatures.v1_9_UP.RideableCreatureEvents; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumMap; +import java.util.HashSet; import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; /** @@ -42,18 +50,20 @@ *

* Created at 01.05.2022 */ -public class EnemySpawnerRegistry extends EnemySpawnerRegistryLegacy { +public class EnemySpawnerRegistry { + private static final String CREATURES_MISSING_SECTION = "Creatures section {0} is missing! Was it manually removed?"; + private final Set enemySpawnerSet = new TreeSet<>(Collections.reverseOrder()); + private final Set rideableCreatures = new HashSet<>(); + private final Main plugin; public EnemySpawnerRegistry(Main plugin) { - super(plugin); + this.plugin = plugin; + registerCreatures(); + registerRideableCreatures(); } - @Override public void registerRideableCreatures() { - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_8_R3)) { - return; - } FileConfiguration config = ConfigUtils.getConfig(plugin, "creatures"); ConfigurationSection village = config.getConfigurationSection("Creatures.Village"); if(village == null) { @@ -87,9 +97,9 @@ public void registerRideableCreatures() { } } - @Override public void registerCreatures() { new CustomCreatureEvents(plugin); + new RideableCreatureEvents(plugin); FileConfiguration config = ConfigUtils.getConfig(plugin, "creatures"); ConfigurationSection content = config.getConfigurationSection("Creatures.Content"); @@ -110,10 +120,12 @@ public void registerCreatures() { boolean explodeTarget = content.getBoolean(creature + ".explosive_hit", false); + String name = content.getString(creature + ".name", "Zombie"); String key = creature.toUpperCase(); EntityType entityType = EntityType.valueOf(content.getString(creature + ".entity_type", "ZOMBIE").toUpperCase()); + boolean doorBulldozing = content.getBoolean(creature + ".door_bulldozing", false); boolean baby = content.getBoolean(creature + ".baby", false); boolean breed = content.getBoolean(creature + ".breed", false); int age = content.getInt(creature + ".age", 0); @@ -176,9 +188,71 @@ public void registerCreatures() { dropItem = XMaterial.matchXMaterial(item).orElse(XMaterial.BEDROCK).parseItem(); } plugin.getDebugger().debug("Registered CustomCreature named {0}", key); - enemySpawnerSet.add(new CustomCreature(plugin, waveMin, waveMax, priorityTarget, explodeTarget, key, entityType, baby, breed, age, ageLook, expDrop, holidayEffects, rates, attributes, equipments, dropItem)); + enemySpawnerSet.add(new CustomCreature(plugin, name, waveMin, waveMax, priorityTarget, explodeTarget, key, entityType, doorBulldozing, baby, breed, age, ageLook, expDrop, holidayEffects, rates, attributes, equipments, dropItem)); + } + } + + /** + * Spawn the enemies at the arena + * + * @param random the random instance + * @param arena the arena + */ + public void spawnEnemies(Random random, Arena arena) { + int spawn = arena.getWave(); + int zombiesLimit = plugin.getConfig().getInt("Limit.Spawn.Creatures", 75); + if(zombiesLimit < spawn) { + spawn = (int) Math.ceil(zombiesLimit / 2.0); + } + String zombieSpawnCounterOption = "ZOMBIE_SPAWN_COUNTER"; + arena.changeArenaOptionBy(zombieSpawnCounterOption, 1); + if(arena.getArenaOption(zombieSpawnCounterOption) == 20) { + arena.setArenaOption(zombieSpawnCounterOption, 0); + } + + List enemySpawners = new ArrayList<>(enemySpawnerSet); + Collections.shuffle(enemySpawners); + for(EnemySpawner enemySpawner : enemySpawners) { + plugin.getDebugger().debug("Trying enemy spawn for " + enemySpawner.getName()); + enemySpawner.spawn(random, arena, spawn); } + } + + /** + * Get the set of enemy spawners + * + * @return the set of enemy spawners + */ + public Set getEnemySpawnerSet() { + return enemySpawnerSet; + } + + public Set getRideableCreatures() { + return rideableCreatures; + } + + /** + * Get the rideable creature by its type + * + * @param type the tyoe + * @return the rideable creature + */ + public Optional getRideableCreatureByName(CustomRideableCreature.RideableType type) { + return rideableCreatures.stream() + .filter(creature -> creature.getRideableType().equals(type)) + .findFirst(); + } + /** + * Get the enemy spawner by its name + * + * @param name the name + * @return the enemy spawner + */ + public Optional getSpawnerByName(String name) { + return enemySpawnerSet.stream() + .filter(enemySpawner -> enemySpawner.getName().equals(name)) + .findFirst(); } diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistryLegacy.java b/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistryLegacy.java deleted file mode 100644 index 5da57293d..000000000 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/enemy/spawner/EnemySpawnerRegistryLegacy.java +++ /dev/null @@ -1,145 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.arena.managers.enemy.spawner; - -import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; -import plugily.projects.villagedefense.Main; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.EnemySpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.BabyZombieSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.FastZombieSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.GolemBusterSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.HalfInvisibleZombieSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.HardZombieSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.KnockbackResistantZombieSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.PlayerBusterSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.SoftHardZombieSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.VillagerBusterSpawner; -import plugily.projects.villagedefense.creatures.v1_8_R3.spawner.VillagerSlayerSpawner; -import plugily.projects.villagedefense.creatures.v1_9_UP.CustomRideableCreature; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.TreeSet; - -/** - * The registry for all {@link EnemySpawner} - */ -public class EnemySpawnerRegistryLegacy { - final Set enemySpawnerSet = new TreeSet<>(Collections.reverseOrder()); - final Set rideableCreatures = new HashSet<>(); - final Main plugin; - - public EnemySpawnerRegistryLegacy(Main plugin) { - this.plugin = plugin; - registerCreatures(); - registerRideableCreatures(); - } - - public void registerRideableCreatures() { - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_8_R3)) { - return; - } - } - - public void registerCreatures() { - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_8_R3)) { - enemySpawnerSet.add(new BabyZombieSpawner()); - enemySpawnerSet.add(new FastZombieSpawner()); - enemySpawnerSet.add(new GolemBusterSpawner()); - enemySpawnerSet.add(new HalfInvisibleZombieSpawner()); - enemySpawnerSet.add(new HardZombieSpawner()); - enemySpawnerSet.add(new KnockbackResistantZombieSpawner()); - enemySpawnerSet.add(new PlayerBusterSpawner()); - enemySpawnerSet.add(new SoftHardZombieSpawner()); - enemySpawnerSet.add(new VillagerBusterSpawner()); - enemySpawnerSet.add(new VillagerSlayerSpawner()); - return; - } - } - - /** - * Spawn the enemies at the arena - * - * @param random the random instance - * @param arena the arena - */ - public void spawnEnemies(Random random, Arena arena) { - int spawn = arena.getWave(); - int zombiesLimit = plugin.getConfig().getInt("Limit.Spawn.Creatures", 75); - if(zombiesLimit < spawn) { - spawn = (int) Math.ceil(zombiesLimit / 2.0); - } - String zombieSpawnCounterOption = "ZOMBIE_SPAWN_COUNTER"; - arena.changeArenaOptionBy(zombieSpawnCounterOption, 1); - if(arena.getArenaOption(zombieSpawnCounterOption) == 20) { - arena.setArenaOption(zombieSpawnCounterOption, 0); - } - - List enemySpawners = new ArrayList<>(enemySpawnerSet); - Collections.shuffle(enemySpawners); - for(EnemySpawner enemySpawner : enemySpawners) { - plugin.getDebugger().debug("Trying enemy spawn for " + enemySpawner.getName()); - enemySpawner.spawn(random, arena, spawn); - } - } - - /** - * Get the set of enemy spawners - * - * @return the set of enemy spawners - */ - public Set getEnemySpawnerSet() { - return enemySpawnerSet; - } - - public Set getRideableCreatures() { - return rideableCreatures; - } - - /** - * Get the rideable creature by its type - * - * @param type the tyoe - * @return the rideable creature - */ - public Optional getRideableCreatureByName(CustomRideableCreature.RideableType type) { - return rideableCreatures.stream() - .filter(creature -> creature.getRideableType().equals(type)) - .findFirst(); - } - - /** - * Get the enemy spawner by its name - * - * @param name the name - * @return the enemy spawner - */ - public Optional getSpawnerByName(String name) { - return enemySpawnerSet.stream() - .filter(enemySpawner -> enemySpawner.getName().equals(name)) - .findFirst(); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManager.java b/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManager.java index 889733911..a9a2c1fb3 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManager.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManager.java @@ -1,26 +1,28 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers.maprestorer; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.TreeSpecies; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -28,33 +30,34 @@ import plugily.projects.minigamesbox.classic.arena.managers.PluginMapRestorerManager; import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.DoorBreakListener; import plugily.projects.villagedefense.utils.Utils; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; /** - * @author Plajer + * @author Tigerpanzer_02 *

- * Created at 14.02.2019 + * Created at 13.01.2021 */ @SuppressWarnings("deprecation") public class MapRestorerManager extends PluginMapRestorerManager { - protected final Map doorBlocks = new LinkedHashMap<>(); - public final Arena arena; + private final List doorBlocks = new ArrayList<>(); + private final Arena arena; public MapRestorerManager(Arena arena) { super(arena); this.arena = arena; } - public final void addDoor(Location location, byte data) { - doorBlocks.put(location, data); + public final void addDoor(Location location) { + doorBlocks.add(location); } - public final Map getGameDoorLocations() { + public final List getGameDoorLocations() { return doorBlocks; } @@ -101,21 +104,22 @@ public final void clearWolvesFromArena() { public void restoreDoors() { int i = 0; - for(Map.Entry entry : doorBlocks.entrySet()) { - Block block = entry.getKey().getBlock(); - Byte doorData = entry.getValue(); + for(Location location : doorBlocks) { + Block block = location.getBlock(); try { if(block.getType() != XMaterial.AIR.parseMaterial()) { i++; continue; } - if(doorData == (byte) 8) { - restoreTopHalfDoorPart(block); - i++; - continue; + Block relative = block.getRelative(BlockFace.DOWN).getLocation().getBlock(); + boolean isAirBelow = relative.getType().equals(XMaterial.AIR.parseMaterial()); + boolean relativeTopHalf = false; + if(!isAirBelow) { + relative = block.getRelative(BlockFace.UP).getLocation().getBlock(); + relativeTopHalf = true; } - restoreBottomHalfDoorPart(block, doorData); - i++; + restoreDoorPart(block, !relativeTopHalf); + restoreDoorPart(relative, relativeTopHalf); } catch(Exception ex) { arena.getPlugin().getDebugger().debug(Level.WARNING, "Door has failed to load for arena {0} message {1} type {2} skipping!", arena.getId(), ex.getMessage(), ex.getCause()); } @@ -125,32 +129,36 @@ public void restoreDoors() { } } - public void restoreTopHalfDoorPart(Block block) { - block.setType(Utils.getCachedDoor(block)); - BlockState doorBlockState = block.getState(); - Door doorBlockData = new Door(TreeSpecies.GENERIC, arena.getPlugin().getBukkitHelper().getFacingByByte((byte) 8)); - - doorBlockData.setTopHalf(true); - doorBlockData.setFacingDirection(doorBlockData.getFacing()); - - doorBlockState.setType(doorBlockData.getItemType()); - doorBlockState.setData(doorBlockData); - - doorBlockState.update(true); - } + public void restoreDoorPart(Block block, boolean topHalf) { + byte doorByte; + if(topHalf) { + doorByte = 8; + } else { + doorByte = 1; + } - public void restoreBottomHalfDoorPart(Block block, byte doorData) { block.setType(Utils.getCachedDoor(block)); - BlockState doorBlockState = block.getState(); - Door doorBlockData = new Door(TreeSpecies.GENERIC, arena.getPlugin().getBukkitHelper().getFacingByByte(doorData)); - - doorBlockData.setTopHalf(false); - doorBlockData.setFacingDirection(doorBlockData.getFacing()); - - doorBlockState.setType(doorBlockData.getItemType()); - doorBlockState.setData(doorBlockData); - - doorBlockState.update(true); + Door doorData = null; + try { + doorData = new Door(TreeSpecies.GENERIC, arena.getPlugin().getBukkitHelper().getFacingByByte(doorByte)); + } catch(NoSuchMethodError e) { + try { + doorData = Door.class.getDeclaredConstructor(Material.class, byte.class).newInstance(XMaterial.OAK_DOOR.parseMaterial(), doorByte); + } catch(Exception ex) { + ex.printStackTrace(); + } + } + if(doorData == null) { + return; + } + BlockState state = block.getState(); + doorData.setTopHalf(topHalf); + doorData.setFacingDirection(doorData.getFacing()); + state.setType(doorData.getItemType()); + state.setData(doorData); + state.update(true); + + block.removeMetadata(DoorBreakListener.CREATURE_DOOR_BULLDOZER_METADATA, arena.getPlugin()); } } diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManagerLegacy.java b/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManagerLegacy.java deleted file mode 100644 index f5ab3be34..000000000 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/maprestorer/MapRestorerManagerLegacy.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.arena.managers.maprestorer; - -import java.util.Map; -import java.util.logging.Level; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.TreeSpecies; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.material.Door; -import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.utils.Utils; - -/** - * @author Tigerpanzer_02 - *

- * Created at 13.01.2021 - */ -@SuppressWarnings("deprecation") -public class MapRestorerManagerLegacy extends MapRestorerManager { - - public MapRestorerManagerLegacy(Arena arena) { - super(arena); - } - - @Override - public void restoreDoors() { - int i = 0; - for(Map.Entry entry : doorBlocks.entrySet()) { - Block block = entry.getKey().getBlock(); - Byte doorData = entry.getValue(); - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_11_R1) && block.getType() != org.bukkit.Material.AIR) { - Material mat = Utils.getCachedDoor(block); - try { - int id = (int) mat.getClass().getDeclaredMethod("getId").invoke(mat); - block.getClass().getDeclaredMethod("setTypeIdAndData", int.class, byte.class, boolean.class) - .invoke(block, id, doorData, false); - } catch(Exception e) { - e.printStackTrace(); - } - i++; - } else { - try { - if(block.getType() != XMaterial.AIR.parseMaterial()) { - i++; - continue; - } - if(doorData == (byte) 8) { - restoreTopHalfDoorPart(block); - i++; - continue; - } - restoreBottomHalfDoorPart(block, doorData); - i++; - } catch(Exception ex) { - arena.getPlugin().getDebugger().debug(Level.WARNING, "Door has failed to load for arena {0} message {1} type {2} skipping!", arena.getId(), ex.getMessage(), ex.getCause()); - } - } - } - if(i != doorBlocks.size()) { - arena.getPlugin().getDebugger().debug(Level.WARNING, "Failed to load doors for {0}! Expected {1} got {2}", arena.getId(), doorBlocks.size(), i); - } - } - - @Override - public void restoreTopHalfDoorPart(Block block) { - block.setType(Utils.getCachedDoor(block)); - - Door doorBlockData = null; - try { - doorBlockData = new Door(TreeSpecies.GENERIC, arena.getPlugin().getBukkitHelper().getFacingByByte((byte) 8)); - } catch (NoSuchMethodError e) { - try { - doorBlockData = Door.class.getDeclaredConstructor(Material.class, byte.class) - .newInstance(XMaterial.OAK_DOOR, arena.getPlugin().getBukkitHelper().getFacingByByte((byte) 8)); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - if (doorBlockData == null) - return; - - BlockState doorBlockState = block.getState(); - - doorBlockData.setTopHalf(true); - doorBlockData.setFacingDirection(doorBlockData.getFacing()); - doorBlockState.setType(doorBlockData.getItemType()); - doorBlockState.setData(doorBlockData); - doorBlockState.update(true); - } - - @Override - public void restoreBottomHalfDoorPart(Block block, byte doorData) { - block.setType(Utils.getCachedDoor(block)); - - Door doorBlockData = null; - try { - doorBlockData = new Door(TreeSpecies.GENERIC, arena.getPlugin().getBukkitHelper().getFacingByByte(doorData)); - } catch (NoSuchMethodError e) { - try { - doorBlockData = Door.class.getDeclaredConstructor(Material.class, byte.class) - .newInstance(XMaterial.OAK_DOOR.parseMaterial(), arena.getPlugin().getBukkitHelper().getFacingByByte(doorData)); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - if (doorBlockData == null) - return; - - BlockState doorBlockState = block.getState(); - - doorBlockData.setTopHalf(false); - doorBlockData.setFacingDirection(doorBlockData.getFacing()); - doorBlockState.setType(doorBlockData.getItemType()); - doorBlockState.setData(doorBlockData); - doorBlockState.update(true); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/EnemySpawner.java b/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/EnemySpawner.java index 18a2c9abd..c80551f56 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/EnemySpawner.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/EnemySpawner.java @@ -1,29 +1,29 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers.spawner; -import java.util.Random; - import org.bukkit.inventory.ItemStack; import plugily.projects.villagedefense.arena.Arena; +import java.util.Random; + /** * The interface for enemy spawner */ @@ -53,8 +53,8 @@ default int getPriority() { /** * Get the defined itemstack for drop reasons - * does NOT work on 1.8.8 or lower - * @return ItemStack that gets dropped on enemey death + * + * @return ItemStack that gets dropped on enemy death */ ItemStack getDropItem(); diff --git a/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/SimpleEnemySpawner.java b/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/SimpleEnemySpawner.java index 34e60807d..604ea9138 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/SimpleEnemySpawner.java +++ b/src/main/java/plugily/projects/villagedefense/arena/managers/spawner/SimpleEnemySpawner.java @@ -1,20 +1,20 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.managers.spawner; @@ -134,6 +134,9 @@ default void spawn(Location location, Arena arena) { if(creature == null) { return; } + //2 seconds of invulnerability to avoid suffocation problem + creature.setMaximumNoDamageTicks(45); + creature.setNoDamageTicks(40); if(canApplyAttributes()) { CreatureUtils.applyAttributes(creature, arena); } diff --git a/src/main/java/plugily/projects/villagedefense/arena/midwave/MidWaveEvent.java b/src/main/java/plugily/projects/villagedefense/arena/midwave/MidWaveEvent.java new file mode 100644 index 000000000..7c9d6ba44 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/midwave/MidWaveEvent.java @@ -0,0 +1,31 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.midwave; + +import plugily.projects.villagedefense.arena.Arena; + +public interface MidWaveEvent { + + boolean canTrigger(Arena arena); + + void initiate(Arena arena); + + void cleanup(Arena arena); + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/midwave/PinataZombieEvent.java b/src/main/java/plugily/projects/villagedefense/arena/midwave/PinataZombieEvent.java new file mode 100644 index 000000000..6da7771d0 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/midwave/PinataZombieEvent.java @@ -0,0 +1,211 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.midwave; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.ZombieVillager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.utils.hologram.ArmorStandHologram; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; + +import java.util.concurrent.ThreadLocalRandom; + +public class PinataZombieEvent implements MidWaveEvent, Listener { + + public static final String PINATA_METADATA = "VD_PINATA_EVENT"; + private final Main plugin; + + public PinataZombieEvent(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @Override + public boolean canTrigger(Arena arena) { + return arena.getWave() % 11 == 0; + } + + @Override + public void initiate(Arena arena) { + LivingEntity target = (LivingEntity) arena.getStartLocation().getWorld().spawnEntity(arena.getStartLocation(), EntityType.ZOMBIE_VILLAGER); + target.setGlowing(true); + target.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.1); + target.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(100.0); + ((Ageable) target).setAdult(); + target.setMetadata(PINATA_METADATA, new FixedMetadataValue(plugin, true)); + + ArmorStandHologram hologram = new ArmorStandHologram(target.getLocation().add(0, 0.25, 0), + ChatColor.translateAlternateColorCodes('&', "&e&lPUNCH ME")); + new BukkitRunnable() { + boolean toggle = false; + int ticks = 0; + int color = 0; + + @Override + public void run() { + if (!target.hasMetadata(PINATA_METADATA) || target.isDead()) { + hologram.delete(); + target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().clone().add(0, 0.5, 0), 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_INFECT, 1, 0.5f); + for (int i = 0; i < 8; i++) { + dropNaturalItem(hologram.getLocation(), XMaterial.ROTTEN_FLESH.parseItem()); + } + target.remove(); + cancel(); + return; + } + ArmorStand stand = hologram.getArmorStands().get(0); + stand.teleport(target.getLocation().add(0, 0.25, 0)); + if (ticks % 5 == 0) { + for (Player player : arena.getPlayers()) { + try { + plugin.getGlowingEntities().setGlowing(target, player, getNextColor(color)); + } catch (Exception ignored) { + } + color = (color + 1) % 7; + } + } + if (ticks % 10 == 0) { + String message; + if (toggle) { + message = ChatColor.translateAlternateColorCodes('&', "&c&lPUNCH ME"); + } else { + message = ChatColor.translateAlternateColorCodes('&', "&e&lPUNCH ME"); + } + toggle = !toggle; + stand.setCustomName(message); + } + ticks++; + } + }.runTaskTimer(plugin, 0, 1); + arena.getSpecialEntities().add(target); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_PINATA_EVENT") + .asKey() + .arena(arena) + .sendArena(); + for (Player player : arena.getPlayers()) { + player.playSound(player, Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 0.5f, 2f); + } + } + + @Override + public void cleanup(Arena arena) { + for (LivingEntity livingEntity : arena.getSpecialEntities()) { + if (livingEntity.hasMetadata(PINATA_METADATA)) { + livingEntity.removeMetadata(PINATA_METADATA, plugin); + } + } + } + + @EventHandler + public void onPinataFocus(EntityTargetLivingEntityEvent event) { + if (!(event.getTarget() instanceof ZombieVillager)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getSpecialEntities().contains(event.getTarget())) { + continue; + } + if (!event.getTarget().hasMetadata(PINATA_METADATA)) { + continue; + } + event.setCancelled(true); + } + } + + @EventHandler + public void onPinataDamage(EntityDamageByEntityEvent event) { + //cancel all pinata damages + if (event.getDamager().hasMetadata(PINATA_METADATA)) { + event.setCancelled(true); + } + //drop rewards on pinata punch + if (event.getDamager() instanceof Player player && event.getEntity().hasMetadata(PINATA_METADATA)) { + if (!plugin.getArenaRegistry().isInArena(player)) { + return; + } + Vector velocity = event.getEntity().getLocation().getDirection().multiply(-1).normalize().multiply(2.0); + event.getEntity().setVelocity(velocity); + //60% chance of drop + if (ThreadLocalRandom.current().nextInt(0, 100) >= 40) { + doCustomDrop(player, event.getDamager().getLocation()); + } + event.setDamage(1.0); + } + } + + private void dropNaturalItem(Location location, ItemStack itemStack) { + Item item = location.getWorld().dropItemNaturally(location.clone().add(0, 0.5, 0), itemStack); + item.setInvulnerable(true); + item.setPickupDelay(Integer.MAX_VALUE); + item.setGravity(true); + item.setCustomNameVisible(false); + Bukkit.getScheduler().runTaskLater(plugin, () -> item.remove(), 15); + } + + private ChatColor getNextColor(int color) { + return switch (color) { + case 0 -> ChatColor.WHITE; + case 1 -> ChatColor.RED; + case 2 -> ChatColor.GOLD; + case 3 -> ChatColor.DARK_RED; + case 4 -> ChatColor.BLUE; + case 5 -> ChatColor.GREEN; + case 6 -> ChatColor.DARK_PURPLE; + default -> ChatColor.BLACK; + }; + } + + private void doCustomDrop(Player player, Location location) { + if (ThreadLocalRandom.current().nextBoolean()) { + int rand = ThreadLocalRandom.current().nextInt(4, 12); + plugin.getUserManager().getUser(player).adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), rand); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a+" + rand + " &7orbs")); + } else { + int amount = ThreadLocalRandom.current().nextInt(1, 3); + for (int i = 0; i < amount; i++) { + dropNaturalItem(location, XMaterial.ROTTEN_FLESH.parseItem()); + } + player.getInventory().addItem(new ItemStack(Material.ROTTEN_FLESH, amount)); + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/midwave/RottenOfferEvent.java b/src/main/java/plugily/projects/villagedefense/arena/midwave/RottenOfferEvent.java new file mode 100644 index 000000000..000ec86de --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/midwave/RottenOfferEvent.java @@ -0,0 +1,154 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.midwave; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.utils.hologram.ArmorStandHologram; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.creatures.v1_9_UP.CustomCreature; + +import java.util.Map; + +public class RottenOfferEvent implements MidWaveEvent, Listener { + + public static final String ROTTEN_SALE_METADATA = "VD_TRADER_ROTTEN_SALE"; + private final Main plugin; + + public RottenOfferEvent(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @Override + public boolean canTrigger(Arena arena) { + return arena.getWave() % 7 == 0; + } + + @Override + public void initiate(Arena arena) { + LivingEntity target = (LivingEntity) arena.getStartLocation().getWorld().spawnEntity(arena.getStartLocation(), EntityType.WANDERING_TRADER); + String name = CreatureUtils.getRandomVillagerName(); + target.setCustomName(name); + target.setCustomNameVisible(true); + target.setMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA, new FixedMetadataValue(plugin, name)); + target.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(1.0); + target.setGlowing(true); + + String offerMessage = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_ROTTEN_OFFER").asKey().build(); + ArmorStandHologram hologram = new ArmorStandHologram(target.getLocation().add(0, 0.25, 0), offerMessage); + new BukkitRunnable() { + @Override + public void run() { + if (!target.hasMetadata(ROTTEN_SALE_METADATA)) { + hologram.delete(); + target.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, target.getLocation().clone().add(0, 0.5, 0), 1); + target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1, .5f); + target.remove(); + cancel(); + return; + } + ArmorStand stand = hologram.getArmorStands().get(0); + stand.teleport(target.getLocation().add(0, 0.25, 0)); + } + }.runTaskTimer(plugin, 0, 1); + target.setMetadata(ROTTEN_SALE_METADATA, new FixedMetadataValue(plugin, true)); + arena.addSpecialEntity(target); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_ROTTEN_SALE") + .asKey() + .value(ChatColor.translateAlternateColorCodes('&', "&c&lROTTEN FLESH")) + .arena(arena) + .sendArena(); + for (Player player : arena.getPlayers()) { + player.playSound(player, Sound.ENTITY_WANDERING_TRADER_TRADE, 1, 1.15f); + } + } + + @Override + public void cleanup(Arena arena) { + for (LivingEntity livingEntity : arena.getSpecialEntities()) { + if (livingEntity.hasMetadata(ROTTEN_SALE_METADATA)) { + livingEntity.removeMetadata(ROTTEN_SALE_METADATA, plugin); + } + } + } + + @EventHandler + public void onTraderDamage(EntityDamageByEntityEvent event) { + if (!event.getEntity().hasMetadata(ROTTEN_SALE_METADATA)) { + return; + } + //cancel no matter what + event.setCancelled(true); + } + + @EventHandler + public void onInteract(PlayerInteractEntityEvent event) { + if (!event.getRightClicked().hasMetadata(ROTTEN_SALE_METADATA)) { + return; + } + Player player = event.getPlayer(); + if (!plugin.getArenaRegistry().isInArena(player)) { + return; + } + event.setCancelled(true); + if (!player.getInventory().contains(Material.ROTTEN_FLESH)) { + player.playSound(player, Sound.ENTITY_WANDERING_TRADER_NO, 1, 1); + return; + } + int count = 0; + for (Map.Entry entry : player.getInventory().all(Material.ROTTEN_FLESH).entrySet()) { + count += entry.getValue().getAmount(); + } + player.getInventory().remove(Material.ROTTEN_FLESH); + Arena arena = plugin.getArenaRegistry().getArena(player); + arena.changeArenaOptionBy("ROTTEN_FLESH_AMOUNT", count); + int orbs = (int) (count * 1.45); + plugin.getUserManager().getUser(player).adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), orbs); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a+" + orbs + " &7orbs")); + player.playSound(player, Sound.ENTITY_WANDERING_TRADER_TRADE, 1, 1); + if (!arena.checkLevelUpRottenFlesh() || arena.getArenaOption("ROTTEN_FLESH_LEVEL") >= 30) { + return; + } + for (Player arenaPlayer : arena.getPlayers()) { + arenaPlayer.setHealth(VersionUtils.getMaxHealth(player)); + VersionUtils.setMaxHealth(player, VersionUtils.getMaxHealth(player) + 2.0); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_ROTTEN_FLESH_LEVEL_UP").asKey().player(arenaPlayer).sendPlayer(); + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/midwave/ShopOfferEvent.java b/src/main/java/plugily/projects/villagedefense/arena/midwave/ShopOfferEvent.java new file mode 100644 index 000000000..4964aabd8 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/midwave/ShopOfferEvent.java @@ -0,0 +1,94 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.midwave; + +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.utils.hologram.ArmorStandHologram; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.arena.managers.ShopManager; +import plugily.projects.villagedefense.creatures.v1_9_UP.CustomCreature; + +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +public class ShopOfferEvent implements MidWaveEvent { + + private final Main plugin; + + public ShopOfferEvent(Main plugin) { + this.plugin = plugin; + } + + @Override + public boolean canTrigger(Arena arena) { + return arena.getWave() % 5 == 0; + } + + @Override + public void initiate(Arena arena) { + List list = arena.getVillagers() + .stream() + .filter(v -> !v.isDead()) + .collect(Collectors.toList()); + Villager target = list.get(ThreadLocalRandom.current().nextInt(list.size())); + target.setGlowing(true); + + String offerMessage = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_SPECIAL_OFFER").asKey().build(); + ArmorStandHologram hologram = new ArmorStandHologram(target.getLocation().add(0, 0.25, 0), offerMessage); + new BukkitRunnable() { + @Override + public void run() { + if (!target.hasMetadata(ShopManager.SHOP_OFFER_METADATA)) { + hologram.delete(); + cancel(); + return; + } + ArmorStand stand = hologram.getArmorStands().get(0); + stand.teleport(target.getLocation().add(0, 0.25, 0)); + } + }.runTaskTimer(plugin, 0, 1); + target.setMetadata(ShopManager.SHOP_OFFER_METADATA, new FixedMetadataValue(plugin, true)); + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_OFFERING_SALE") + .asKey() + .value(target.getMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA).get(0).asString()) + .arena(arena) + .sendArena(); + for (Player player : arena.getPlayers()) { + player.playSound(player, Sound.ENTITY_VILLAGER_TRADE, 1, 1.15f); + } + } + + @Override + public void cleanup(Arena arena) { + for (Villager villager : arena.getVillagers()) { + if (villager.hasMetadata(ShopManager.SHOP_OFFER_METADATA)) { + villager.setGlowing(false); + villager.removeMetadata(ShopManager.SHOP_OFFER_METADATA, plugin); + } + } + } +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/powerup/IronDeliveryPowerup.java b/src/main/java/plugily/projects/villagedefense/arena/powerup/IronDeliveryPowerup.java new file mode 100644 index 000000000..60c8c7ce9 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/powerup/IronDeliveryPowerup.java @@ -0,0 +1,199 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.powerup; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Creature; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Item; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.handlers.hologram.ArmorStandHologram; +import plugily.projects.villagedefense.handlers.upgrade.NewEntityUpgradeManager; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +public class IronDeliveryPowerup implements Powerup { + + private final Main plugin; + + public IronDeliveryPowerup(Main plugin) { + this.plugin = plugin; + } + + @Override + public boolean canSpawn(Arena arena) { + return arena.getWave() >= 5; + } + + @Override + public void spawn(Arena arena, Location location) { + ArmorStandHologram hologram = new ArmorStandHologram(location.clone().add(0, -1.35, 0)) + .appendItem(XMaterial.IRON_BLOCK.parseItem()) + .appendLine(ChatColor.translateAlternateColorCodes('&', "&e&lIRON DELIVERY")); + + hologram.setPickupHandler(player -> { + if (!plugin.getArenaRegistry().getArena(player).equals(arena)) { + return; + } + XSound.ENTITY_PLAYER_LEVELUP.play(player, 1, 0); + XSound.ENTITY_IRON_GOLEM_DEATH.play(arena.getStartLocation(), 1, 0); + int count; + KitSpecifications.GameTimeState state = KitSpecifications.getTimeState(arena); + if (state == KitSpecifications.GameTimeState.EARLY) { + count = 1; + } else if (state == KitSpecifications.GameTimeState.MID) { + count = 2; + } else { + count = 3; + } + for (int i = 0; i < count; i++) { + Bukkit.getScheduler().runTaskLater(plugin, () -> { + XSound.ENTITY_IRON_GOLEM_REPAIR.play(arena.getStartLocation(), 1, 1.25f); + Creature golem = arena.spawnGolemForce(arena.getStartLocation(), player); + if (golem == null) { + return; + } + golem.setMetadata(NewEntityUpgradeManager.UPGRADES_DISABLED_METADATA, new FixedMetadataValue(plugin, true)); + NewEntityUpgradeManager upgradeManager = plugin.getEntityUpgradeManager(); + upgradeManager.getRegisteredUpgrades() + .stream() + .filter(u -> u.getApplicableEntity() == EntityType.IRON_GOLEM) + .forEach(upgrade -> upgradeManager.applyUpgradeSilent(golem, player, upgrade)); + ArmorStandHologram golemHologram = new ArmorStandHologram(golem.getLocation()) + .appendLine(ChatColor.translateAlternateColorCodes('&', "&e&lIRON DELIVERY")); + golem.getWorld().playSound(golem.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 0.5f); + + new BukkitRunnable() { + int tick = 0; + boolean toggle = false; + + @Override + public void run() { + if (tick == 400 || golemHologram.isDeleted() || golemHologram.getArmorStands().isEmpty()) { + World world = golem.getLocation().getWorld(); + world.spawnParticle(Particle.EXPLOSION_LARGE, golem.getLocation().clone().add(0, 0.5, 0), 1); + world.playSound(golem.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1, 0.5f); + arena.removeIronGolem((IronGolem) golem); + golemHologram.delete(); + cancel(); + return; + } + ArmorStand stand = golemHologram.getArmorStands().get(0); + stand.teleport(golem.getLocation().clone().add(0, 1.1, 0)); + //postpone countdown until wave starts but still teleport moving holograms + if (!arena.isFighting()) { + return; + } + int modulo = tick < 100 ? 10 : tick > 350 ? 3 : 5; + if (tick % modulo == 0) { + String message; + if (toggle) { + message = ChatColor.translateAlternateColorCodes('&', "&c&lIRON DELIVERY (" + ((400 - tick) / 20) + "s)"); + } else { + message = ChatColor.translateAlternateColorCodes('&', "&e&lIRON DELIVERY (" + ((400 - tick) / 20) + "s)"); + } + toggle = !toggle; + stand.setCustomName(message); + } + tick++; + } + }.runTaskTimer(plugin, 1, 1); + Bukkit.getScheduler().runTaskLater(plugin, () -> { + if (!golemHologram.isDeleted()) { + golemHologram.delete(); + } + }, /* remove after 40 seconds to prevent staying even if arena is finished */ 20 * 40); + }, 15 * (i + 1)); + } + hologram.delete(); + }); + + new BukkitRunnable() { + boolean toggle = true; + boolean grounded = false; + boolean flyReverse = false; + int tick = 0; + + @Override + public void run() { + if (tick == 200 || hologram.isDeleted() || hologram.getArmorStands().isEmpty()) { + hologram.getLocation().getWorld().spawnParticle(XParticle.getParticle("EXPLOSION_HUGE"), hologram.getLocation(), 1); + hologram.delete(); + cancel(); + return; + } + if (hologram.getEntityItem().isOnGround() && !grounded) { + grounded = true; + hologram.getEntityItem().setGravity(false); + hologram.getEntityItem().teleport(hologram.getEntityItem().getLocation().add(0, 0.75, 0)); + } + if (grounded) { + hologram.getEntityItem().setGravity(true); + Location newLocation = hologram.getEntityItem().getLocation().clone().add(0, 0.015 * (flyReverse ? -1 : 1), 0); + hologram.getEntityItem().teleport(newLocation); + hologram.getEntityItem().setGravity(false); + if (tick % 60 == 0) { + flyReverse = !flyReverse; + } + } + ArmorStand stand = hologram.getArmorStands().get(0); + int modulo = tick < 100 ? 10 : tick > 150 ? 3 : 5; + if (tick % modulo == 0) { + String message; + if (toggle) { + message = ChatColor.translateAlternateColorCodes('&', "&c&lIRON DELIVERY (" + ((200 - tick) / 20) + "s)"); + } else { + message = ChatColor.translateAlternateColorCodes('&', "&e&lIRON DELIVERY (" + ((200 - tick) / 20) + "s)"); + } + toggle = !toggle; + stand.setCustomName(message); + } + if (tick % 10 == 0) { + for (int i = 0; i < 2; i++) { + Item item = hologram.getLocation().getWorld().dropItemNaturally(stand.getLocation().clone().add(0, 0.5, 0), XMaterial.IRON_INGOT.parseItem()); + item.setInvulnerable(true); + item.setPickupDelay(Integer.MAX_VALUE); + item.setGravity(true); + item.setCustomNameVisible(false); + Bukkit.getScheduler().runTaskLater(plugin, () -> item.remove(), 15); + } + } + stand.teleport(hologram.getEntityItem().getLocation().clone().add(0, -1.25, 0)); + tick++; + } + }.runTaskTimer(plugin, 1, 1); + Bukkit.getScheduler().runTaskLater(plugin, () -> { + if (!hologram.isDeleted()) { + hologram.delete(); + } + }, /* remove after 40 seconds to prevent staying even if arena is finished */ 20 * 40); + } +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/powerup/MoneyPouchPowerup.java b/src/main/java/plugily/projects/villagedefense/arena/powerup/MoneyPouchPowerup.java new file mode 100644 index 000000000..2ab91eef8 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/powerup/MoneyPouchPowerup.java @@ -0,0 +1,163 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.powerup; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.handlers.hologram.ArmorStandHologram; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +public class MoneyPouchPowerup implements Powerup { + + private final List goldBlocks = Arrays.asList(XMaterial.GOLD_NUGGET.parseItem(), XMaterial.GOLD_INGOT.parseItem()); + private final Random random = new Random(); + private final Main plugin; + + public MoneyPouchPowerup(Main plugin) { + this.plugin = plugin; + } + + @Override + public boolean canSpawn(Arena arena) { + return true; + } + + @Override + public void spawn(Arena arena, Location location) { + ArmorStandHologram hologram = new ArmorStandHologram(location.clone().add(0, -1.35, 0)) + .appendItem(XMaterial.GOLD_BLOCK.parseItem()) + .appendLines(ChatColor.translateAlternateColorCodes('&', "&e&lMONEY POUCH")) + .appendLines(ChatColor.translateAlternateColorCodes('&', "&7Click me!")); + + AtomicInteger pouchHits = new AtomicInteger(10); + hologram.setTouchHandler(player -> { + if (!plugin.getArenaRegistry().getArena(player).equals(arena)) { + return; + } + XSound.BLOCK_LAVA_POP.play(player); + Item item = hologram.getLocation().getWorld().dropItemNaturally(hologram.getLocation(), goldBlocks.get(random.nextInt(goldBlocks.size()))); + item.setInvulnerable(true); + item.setPickupDelay(Integer.MAX_VALUE); + item.setGravity(true); + item.setCustomNameVisible(false); + Bukkit.getScheduler().runTaskLater(plugin, () -> item.remove(), 15); + int rand = random.nextInt(3, 15); + plugin.getUserManager().getUser(player).adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), rand); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a+" + rand + " &7orbs")); + int hits = pouchHits.decrementAndGet(); + if (hits <= 0) { + hologram.delete(); + } + }); + + new BukkitRunnable() { + boolean toggle = true; + boolean grounded = false; + boolean flyReverse = false; + boolean soundPlayed = false; + int tick = 0; + + @Override + public void run() { + Item entityItem = hologram.getEntityItem(); + if (tick == 190) { + XSound.BLOCK_ANVIL_DESTROY.play(hologram.getLocation(), 1, 1.25f); + soundPlayed = true; + } + if (tick == 200 || hologram.isDeleted() || hologram.getArmorStands().isEmpty()) { + if (!soundPlayed) { + XSound.BLOCK_ANVIL_DESTROY.play(hologram.getLocation(), 1, 1.25f); + } + for (int i = 0; i < 12; i++) { + Bukkit.getScheduler().runTaskLater(plugin, () -> { + Item item = hologram.getLocation().getWorld().dropItemNaturally(entityItem.getLocation(), goldBlocks.get(random.nextInt(goldBlocks.size()))); + item.setVelocity(item.getVelocity().multiply(random.nextDouble(1.0, 1.5))); + item.setInvulnerable(true); + item.setPickupDelay(Integer.MAX_VALUE); + item.setGravity(true); + item.setCustomNameVisible(false); + Bukkit.getScheduler().runTaskLater(plugin, () -> item.remove(), 15); + }, random.nextInt(1, 10)); + } + hologram.delete(); + cancel(); + return; + } + if (hologram.getEntityItem().isOnGround() && !grounded) { + grounded = true; + entityItem.setGravity(false); + entityItem.teleport(hologram.getEntityItem().getLocation().add(0, 0.75, 0)); + } + if (grounded) { + entityItem.setGravity(true); + Location newLocation = hologram.getEntityItem().getLocation().clone().add(0, 0.015 * (flyReverse ? -1 : 1), 0); + entityItem.teleport(newLocation); + entityItem.setGravity(false); + if (tick % 60 == 0) { + flyReverse = !flyReverse; + } + } + ArmorStand stand = hologram.getArmorStands().get(0); + int modulo = tick < 100 ? 10 : tick > 150 ? 3 : 5; + if (tick % modulo == 0) { + String message; + if (toggle) { + message = ChatColor.translateAlternateColorCodes('&', "&c&lMONEY POUCH (" + ((200 - tick) / 20) + "s)"); + } else { + message = ChatColor.translateAlternateColorCodes('&', "&e&lMONEY POUCH (" + ((200 - tick) / 20) + "s)"); + } + toggle = !toggle; + stand.setCustomName(message); + } + if (tick % 10 == 0) { + for (int i = 0; i < 2; i++) { + Item item = hologram.getLocation().getWorld().dropItemNaturally(stand.getLocation().clone().add(0, 0.5, 0), goldBlocks.get(random.nextInt(goldBlocks.size()))); + item.setInvulnerable(true); + item.setPickupDelay(Integer.MAX_VALUE); + item.setGravity(true); + item.setCustomNameVisible(false); + Bukkit.getScheduler().runTaskLater(plugin, () -> item.remove(), 15); + } + } + stand.teleport(entityItem.getLocation().clone().add(0, -1.25 + 0.27, 0)); + hologram.getArmorStands().get(1).teleport(entityItem.getLocation().clone().add(0, -1.25, 0)); + tick++; + } + }.runTaskTimer(plugin, 1, 1); + Bukkit.getScheduler().runTaskLater(plugin, () -> { + if (!hologram.isDeleted()) { + hologram.delete(); + } + }, /* remove after 40 seconds to prevent staying even if arena is finished */ 20 * 40); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/powerup/Powerup.java b/src/main/java/plugily/projects/villagedefense/arena/powerup/Powerup.java new file mode 100644 index 000000000..3c4fba50a --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/powerup/Powerup.java @@ -0,0 +1,30 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.powerup; + +import org.bukkit.Location; +import plugily.projects.villagedefense.arena.Arena; + +public interface Powerup { + + boolean canSpawn(Arena arena); + + void spawn(Arena arena, Location location); + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/powerup/PowerupEvents.java b/src/main/java/plugily/projects/villagedefense/arena/powerup/PowerupEvents.java new file mode 100644 index 000000000..8381f7b48 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/powerup/PowerupEvents.java @@ -0,0 +1,68 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.powerup; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @author Plajer + *

+ * Created at 06.10.2023 + */ +public class PowerupEvents implements Listener { + + private final List powerups = new ArrayList<>(); + private final Random random = new Random(); + private Main plugin; + + public PowerupEvents(Main plugin) { + this.plugin = plugin; + powerups.add(new IronDeliveryPowerup(plugin)); + powerups.add(new MoneyPouchPowerup(plugin)); + powerups.add(new RandomPowerup(plugin)); + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onPowerupDrop(EntityDeathEvent event) { + if (!CreatureUtils.isEnemy(event.getEntity())) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getEnemies().contains(event.getEntity())) { + continue; + } + if (ThreadLocalRandom.current().nextDouble(0.0, 100.0) <= 1.5) { + powerups.get(random.nextInt(powerups.size())).spawn(arena, event.getEntity().getLocation().clone().add(0, 0.1, 0)); + } + } + } + + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/powerup/RandomPowerup.java b/src/main/java/plugily/projects/villagedefense/arena/powerup/RandomPowerup.java new file mode 100644 index 000000000..0900fb6d7 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/powerup/RandomPowerup.java @@ -0,0 +1,237 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.powerup; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Creature; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.handlers.hologram.ArmorStandHologram; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.BiConsumer; + +public class RandomPowerup implements Powerup { + + private final List localPowerups = new ArrayList<>(); + private final Main plugin; + + public RandomPowerup(Main plugin) { + this.plugin = plugin; + registerLocalPowerups(); + } + + private void registerLocalPowerups() { + String powerupMessage = color("&7You received %name%&7 powerup from %player%!"); + localPowerups.add(new LocalRandomPowerup( + color("&e&lREJUVENATION"), + color("&7Heal and absorption for 5s for you and your pets!"), + (arena, player) -> { + for (Player target : arena.getPlayersLeft()) { + target.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 20 * 5, 0)); + target.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 20 * 5, 0)); + if (!target.equals(player)) { + player.sendMessage(powerupMessage.replace("%name%", color("&e&lREJUVENATION")).replace("%player%", player.getName())); + } + } + List pets = new ArrayList<>(); + pets.addAll(arena.getWolves()); + pets.addAll(arena.getIronGolems()); + for (LivingEntity pet : pets) { + pet.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 20 * 5, 0)); + pet.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 20 * 5, 0)); + } + } + )); + localPowerups.add(new LocalRandomPowerup( + color("&b&lSWIFTNESS"), + color("&7Speed boost for 5s for you and your pets!"), + (arena, player) -> { + for (Player target : arena.getPlayersLeft()) { + target.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 20 * 5, 0)); + if (!target.equals(player)) { + player.sendMessage(powerupMessage.replace("%name%", color("&b&lSWIFTNESS")).replace("%player%", player.getName())); + } + } + List pets = new ArrayList<>(); + pets.addAll(arena.getWolves()); + pets.addAll(arena.getIronGolems()); + for (LivingEntity pet : pets) { + pet.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 20 * 5, 0)); + pet.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 20 * 5, 0)); + } + } + )); + localPowerups.add(new LocalRandomPowerup( + color("&d&lTIME STOP"), + color("&7Alive enemies are frozen in time for 3 seconds!"), + (arena, player) -> { + for (Creature creature : arena.getEnemies()) { + CreatureUtils.doStunEnemy(creature, 3); + } + } + )); + localPowerups.add(new LocalRandomPowerup( + color("&6&lJACKPOT"), + color("&7You won jackpot prize of 300 orbs!"), + (arena, player) -> { + int orbs = 300; + plugin.getUserManager().getUser(player).adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), orbs); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a+" + orbs + " &7orbs")); + } + )); + //todo test divine barrier + localPowerups.add(new LocalRandomPowerup( + color("&f&lDIVINE BARRIER"), + color("&7Villagers are protected from damage for 10s!"), + (arena, player) -> { + for (Villager villager : arena.getVillagers()) { + villager.setNoDamageTicks(20 * 10); + for (Player target : arena.getPlayers()) { + try { + plugin.getGlowingEntities().setGlowing(villager, target, ChatColor.YELLOW); + } catch (ReflectiveOperationException ignored) { + } + Bukkit.getScheduler().runTaskLater(plugin, () -> { + try { + plugin.getGlowingEntities().unsetGlowing(villager, target); + } catch (ReflectiveOperationException ignored) { + } + }, 20 * 10); + } + } + } + )); + } + + private String color(String text) { + return ChatColor.translateAlternateColorCodes('&', text); + } + + @Override + public boolean canSpawn(Arena arena) { + return true; + } + + @Override + public void spawn(Arena arena, Location location) { + ArmorStandHologram hologram = new ArmorStandHologram(location.clone().add(0, -1.5, 0)) + .appendItem(XMaterial.BLAZE_POWDER.parseItem()) + .appendLine(ChatColor.translateAlternateColorCodes('&', "&e&lPOWERUP")); + hologram.setPickupHandler(player -> { + if (!plugin.getArenaRegistry().getArena(player).equals(arena)) { + return; + } + XSound.ENTITY_PLAYER_LEVELUP.play(player, 1, 0); + XSound.ENTITY_VILLAGER_YES.play(player); + hologram.delete(); + onPickup(arena, player); + }); + List materials = Arrays.asList(XMaterial.BLAZE_POWDER.parseItem(), XMaterial.COCOA_BEANS.parseItem(), XMaterial.ANVIL.parseItem(), XMaterial.NETHER_STAR.parseItem()); + + new BukkitRunnable() { + boolean toggle = true; + boolean grounded = false; + boolean flyReverse = false; + int tick = 0; + int index = 0; + + @Override + public void run() { + if (tick == 200 || hologram.isDeleted() || hologram.getArmorStands().isEmpty()) { + hologram.getLocation().getWorld().spawnParticle(XParticle.getParticle("EXPLOSION_HUGE"), hologram.getLocation(), 1); + hologram.delete(); + cancel(); + return; + } + if (hologram.getEntityItem().isOnGround() && !grounded) { + grounded = true; + hologram.getEntityItem().setGravity(false); + hologram.getEntityItem().teleport(hologram.getEntityItem().getLocation().add(0, 0.75, 0)); + } + if (grounded) { + hologram.getEntityItem().setGravity(true); + Location newLocation = hologram.getEntityItem().getLocation().clone().add(0, 0.015 * (flyReverse ? -1 : 1), 0); + hologram.getEntityItem().teleport(newLocation); + hologram.getEntityItem().setGravity(false); + if (tick % 60 == 0) { + flyReverse = !flyReverse; + } + } + ArmorStand stand = hologram.getArmorStands().get(0); + int modulo = tick < 100 ? 10 : tick > 150 ? 3 : 5; + if (tick % modulo == 0) { + String message; + if (toggle) { + message = ChatColor.translateAlternateColorCodes('&', "&c&lRANDOM POWERUP (" + ((200 - tick) / 20) + "s)"); + } else { + message = ChatColor.translateAlternateColorCodes('&', "&e&lRANDOM POWERUP (" + ((200 - tick) / 20) + "s)"); + } + toggle = !toggle; + stand.setCustomName(message); + } + if (tick % 10 == 0) { + hologram.getEntityItem().setItemStack(materials.get(index)); + index++; + if (index >= materials.size()) { + index = 0; + } + + stand.getLocation().getWorld().spawnParticle(XParticle.getParticle("LAVA"), hologram.getEntityItem().getLocation(), 2); + } + stand.teleport(hologram.getEntityItem().getLocation().clone().add(0, -1.25, 0)); + tick++; + } + }.runTaskTimer(plugin, 1, 1); + Bukkit.getScheduler().runTaskLater(plugin, () -> { + if (!hologram.isDeleted()) { + hologram.delete(); + } + }, /* remove after 40 seconds to prevent staying even if arena is finished */ 20 * 40); + } + + private void onPickup(Arena arena, Player player) { + Collections.shuffle(localPowerups); + for (LocalRandomPowerup powerup : localPowerups) { + powerup.onPickup().accept(arena, player); + break; + } + } + + private record LocalRandomPowerup(String name, String description, BiConsumer onPickup) { + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/record/RecordsManager.java b/src/main/java/plugily/projects/villagedefense/arena/record/RecordsManager.java new file mode 100644 index 000000000..71375a480 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/arena/record/RecordsManager.java @@ -0,0 +1,75 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.arena.record; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.kits.basekits.Kit; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.user.VDUser; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Handles creation of users records on particular maps + */ +//todo records announce on game end +//todo record per map placeholder (papi) +public class RecordsManager { + + private final Main plugin; + + public RecordsManager(Main plugin) { + this.plugin = plugin; + } + + /** + * Attempts to register survived gameplay wave as a player record if possible. + * If new record is made an announcement is sent to the player. + */ + public void registerAndAnnounceRecord(Player player, Arena arena) { + Kit kit = plugin.getUserManager().getUser(player).getKit(); + VDUser vdUser = plugin.getVdUserManager().getUser(player); + List records = vdUser.getGameplayRecords() + .getOrDefault(arena.getMapName(), new ArrayList<>()) + .stream() + .filter(record -> record.getMapId().equals(arena.getMapName())) + .collect(Collectors.toList()); + VDUser.GameplayRecord newRecord = new VDUser.GameplayRecord(arena.getMapName(), kit.getName(), arena.getWave()); + records.add(newRecord); + List updatedRecords = records + .stream() + .sorted(Comparator.comparing(VDUser.GameplayRecord::getWave).reversed()) + .limit(3) + .collect(Collectors.toList()); + vdUser.getGameplayRecords().put(arena.getMapName(), updatedRecords); + if (!updatedRecords.contains(newRecord)) { + return; + } + player.playSound(player, Sound.ENTITY_VILLAGER_YES, 1, 1); + player.playSound(player, Sound.ENTITY_PLAYER_LEVELUP, 1, 1.25f); + new MessageBuilder("VD_GOLD_NEW_RECORD_REACHED").asKey().player(player).value(kit.getName()).sendPlayer(); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/arena/states/InGameState.java b/src/main/java/plugily/projects/villagedefense/arena/states/InGameState.java index a2d5bb5f3..190e8818f 100644 --- a/src/main/java/plugily/projects/villagedefense/arena/states/InGameState.java +++ b/src/main/java/plugily/projects/villagedefense/arena/states/InGameState.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.arena.states; @@ -22,6 +22,8 @@ import plugily.projects.minigamesbox.classic.arena.PluginArena; import plugily.projects.minigamesbox.classic.arena.states.PluginInGameState; import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.TitleBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.SoundHelper; import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; import plugily.projects.villagedefense.arena.Arena; @@ -48,10 +50,8 @@ public void handleCall(PluginArena arena) { int zombiesLeft = pluginArena.getZombiesLeft(); getPlugin().getDebugger().debug("Arena {0} Zombies to spawn {1} Zombies left {2} Fighting {3}", arena.getId(), arena.getArenaOption("ZOMBIES_TO_SPAWN"), zombiesLeft, pluginArena.isFighting()); if(pluginArena.isFighting()) { - if(ServerVersion.Version.isCurrentHigher(ServerVersion.Version.v1_8_R3)) { - pluginArena.getCreatureTargetManager().targetCreatures(); - pluginArena.getCreatureTargetManager().targetRideableCreatures(); - } + pluginArena.getCreatureTargetManager().targetCreatures(); + pluginArena.getCreatureTargetManager().targetRideableCreatures(); if(zombiesLeft <= 0) { pluginArena.setFighting(false); pluginArena.getPlugin().getArenaManager().endWave(pluginArena); @@ -63,8 +63,8 @@ public void handleCall(PluginArena arena) { int zombiesLeftFrom = getPlugin().getConfig().getInt("Glowing-Status.Creatures-Left"); int startingWave; if(zombiesLeftFrom > 0 && zombiesLeft <= zombiesLeftFrom - && (startingWave = getPlugin().getConfig().getInt("Glowing-Status.Starting-Wave")) > 0 - && pluginArena.getWave() >= startingWave) { + && (startingWave = getPlugin().getConfig().getInt("Glowing-Status.Starting-Wave")) > 0 + && pluginArena.getWave() >= startingWave) { for(org.bukkit.entity.Creature remaining : pluginArena.getEnemies()) { if(!remaining.isGlowing()) { // To avoid setting glowing property every time remaining.setGlowing(true); @@ -82,9 +82,14 @@ public void handleCall(PluginArena arena) { if(arena.getArenaOption("ZOMBIES_TO_SPAWN") < 0) { arena.setArenaOption("ZOMBIES_TO_SPAWN", 0); } - } else if(arena.getTimer() <= 0) { - pluginArena.setFighting(true); - pluginArena.getPlugin().getArenaManager().startWave(pluginArena); + } else if(arena.getTimer() <= 3) { + SoundHelper.playArenaCountdown(arena); + if(arena.getTimer() <= 0) { + pluginArena.setFighting(true); + pluginArena.getPlugin().getArenaManager().startWave(pluginArena); + } else if(arena.getTimer() >= 1) { + new TitleBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_TITLE_STARTING_" + arena.getTimer()).asKey().arena(arena).sendArena(); + } } } diff --git a/src/main/java/plugily/projects/villagedefense/boot/AdditionalValueInitializer.java b/src/main/java/plugily/projects/villagedefense/boot/AdditionalValueInitializer.java index 4b2075c34..e1af83f21 100644 --- a/src/main/java/plugily/projects/villagedefense/boot/AdditionalValueInitializer.java +++ b/src/main/java/plugily/projects/villagedefense/boot/AdditionalValueInitializer.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.boot; @@ -57,10 +57,6 @@ private void registerConfigOptions() { getConfigPreferences().registerOption("RESPAWN_IN_GAME_JOIN", new ConfigOption("Respawn.In-Game-Join", true)); getConfigPreferences().registerOption("LIMIT_WAVE_UNLIMITED", new ConfigOption("Limit.Wave.Unlimited", true)); getConfigPreferences().registerOption("LIMIT_ENTITY_BUY_AFTER_DEATH", new ConfigOption("Limit.Wave.Entity-Buy-After-Death", true)); - getConfigPreferences().registerOption("ZOMBIE_HEALTHBAR", new ConfigOption("Creatures.Health-Bar", true)); - getConfigPreferences().registerOption("NAME_VISIBILITY_GOLEM", new ConfigOption("Name-Visibility.Golem", true)); - getConfigPreferences().registerOption("NAME_VISIBILITY_WOLF", new ConfigOption("Name-Visibility.Wolf", true)); - getConfigPreferences().registerOption("NAME_VISIBILITY_VILLAGER", new ConfigOption("Name-Visibility.Villager", true)); } private void registerStatistics() { diff --git a/src/main/java/plugily/projects/villagedefense/boot/MessageInitializer.java b/src/main/java/plugily/projects/villagedefense/boot/MessageInitializer.java index e8f39b320..f8afca4d2 100644 --- a/src/main/java/plugily/projects/villagedefense/boot/MessageInitializer.java +++ b/src/main/java/plugily/projects/villagedefense/boot/MessageInitializer.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.boot; @@ -40,6 +40,7 @@ public MessageInitializer(Main plugin) { } public void registerMessages() { + registerGoldMessages(); getMessageManager().registerMessage("COMMANDS_ADMIN_ADDED_ORBS", new Message("Commands.Admin.Added-Orbs", "")); getMessageManager().registerMessage("COMMANDS_ADMIN_RECEIVED_ORBS", new Message("Commands.Admin.Received-Orbs", "")); @@ -53,12 +54,19 @@ public void registerMessages() { getMessageManager().registerMessage("IN_GAME_MESSAGES_ADMIN_REMOVED_ZOMBIES", new Message("In-Game.Messages.Admin.Removed.Zombies", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_ADMIN_REMOVED_WOLVES", new Message("In-Game.Messages.Admin.Removed.Wolves", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_ADMIN_CHANGED_WAVE", new Message("In-Game.Messages.Admin.Changed.Wave", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_ADMIN_NOTHING_T0_CLEAN", new Message("In-Game.Messages.Admin.Nothing-To-Clean", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_ROTTEN_FLESH_LEVEL_UP", new Message("In-Game.Messages.Village.Rotten-Flesh-Level-Up", "")); - getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_FEEL_REFRESHED", new Message("In-Game.Messages.Village.You-Feel-Refreshed", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_DIED", new Message("In-Game.Messages.Village.Villager.Died", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_NAMES", new Message("In-Game.Messages.Village.Villager.Names", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_SPECIAL_OFFER", new Message("In-Game.Messages.Village.Villager.Special-Offer", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_OFFERING_SALE", new Message("In-Game.Messages.Village.Villager.Offering-Sale", "")); + + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_ROTTEN_OFFER", new Message("In-Game.Messages.Village.Villager.Rotten-Offer", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_ROTTEN_SALE", new Message("In-Game.Messages.Village.Villager.Rotten-Sale", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_VILLAGER_PINATA_EVENT", new Message("In-Game.Messages.Village.Villager.Pinata-Event", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_STUCK_ZOMBIES", new Message("In-Game.Messages.Village.Wave.Stuck-Zombies", "")); /*unused*/ getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_SPECTATOR_WARNING", new Message("In-Game.Messages.Village.Wave.Spectator-Warning", "")); @@ -68,13 +76,19 @@ public void registerMessages() { getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_STARTED", new Message("In-Game.Messages.Village.Wave.Started", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_TITLE_START", new Message("In-Game.Messages.Village.Wave.Title.Start", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_TITLE_END", new Message("In-Game.Messages.Village.Wave.Title.End", "")); - getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ORBS_PICKUP", new Message("In-Game.Messages.Village.Orbs.Pickup", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_TITLE_STARTING_3", new Message("In-Game.Messages.Village.Wave.Title.Start-3", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_TITLE_STARTING_2", new Message("In-Game.Messages.Village.Wave.Title.Start-2", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_TITLE_STARTING_1", new Message("In-Game.Messages.Village.Wave.Title.Start-1", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_CANT_RIDE_OTHER", new Message("In-Game.Messages.Village.Entities.Cant-Ride-Other", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_CANT_UPGRADE_THIS", new Message("In-Game.Messages.Village.Entities.Cant-Upgrade-This", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_CANT_UPGRADE_OTHER", new Message("In-Game.Messages.Village.Entities.Cant-Upgrade-Other", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_SPAWN", new Message("In-Game.Messages.Village.Entities.Wolf.Spawn", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_NAME", new Message("In-Game.Messages.Village.Entities.Wolf.Name", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_DEATH", new Message("In-Game.Messages.Village.Entities.Wolf.Death", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_DEATH", new Message("In-Game.Messages.Village.Entities.Golem.Death", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_SPAWN", new Message("In-Game.Messages.Village.Entities.Golem.Spawn", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_NAME", new Message("In-Game.Messages.Village.Entities.Golem.Name", "")); - getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_CANT_RIDE_OTHER", new Message("In-Game.Messages.Village.Entities.Golem.Cant-Ride-Other", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_ZOMBIE_STUNNED_NAME", new Message("In-Game.Messages.Village.Entities.Zombie.Stunned-Name", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_GUI", new Message("In-Game.Messages.Village.Shop.GUI", "")); @@ -83,7 +97,13 @@ public void registerMessages() { getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_MOB_LIMIT_REACHED", new Message("In-Game.Messages.Village.Shop.Mob-Limit-Reached", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_NOT_ENOUGH_CURRENCY", new Message("In-Game.Messages.Village.Shop.Not-Enough-Currency", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_CURRENCY", new Message("In-Game.Messages.Village.Shop.Currency", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_WAVE_LOCK", new Message("In-Game.Messages.Village.Shop.Wave-Lock", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_ITEM_LOCKED", new Message("In-Game.Messages.Village.Shop.Item-Locked-Name", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_WAVE_STILL_LOCKED", new Message("In-Game.Messages.Village.Shop.Wave-Still-Locked", "")); getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_NOT_DEFINED", new Message("In-Game.Messages.Village.Shop.Not-Defined", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_NEW_OFFERS_AVAILABLE", new Message("In-Game.Messages.Village.Shop.New-Shop-Offers", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_SPECIAL_OFFER", new Message("In-Game.Messages.Village.Shop.Special-Offer", "")); + getMessageManager().registerMessage("IN_GAME_MESSAGES_VILLAGE_SHOP_AUTO_ARMOR_EQUIPPED", new Message("In-Game.Messages.Village.Shop.Auto-Armor-Equipped", "")); getMessageManager().registerMessage("LEADERBOARD_STATISTICS_ORBS", new Message("Leaderboard.Statistics.Orbs", "")); @@ -109,155 +129,20 @@ public void registerMessages() { getMessageManager().registerMessage("UPGRADE_MENU_UPGRADES_DEFENSE_NAME", new Message("Upgrade-Menu.Upgrades.Final-Defense.Name", "")); getMessageManager().registerMessage("UPGRADE_MENU_UPGRADES_DEFENSE_DESCRIPTION", new Message("Upgrade-Menu.Upgrades.Final-Defense.Description", "")); - - //CLEANER KIT - - getMessageManager().registerMessage("KIT_CONTENT_CLEANER_NAME", new Message("Kit.Content.Cleaner.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_CLEANER_DESCRIPTION", new Message("Kit.Content.Cleaner.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_CLEANER_GAME_ITEM_NAME", new Message("Kit.Content.Cleaner.Game-Item.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_CLEANER_GAME_ITEM_DESCRIPTION", new Message("Kit.Content.Cleaner.Game-Item.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_CLEANER_CLEANED_MAP", new Message("Kit.Content.Cleaner.Cleaned.Map", "")); - getMessageManager().registerMessage("KIT_CONTENT_CLEANER_CLEANED_NOTHING", new Message("Kit.Content.Cleaner.Cleaned.Nothing", "")); - -//ZOMBIE_TELEPORTER KIT - - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_NAME", new Message("Kit.Content.Zombie-Teleporter.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_DESCRIPTION", new Message("Kit.Content.Zombie-Teleporter.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_GAME_ITEM_NAME", new Message("Kit.Content.Zombie-Teleporter.Game-Item.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_GAME_ITEM_DESCRIPTION", new Message("Kit.Content.Zombie-Teleporter.Game-Item.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_GAME_ITEM_GUI", new Message("Kit.Content.Zombie-Teleporter.Game-Item.GUI", "")); - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_TELEPORT_ZOMBIE", new Message("Kit.Content.Zombie-Teleporter.Teleport.Zombie", "")); - getMessageManager().registerMessage("KIT_CONTENT_ZOMBIE_TELEPORTER_TELEPORT_NOT_FOUND", new Message("Kit.Content.Zombie-Teleporter.Teleport.Not-Found", "")); - -//KNIGHT + //KNIGHT getMessageManager().registerMessage("KIT_CONTENT_KNIGHT_NAME", new Message("Kit.Content.Knight.Name", "")); getMessageManager().registerMessage("KIT_CONTENT_KNIGHT_DESCRIPTION", new Message("Kit.Content.Knight.Description", "")); -//LIGHT_TANK - - getMessageManager().registerMessage("KIT_CONTENT_LIGHT_TANK_NAME", new Message("Kit.Content.Light-Tank.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_LIGHT_TANK_DESCRIPTION", new Message("Kit.Content.Light-Tank.Description", "")); - -//ARCHER - - getMessageManager().registerMessage("KIT_CONTENT_ARCHER_NAME", new Message("Kit.Content.Archer.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_ARCHER_DESCRIPTION", new Message("Kit.Content.Archer.Description", "")); - -//PUNCHER - - getMessageManager().registerMessage("KIT_CONTENT_PUNCHER_NAME", new Message("Kit.Content.Puncher.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_PUNCHER_DESCRIPTION", new Message("Kit.Content.Puncher.Description", "")); - -//HEALER - - getMessageManager().registerMessage("KIT_CONTENT_HEALER_NAME", new Message("Kit.Content.Healer.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_HEALER_DESCRIPTION", new Message("Kit.Content.Healer.Description", "")); - -//LOOTER - - getMessageManager().registerMessage("KIT_CONTENT_LOOTER_NAME", new Message("Kit.Content.Looter.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_LOOTER_DESCRIPTION", new Message("Kit.Content.Looter.Description", "")); - -//RUNNER - - getMessageManager().registerMessage("KIT_CONTENT_RUNNER_NAME", new Message("Kit.Content.Runner.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_RUNNER_DESCRIPTION", new Message("Kit.Content.Runner.Description", "")); - -//MEDIUM_TANK - - getMessageManager().registerMessage("KIT_CONTENT_MEDIUM_TANK_NAME", new Message("Kit.Content.Medium-Tank.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_MEDIUM_TANK_DESCRIPTION", new Message("Kit.Content.Medium-Tank.Description", "")); - -//WORKER - - getMessageManager().registerMessage("KIT_CONTENT_WORKER_NAME", new Message("Kit.Content.Worker.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_WORKER_DESCRIPTION", new Message("Kit.Content.Worker.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_WORKER_GAME_ITEM_CHAT", new Message("Kit.Content.Worker.Game-Item.Chat", "")); - -//DOG_FRIEND - - getMessageManager().registerMessage("KIT_CONTENT_DOG_FRIEND_NAME", new Message("Kit.Content.Dog-Friend.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_DOG_FRIEND_DESCRIPTION", new Message("Kit.Content.Dog-Friend.Description", "")); - -//HARDCORE - - getMessageManager().registerMessage("KIT_CONTENT_HARDCORE_NAME", new Message("Kit.Content.Hardcore.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_HARDCORE_DESCRIPTION", new Message("Kit.Content.Hardcore.Description", "")); - -//GOLEM_FRIEND - - getMessageManager().registerMessage("KIT_CONTENT_GOLEM_FRIEND_NAME", new Message("Kit.Content.Golem-Friend.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_GOLEM_FRIEND_DESCRIPTION", new Message("Kit.Content.Golem-Friend.Description", "")); - -//TORNADO - - getMessageManager().registerMessage("KIT_CONTENT_TORNADO_NAME", new Message("Kit.Content.Tornado.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_TORNADO_DESCRIPTION", new Message("Kit.Content.Tornado.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_TORNADO_GAME_ITEM_NAME", new Message("Kit.Content.Tornado.Game-Item.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_TORNADO_GAME_ITEM_DESCRIPTION", new Message("Kit.Content.Tornado.Game-Item.Description", "")); - -//TERMINATOR - - getMessageManager().registerMessage("KIT_CONTENT_TERMINATOR_NAME", new Message("Kit.Content.Terminator.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_TERMINATOR_DESCRIPTION", new Message("Kit.Content.Terminator.Description", "")); - -//TELEPORTER - - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_NAME", new Message("Kit.Content.Teleporter.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_DESCRIPTION", new Message("Kit.Content.Teleporter.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_GAME_ITEM_NAME", new Message("Kit.Content.Teleporter.Game-Item.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_GAME_ITEM_DESCRIPTION", new Message("Kit.Content.Teleporter.Game-Item.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_GAME_ITEM_GUI", new Message("Kit.Content.Teleport.Game-Item.GUI", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_TELEPORT_VILLAGER", new Message("Kit.Content.Teleporter.Teleport.Villager", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_TELEPORT_WARNING", new Message("Kit.Content.Teleporter.Teleport.Warning", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_TELEPORT_PLAYER", new Message("Kit.Content.Teleporter.Teleport.Player", "")); - getMessageManager().registerMessage("KIT_CONTENT_TELEPORTER_TELEPORT_NOT_FOUND", new Message("Kit.Content.Teleporter.Teleport.Not-Found", "")); - -//HEAVY_TANK - - getMessageManager().registerMessage("KIT_CONTENT_HEAVY_TANK_NAME", new Message("Kit.Content.Heavy-Tank.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_HEAVY_TANK_DESCRIPTION", new Message("Kit.Content.Heavy-Tank.Description", "")); - -//SHOT_BOW - - getMessageManager().registerMessage("KIT_CONTENT_SHOT_BOW_NAME", new Message("Kit.Content.Shot-Bow.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_SHOT_BOW_DESCRIPTION", new Message("Kit.Content.Shot-Bow.Description", "")); - -//BLOCKER - - getMessageManager().registerMessage("KIT_CONTENT_BLOCKER_NAME", new Message("Kit.Content.Blocker.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_BLOCKER_DESCRIPTION", new Message("Kit.Content.Blocker.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_BLOCKER_GAME_ITEM_NAME", new Message("Kit.Content.Blocker.Game-Item.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_BLOCKER_GAME_ITEM_DESCRIPTION", new Message("Kit.Content.Blocker.Game-Item.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_BLOCKER_PLACE_SUCCESS", new Message("Kit.Content.Blocker.Place.Success", "")); - getMessageManager().registerMessage("KIT_CONTENT_BLOCKER_PLACE_FAIL", new Message("Kit.Content.Blocker.Place.Fail", "")); - -//PREMIUM_HARDCORE - - getMessageManager().registerMessage("KIT_CONTENT_PREMIUM_HARDCORE_NAME", new Message("Kit.Content.Premium-Hardcore.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_PREMIUM_HARDCORE_DESCRIPTION", new Message("Kit.Content.Premium-Hardcore.Description", "")); - -//MEDIC - - getMessageManager().registerMessage("KIT_CONTENT_MEDIC_NAME", new Message("Kit.Content.Medic.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_MEDIC_DESCRIPTION", new Message("Kit.Content.Medic.Description", "")); - -//WILD_NAKED - - getMessageManager().registerMessage("KIT_CONTENT_WILD_NAKED_NAME", new Message("Kit.Content.Wild-Naked.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_WILD_NAKED_DESCRIPTION", new Message("Kit.Content.Wild-Naked.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_WILD_NAKED_CANNOT_WEAR_ARMOR", new Message("Kit.Content.Wild-Naked.Cannot-Wear-Armor", "")); - -//WIZARD - - getMessageManager().registerMessage("KIT_CONTENT_WIZARD_NAME", new Message("Kit.Content.Wizard.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_WIZARD_DESCRIPTION", new Message("Kit.Content.Wizard.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_NAME", new Message("Kit.Content.Wizard.Game-Item.Essence.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_DESCRIPTION", new Message("Kit.Content.Wizard.Game-Item.Essence.Description", "")); - getMessageManager().registerMessage("KIT_CONTENT_WIZARD_GAME_ITEM_WAND_NAME", new Message("Kit.Content.Wizard.Game-Item.Wand.Name", "")); - getMessageManager().registerMessage("KIT_CONTENT_WIZARD_GAME_ITEM_WAND_DESCRIPTION", new Message("Kit.Content.Wizard.Game-Item.Wand.Description", "")); + //GENERAL FOR KITS + getMessageManager().registerMessage("KIT_LOCKED_TILL", new Message("Kit.Locked-Till", "")); + getMessageManager().registerMessage("KIT_ABILITY_UNLOCKED", new Message("Kit.Ability-Unlocked", "")); + getMessageManager().registerMessage("KIT_ABILITY_POWER_INCREASED", new Message("Kit.Ability-Power-Increased", "")); + getMessageManager().registerMessage("KIT_PASSIVE_POWER_INCREASED", new Message("Kit.Passive-Power-Increased", "")); + } + private void registerGoldMessages() { + getMessageManager().registerMessage("VD_GOLD_NEW_RECORD_REACHED", new Message("Gold-Messages.New-Record-Reached", "")); } private void registerLocales() { diff --git a/src/main/java/plugily/projects/villagedefense/boot/PlaceholderInitializer.java b/src/main/java/plugily/projects/villagedefense/boot/PlaceholderInitializer.java index e7b54f132..f3e608b15 100644 --- a/src/main/java/plugily/projects/villagedefense/boot/PlaceholderInitializer.java +++ b/src/main/java/plugily/projects/villagedefense/boot/PlaceholderInitializer.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.boot; @@ -24,6 +24,7 @@ import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; import plugily.projects.minigamesbox.classic.handlers.placeholder.Placeholder; import plugily.projects.minigamesbox.classic.handlers.placeholder.PlaceholderManager; +import plugily.projects.minigamesbox.classic.user.User; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.arena.Arena; import plugily.projects.villagedefense.arena.ArenaRegistry; @@ -167,6 +168,21 @@ public String getValue(PluginArena arena) { return Integer.toString(arena.getArenaOption("ROTTEN_FLESH_AMOUNT")); } }); + getPlaceholderManager().registerPlaceholder(new Placeholder("orbs_amount", Placeholder.PlaceholderType.ARENA, Placeholder.PlaceholderExecutor.ALL) { + @Override + public String getValue(Player player, PluginArena arena) { + User user = plugin.getUserManager().getUser(player); + if(user.getArena() == null) { + return "0"; + } + return Integer.toString(user.getStatistic("ORBS")); + } + + @Override + public String getValue(PluginArena arena) { + return "undefined"; + } + }); } private PlaceholderManager getPlaceholderManager() { diff --git a/src/main/java/plugily/projects/villagedefense/commands/arguments/ArgumentsRegistry.java b/src/main/java/plugily/projects/villagedefense/commands/arguments/ArgumentsRegistry.java index adb5e8f19..615114973 100644 --- a/src/main/java/plugily/projects/villagedefense/commands/arguments/ArgumentsRegistry.java +++ b/src/main/java/plugily/projects/villagedefense/commands/arguments/ArgumentsRegistry.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.commands.arguments; @@ -23,7 +23,9 @@ import plugily.projects.villagedefense.commands.arguments.admin.AddOrbsArgument; import plugily.projects.villagedefense.commands.arguments.admin.ClearEntitiesArgument; import plugily.projects.villagedefense.commands.arguments.admin.RespawnArgument; +import plugily.projects.villagedefense.commands.arguments.admin.ScriptEngineDebugArgument; import plugily.projects.villagedefense.commands.arguments.admin.SetPriceArgument; +import plugily.projects.villagedefense.commands.arguments.admin.SetWaveUnlockArgument; import plugily.projects.villagedefense.commands.arguments.admin.arena.SetWaveArgument; /** @@ -46,5 +48,7 @@ public ArgumentsRegistry(Main plugin) { new ClearEntitiesArgument(this); new RespawnArgument(this); new SetPriceArgument(this); + new SetWaveUnlockArgument(this); + new ScriptEngineDebugArgument(this); } } diff --git a/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ClearEntitiesArgument.java b/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ClearEntitiesArgument.java index 25c6e7cfd..2ae68b4bb 100644 --- a/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ClearEntitiesArgument.java +++ b/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ClearEntitiesArgument.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.commands.arguments.admin; @@ -63,7 +63,7 @@ public void execute(CommandSender sender, String[] args) { switch(args[1].toLowerCase()) { case "villager": if(arena.getVillagers().isEmpty()) { - new MessageBuilder("KIT_CONTENT_CLEANER_CLEANED_NOTHING").asKey().send(sender); + new MessageBuilder("IN_GAME_MESSAGES_ADMIN_NOTHING_T0_CLEAN").asKey().send(sender); return; } for(Villager villager : arena.getVillagers()) { @@ -76,7 +76,7 @@ public void execute(CommandSender sender, String[] args) { break; case "zombie": if(arena.getEnemies().isEmpty()) { - new MessageBuilder("KIT_CONTENT_CLEANER_CLEANED_NOTHING").asKey().send(sender); + new MessageBuilder("IN_GAME_MESSAGES_ADMIN_NOTHING_T0_CLEAN").asKey().send(sender); return; } ArenaUtils.removeSpawnedEnemies(arena); @@ -86,7 +86,7 @@ public void execute(CommandSender sender, String[] args) { break; case "golem": if(arena.getIronGolems().isEmpty()) { - new MessageBuilder("KIT_CONTENT_CLEANER_CLEANED_NOTHING").asKey().send(sender); + new MessageBuilder("IN_GAME_MESSAGES_ADMIN_NOTHING_T0_CLEAN").asKey().send(sender); return; } for(IronGolem golem : arena.getIronGolems()) { @@ -99,7 +99,7 @@ public void execute(CommandSender sender, String[] args) { break; case "wolf": if(arena.getWolves().isEmpty()) { - new MessageBuilder("KIT_CONTENT_CLEANER_CLEANED_NOTHING").asKey().send(sender); + new MessageBuilder("IN_GAME_MESSAGES_ADMIN_NOTHING_T0_CLEAN").asKey().send(sender); return; } for(Wolf wolf : arena.getWolves()) { diff --git a/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ScriptEngineDebugArgument.java b/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ScriptEngineDebugArgument.java new file mode 100644 index 000000000..6fe41cb56 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/ScriptEngineDebugArgument.java @@ -0,0 +1,70 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.commands.arguments.admin; + +import plugily.projects.villagedefense.commands.arguments.ArgumentsRegistry; + +/** + * @author Plajer + *

+ * Created at 03.09.2023 + */ +public class ScriptEngineDebugArgument { + + public ScriptEngineDebugArgument(ArgumentsRegistry registry) { + /*registry.mapArgument("villagedefenseadmin", new LabeledCommandArgument("scripttest", Arrays.asList("villagedefense.admin.scripttest"), + CommandArgument.ExecutorType.PLAYER, new LabelData("/vda scripttest &c[text]", "/vda scripttest", + "&7Perform a rewards script engine test\n&6Permission: &7villagedefense.admin.scripttest")) { + @Override + public void execute(CommandSender sender, String[] args) { + Player player = (Player) sender; + if(!registry.getPlugin().getBukkitHelper().checkIsInGameInstance(player)) { + return; + } + Arena arena = (Arena) registry.getPlugin().getArenaRegistry().getArena(player); + StringBuilder combined = new StringBuilder(); + for(String argument : args) { + if(argument.equals("scripttest")) { + continue; + } + combined = combined.append(argument); + } + javax.script.ScriptEngine engine; + try { + engine = new NashornScriptEngineFactory().getScriptEngine(); + } catch(Exception ex) { + player.sendMessage("Engine failed to initialize"); + player.sendMessage(ex.getMessage()); + return; + } + engine.put("player", player); + engine.put("server", Bukkit.getServer()); + engine.put("arena", arena); + engine.put("plugin", registry.getPlugin()); + try { + engine.eval(combined.toString()); + } catch(ScriptException ex) { + player.sendMessage("Evaluation failed at " + ex.getColumnNumber() + ":" + ex.getLineNumber() + ", details:"); + player.sendMessage(ex.getMessage()); + } + } + });*/ + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/SetWaveUnlockArgument.java b/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/SetWaveUnlockArgument.java new file mode 100644 index 000000000..1feee65c0 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/commands/arguments/admin/SetWaveUnlockArgument.java @@ -0,0 +1,88 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.commands.arguments.admin; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import plugily.projects.minigamesbox.classic.commands.arguments.data.CommandArgument; +import plugily.projects.minigamesbox.classic.commands.arguments.data.LabelData; +import plugily.projects.minigamesbox.classic.commands.arguments.data.LabeledCommandArgument; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.number.NumberUtils; +import plugily.projects.villagedefense.commands.arguments.ArgumentsRegistry; + +import java.util.List; + +/** + * @author Plajer + *

+ * Created at 24.11.2018 + */ +public class SetWaveUnlockArgument { + + public SetWaveUnlockArgument(ArgumentsRegistry registry) { + registry.mapArgument("villagedefenseadmin", new LabeledCommandArgument("setwaveunlock", "villagedefense.admin.setwaveunlock", CommandArgument.ExecutorType.PLAYER, + new LabelData("/vda setwaveunlock &6", "/vda setwaveunlock ", + "&7Set wave at which item is purchasable in the shop\n&6Permission: &7villagedefense.admin.setwaveunlock")) { + @Override + public void execute(CommandSender sender, String[] args) { + if(args.length == 1 || !NumberUtils.isInteger(args[1])) { + new MessageBuilder(ChatColor.RED + "Please type wave number!").prefix().send(sender); + return; + } + + Player player = (Player) sender; + ItemStack item = VersionUtils.getItemInHand(player); + if(item == null || item.getType() == Material.AIR) { + new MessageBuilder("COMMANDS_HOLD_ANY_ITEM").asKey().player(player).sendPlayer(); + return; + } + + ItemMeta meta = item.getItemMeta(); + if(meta == null || !meta.hasLore()) { + VersionUtils.setItemInHand(player, new ItemBuilder(item) + .lore(Integer.parseInt(args[1]) + " wave_lock").build()); + new MessageBuilder("COMMANDS_COMMAND_EXECUTED").asKey().player(player).sendPlayer(); + return; + } + + //check any price from lore + List lore = ComplementAccessor.getComplement().getLore(meta); + for(String search : lore) { + if (search.endsWith("wave_lock")) { + lore.remove(search); + break; + } + } + lore.add(0, Integer.parseInt(args[1]) + " wave_lock"); + ComplementAccessor.getComplement().setLore(meta, lore); + item.setItemMeta(meta); + new MessageBuilder("COMMANDS_COMMAND_EXECUTED").asKey().player(player).sendPlayer(); + } + }); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/BaseCreatureInitializer.java b/src/main/java/plugily/projects/villagedefense/creatures/BaseCreatureInitializer.java index 2b4cf55fd..db6823210 100644 --- a/src/main/java/plugily/projects/villagedefense/creatures/BaseCreatureInitializer.java +++ b/src/main/java/plugily/projects/villagedefense/creatures/BaseCreatureInitializer.java @@ -1,20 +1,20 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.creatures; @@ -29,28 +29,13 @@ import plugily.projects.minigamesbox.classic.utils.misc.MiscUtils; public interface BaseCreatureInitializer { + Villager spawnVillager(Location location); Wolf spawnWolf(Location location); IronGolem spawnGolem(Location location); - Creature spawnFastZombie(Location location); - - Creature spawnBabyZombie(Location location); - - Creature spawnHardZombie(Location location); - - Creature spawnPlayerBuster(Location location); - - Creature spawnGolemBuster(Location location); - - Creature spawnVillagerBuster(Location location); - - Creature spawnKnockbackResistantZombies(Location location); - - Creature spawnVillagerSlayer(Location location); - default void applyFollowRange(Creature zombie) { MiscUtils.getEntityAttribute(zombie, Attribute.GENERIC_FOLLOW_RANGE).ifPresent(ai -> ai.setBaseValue(200.0D)); } diff --git a/src/main/java/plugily/projects/villagedefense/creatures/CachedObject.java b/src/main/java/plugily/projects/villagedefense/creatures/CachedObject.java deleted file mode 100644 index 4b54cae71..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/CachedObject.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures; - -/** - * @author Plajer - *

- * Created at 06.01.2019 - */ -public class CachedObject { - - private final String fieldName; - private final Class clazz; - private final Object object; - - public CachedObject(String fieldName, Class clazz, Object object) { - this.fieldName = fieldName; - this.clazz = clazz; - this.object = object; - } - - public String getFieldName() { - return fieldName; - } - - public Class getClazz() { - return clazz; - } - - public Object getObject() { - return object; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/CreatureUtils.java b/src/main/java/plugily/projects/villagedefense/creatures/CreatureUtils.java index 5fbe41331..3d52c8529 100644 --- a/src/main/java/plugily/projects/villagedefense/creatures/CreatureUtils.java +++ b/src/main/java/plugily/projects/villagedefense/creatures/CreatureUtils.java @@ -1,44 +1,40 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.creatures; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.attribute.Attribute; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.IronGolem; import org.bukkit.entity.Player; import org.bukkit.entity.Villager; import org.bukkit.entity.Wolf; +import org.bukkit.metadata.FixedMetadataValue; import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.string.StringFormatUtils; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.v1_9_UP.CustomCreature; -import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ThreadLocalRandom; -import java.util.logging.Level; /** * @author Plajer @@ -48,10 +44,9 @@ public class CreatureUtils { private static String[] villagerNames = ("Jagger,Kelsey,Kelton,Haylie,Harlow,Howard,Wulffric,Winfred,Ashley,Bailey,Beckett,Alfredo,Alfred,Adair,Edgar,ED,Eadwig,Edgaras,Buckley,Stanley,Nuffley," - + "Mary,Jeffry,Rosaly,Elliot,Harry,Sam,Rosaline,Tom,Ivan,Kevin,Adam,Emma,Mira,Jeff,Isac,Nico").split(","); + + "Mary,Jeffry,Rosaly,Elliot,Harry,Sam,Rosaline,Tom,Ivan,Kevin,Adam,Emma,Mira,Jeff,Isac,Nico").split(","); private static Main plugin; private static BaseCreatureInitializer creatureInitializer; - private static final List cachedObjects = new ArrayList<>(); private CreatureUtils() { } @@ -59,40 +54,7 @@ private CreatureUtils() { public static void init(Main plugin) { CreatureUtils.plugin = plugin; villagerNames = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_VILLAGER_NAMES").asKey().build().split(","); - creatureInitializer = initCreatureInitializer(); - } - - public static BaseCreatureInitializer initCreatureInitializer() { - switch(ServerVersion.Version.getCurrent()) { - case v1_8_R3: - return new plugily.projects.villagedefense.creatures.v1_8_R3.CreatureInitializer(); - default: - return new plugily.projects.villagedefense.creatures.v1_9_UP.CreatureInitializer(); - } - } - - public static Object getPrivateField(String fieldName, Class clazz, Object object) { - for(CachedObject cachedObject : cachedObjects) { - if(cachedObject.getClazz().equals(clazz) && cachedObject.getFieldName().equals(fieldName)) { - return cachedObject.getObject(); - } - } - try { - Field field = clazz.getDeclaredField(fieldName); - - AccessController.doPrivileged((PrivilegedAction) () -> { - field.setAccessible(true); - return null; - }); - - Object o = field.get(object); - cachedObjects.add(new CachedObject(fieldName, clazz, o)); - return o; - } catch(NoSuchFieldException | IllegalAccessException e) { - plugin.getLogger().log(Level.WARNING, "Failed to retrieve private field of object " + object.getClass() + "!"); - plugin.getLogger().log(Level.WARNING, e.getMessage() + " (fieldName " + fieldName + ", class " + clazz.getName() + ")"); - } - return null; + creatureInitializer = new plugily.projects.villagedefense.creatures.v1_9_UP.CreatureInitializer(); } /** @@ -107,29 +69,68 @@ public static boolean isEnemy(Entity entity) { } /** - * Applies attributes (i.e. health bar (if enabled), - * health multiplier and follow range) to target zombie. + * Applies attributes (i.e. health bar, + * health multiplier and follow range) to target enemy. * - * @param zombie zombie to apply attributes for - * @param arena arena to get health multiplier from + * @param enemy enemy to apply attributes for + * @param arena arena to get health multiplier from */ - public static void applyAttributes(Creature zombie, Arena arena) { - creatureInitializer.applyFollowRange(zombie); - VersionUtils.setMaxHealth(zombie, VersionUtils.getMaxHealth(zombie) + arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); - zombie.setHealth(VersionUtils.getMaxHealth(zombie)); - if(plugin.getConfigPreferences().getOption("ZOMBIE_HEALTHBAR")) { - zombie.setCustomNameVisible(true); - zombie.setCustomName(StringFormatUtils.getProgressBar((int) zombie.getHealth(), (int) VersionUtils.getMaxHealth(zombie), 50, "|", - ChatColor.YELLOW + "", ChatColor.GRAY + "")); - } + public static void applyAttributes(Creature enemy, Arena arena) { + creatureInitializer.applyFollowRange(enemy); + VersionUtils.setMaxHealth(enemy, VersionUtils.getMaxHealth(enemy) + arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); + enemy.setHealth(VersionUtils.getMaxHealth(enemy)); + enemy.setCustomNameVisible(true); + enemy.setCustomName(CreatureUtils.getHealthNameTag(enemy)); } - public static float getZombieSpeed() { - return 1.3f; + public static String getHealthNameTag(Creature creature) { + return getHealthNameTagPreDamage(creature, 0); } - public static float getBabyZombieSpeed() { - return 2.0f; + public static void doStunEnemy(Creature creature, int seconds) { + if (creature.hasMetadata("VD_STUNNED")) { + return; + } + final String customName = creature.getMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA).get(0).asString(); + String message = new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_ZOMBIE_STUNNED_NAME").asKey().build(); + creature.setMetadata("VD_STUNNED", new FixedMetadataValue(getPlugin(), true)); + creature.setMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA, new FixedMetadataValue(getPlugin(), message)); + creature.setAI(false); + creature.setCustomName(CreatureUtils.getHealthNameTag(creature)); + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + creature.setAI(true); + creature.removeMetadata("VD_STUNNED", getPlugin()); + creature.setMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA, new FixedMetadataValue(getPlugin(), customName)); + creature.setCustomName(CreatureUtils.getHealthNameTag(creature)); + }, 20L * seconds); + } + + /** + * In damage events, health is modified after all events are listened to + * we must apply health bar change pre damage event + * + * @param creature target to generate health bar for + * @param damage final damage taken by enemy before all events have finished + * @return health bar adjusted to the events' damage + */ + public static String getHealthNameTagPreDamage(Creature creature, double damage) { + double health = creature.getHealth() - damage; + if(health < 0) { + health = 0; + } + double maxHealth = creature.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + ChatColor hpColor; + if(health >= maxHealth * 0.75) { + hpColor = ChatColor.GREEN; + } else if(health >= maxHealth * 0.5) { + hpColor = ChatColor.GOLD; + } else if(health >= maxHealth * 0.25) { + hpColor = ChatColor.YELLOW; + } else { + hpColor = ChatColor.RED; + } + String name = creature.getMetadata(CustomCreature.CREATURE_CUSTOM_NAME_METADATA).get(0).asString(); + return name + " " + hpColor + "" + ChatColor.BOLD + "" + Math.round(health) + ChatColor.GREEN + "" + ChatColor.BOLD + "/" + Math.round(maxHealth) + " ❤"; } public static String[] getVillagerNames() { @@ -147,4 +148,5 @@ public static Main getPlugin() { public static BaseCreatureInitializer getCreatureInitializer() { return creatureInitializer; } + } diff --git a/src/main/java/plugily/projects/villagedefense/creatures/DoorBreakListener.java b/src/main/java/plugily/projects/villagedefense/creatures/DoorBreakListener.java index ca240463f..9b1bc765a 100644 --- a/src/main/java/plugily/projects/villagedefense/creatures/DoorBreakListener.java +++ b/src/main/java/plugily/projects/villagedefense/creatures/DoorBreakListener.java @@ -1,86 +1,180 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.creatures; -import java.util.concurrent.ThreadLocalRandom; +import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.entity.EntityType; +import org.bukkit.entity.Creature; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.scheduler.BukkitRunnable; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; import plugily.projects.villagedefense.Main; -import plugily.projects.villagedefense.arena.ArenaRegistry; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.utils.ProtocolUtils; import plugily.projects.villagedefense.utils.Utils; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + /** * Created by Tom on 14/08/2014. */ public class DoorBreakListener extends BukkitRunnable { + public static final String CREATURE_DOOR_BULLDOZER_METADATA = "VD_DOOR_BULLDOZER_BUFF"; + + private static final String DESTROY_STATE_METADATA = "VD_DOOR_DESTROY_STATE"; private final Main plugin; public DoorBreakListener(Main plugin) { this.plugin = plugin; - runTaskTimer(plugin, 1, 20); + runTaskTimer(plugin, 1, 30); } @Override public void run() { for(World world : plugin.getArenaRegistry().getArenaIngameWorlds()) { - for(LivingEntity entity : world.getLivingEntities()) { - if(entity.getType() != EntityType.ZOMBIE) { - continue; - } - + List entities = world.getLivingEntities() + .stream() + .filter(CreatureUtils::isEnemy) + .collect(Collectors.toList()); + for(LivingEntity entity : entities) { for(Block block : plugin.getBukkitHelper().getNearbyBlocks(entity, 1)) { Material door = Utils.getCachedDoor(block); - if(block.getType() != door) { continue; } + if(entity.hasMetadata("VD_DOOR_BLOCK_BAN")) { + Arena arena = findArenaForEntity(entity); + Player player = Bukkit.getPlayer(UUID.fromString(entity.getMetadata("VD_DOOR_BLOCK_BAN_SOURCE").get(0).asString())); + if(arena == null || player == null) { + continue; + } + arena.getAssistHandler().doRegisterDebuffOnEnemy(player, (Creature) entity); + } + + Location location = block.getLocation(); + VersionUtils.sendParticles("SMOKE_LARGE", null, location, 5, 0.1, 0.1, 0.1); + VersionUtils.playSound(location, "ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR"); + int destroyState = getDoorDestroyState(block); + int doubleAttackChance = 15; + if(entity.hasMetadata(CREATURE_DOOR_BULLDOZER_METADATA)) { + doubleAttackChance = 8; + } + if(ThreadLocalRandom.current().nextInt(20) >= doubleAttackChance) { + destroyState++; + } + destroyState++; + block.setMetadata(CREATURE_DOOR_BULLDOZER_METADATA, new FixedMetadataValue(plugin, destroyState)); + doPerformDoorDamage(block, door, destroyState); + if(destroyState >= 10) { + doPerformDoorBreak(block, door); + } + final int finalState = destroyState; + Bukkit.getScheduler().runTaskLater(plugin, () -> { + //block was already destroyed + if(block.getType() == XMaterial.AIR.parseMaterial() || !block.hasMetadata(CREATURE_DOOR_BULLDOZER_METADATA)) { + return; + } + //block wasn't touched for a while, remove the destruction + if(block.getMetadata(CREATURE_DOOR_BULLDOZER_METADATA).get(0).asInt() == finalState) { + doPerformDamageRemoval(block, door); + } + }, 20L * 5); + } + } + } + } - org.bukkit.Location blockLoc = block.getLocation(); + private Arena findArenaForEntity(LivingEntity entity) { + for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if(arena.getEnemies().contains(entity)) { + return arena; + } + } + return null; + } - VersionUtils.sendParticles("SMOKE_LARGE", null, blockLoc, 5, 0.1,0.1,0.1); - VersionUtils.playSound(blockLoc, "ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR"); + private int getDoorDestroyState(Block block) { + int destroyState; + if(!block.hasMetadata(CREATURE_DOOR_BULLDOZER_METADATA)) { + destroyState = 0; + block.setMetadata(CREATURE_DOOR_BULLDOZER_METADATA, new FixedMetadataValue(plugin, destroyState)); + } else { + destroyState = block.getMetadata(CREATURE_DOOR_BULLDOZER_METADATA).get(0).asInt(); + } + return destroyState; + } - if(ThreadLocalRandom.current().nextInt(20) == 5) { - VersionUtils.sendParticles("SMOKE_LARGE", null, blockLoc, 15, 0.1,0.1,0.1); - VersionUtils.sendParticles("EXPLOSION_HUGE", null, blockLoc, 1, 0.1,0.1,0.1); + private void doPerformDoorDamage(Block block, Material door, int destroyState) { + ProtocolUtils.sendBlockBreakAnimation(block, destroyState); - Block b = block.getRelative(BlockFace.UP); + Block relative = block.getRelative(BlockFace.UP); - if(b.getType() == door) { - b.setType(Material.AIR); - } else if((b = block.getRelative(BlockFace.DOWN)).getType() == door) { - b.setType(Material.AIR); - } + if(relative.getType() == door) { + ProtocolUtils.sendBlockBreakAnimation(relative, destroyState); + } else if((relative = block.getRelative(BlockFace.DOWN)).getType() == door) { + ProtocolUtils.sendBlockBreakAnimation(relative, destroyState); + } + } - block.setType(Material.AIR); - VersionUtils.playSound(blockLoc, "ENTITY_ZOMBIE_BREAK_WOODEN_DOOR"); - } - } - } + private void doPerformDamageRemoval(Block block, Material door) { + block.removeMetadata(CREATURE_DOOR_BULLDOZER_METADATA, plugin); + ProtocolUtils.removeBlockBreakAnimation(block); + + Block relative = block.getRelative(BlockFace.UP); + + if(relative.getType() == door) { + ProtocolUtils.removeBlockBreakAnimation(relative); + relative.removeMetadata(CREATURE_DOOR_BULLDOZER_METADATA, plugin); + } else if((relative = block.getRelative(BlockFace.DOWN)).getType() == door) { + ProtocolUtils.removeBlockBreakAnimation(relative); + relative.removeMetadata(CREATURE_DOOR_BULLDOZER_METADATA, plugin); } } + private void doPerformDoorBreak(Block block, Material door) { + Location location = block.getLocation(); + VersionUtils.sendParticles("SMOKE_LARGE", null, location, 15, 0.1, 0.1, 0.1); + VersionUtils.sendParticles("EXPLOSION_HUGE", null, location, 1, 0.1, 0.1, 0.1); + + Block relative = block.getRelative(BlockFace.UP); + + //break order matters + if(relative.getType() == door) { + block.setType(Material.AIR); + relative.setType(Material.AIR); + } else if((relative = block.getRelative(BlockFace.DOWN)).getType() == door) { + relative.setType(Material.AIR); + block.setType(Material.AIR); + } + + VersionUtils.playSound(location, "ENTITY_ZOMBIE_BREAK_WOODEN_DOOR"); + } + } diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/BabyZombie.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/BabyZombie.java deleted file mode 100644 index ac1150950..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/BabyZombie.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 14/08/2014. - */ -public class BabyZombie extends EntityZombie { - - public BabyZombie(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public BabyZombie(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getBabyZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getBabyZombieSpeed())); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); // this one to look at human - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); // this one to target human - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - setBaby(true); - setHealth(2); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/CreatureInitializer.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/CreatureInitializer.java deleted file mode 100644 index eb0aaaf34..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/CreatureInitializer.java +++ /dev/null @@ -1,231 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import net.minecraft.server.v1_8_R3.AttributeInstance; -import net.minecraft.server.v1_8_R3.AttributeModifier; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.EntityTypes; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity; -import org.bukkit.entity.Creature; -import org.bukkit.entity.IronGolem; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Villager; -import org.bukkit.entity.Wolf; -import org.bukkit.entity.Zombie; -import org.bukkit.event.entity.CreatureSpawnEvent; -import plugily.projects.minigamesbox.classic.utils.misc.MessageUtils; -import plugily.projects.villagedefense.creatures.BaseCreatureInitializer; - -public class CreatureInitializer implements BaseCreatureInitializer { - - private static final UUID uId = UUID.fromString("206a89dc-ae78-4c4d-b42c-3b31db3f5a7e"); - private static final UUID movementSpeedUuId = UUID.fromString("206a89dc-ae78-4c4d-b42c-3b31db3f5a7c"); - private static final UUID attackDamageUuId = UUID.fromString("206a89dc-ae78-4c4d-b42c-3b31db3f5a7d"); - - public CreatureInitializer() { - registerEntity("VillageZombie", 54, FastZombie.class); - registerEntity("VillageZombie", 54, BabyZombie.class); - registerEntity("VillageZombie", 54, PlayerBuster.class); - registerEntity("VillageZombie", 54, GolemBuster.class); - registerEntity("VillageZombie", 54, HardZombie.class); - registerEntity("VillageZombie", 54, TankerZombie.class); - registerEntity("VillageZombie", 54, VillagerSlayer.class); - registerEntity("VillageVillager", 120, RidableVillager.class); - registerEntity("VillageVillagerGolem", 99, RidableIronGolem.class); - registerEntity("VillageWolf", 95, WorkingWolf.class); - registerEntity("VillageZombie", 54, VillagerBuster.class); - } - - private void registerEntity(String name, int id, Class customClass) { - try { - List> dataMaps = new ArrayList<>(); - for (Field f : EntityTypes.class.getDeclaredFields()) { - if (f.getType().isAssignableFrom(Map.class)) { - f.setAccessible(true); - dataMaps.add((Map) f.get(null)); - } - } - ((Map, String>) dataMaps.get(1)).put(customClass, name); - ((Map, Integer>) dataMaps.get(3)).put(customClass, id); - } catch (Exception e) { - e.printStackTrace(); - Bukkit.getConsoleSender().sendMessage("[Village Defense] Entities has failed to register!"); - Bukkit.getConsoleSender().sendMessage("[Village Defense] Restart server or change your server version!"); - } - } - - private World getWorld(Location location) { - return ((CraftWorld) location.getWorld()).getHandle(); - } - - @Override - public Villager spawnVillager(Location location) { - RidableVillager ridableVillager = new RidableVillager(location.getWorld()); - ridableVillager.setPosition(location.getX(), location.getY(), location.getZ()); - getWorld(location).addEntity(ridableVillager, CreatureSpawnEvent.SpawnReason.CUSTOM); - Villager villager = (Villager) ridableVillager.getBukkitEntity(); - villager.setRemoveWhenFarAway(false); - return villager; - } - - @Override - public Wolf spawnWolf(Location location) { - WorkingWolf wolf = new WorkingWolf(location.getWorld()); - wolf.setPosition(location.getX(), location.getY(), location.getZ()); - getWorld(location).addEntity(wolf, CreatureSpawnEvent.SpawnReason.CUSTOM); - wolf.setInvisible(false); - return (Wolf) wolf.getBukkitEntity(); - } - - @Override - public IronGolem spawnGolem(Location location) { - RidableIronGolem ironGolem = new RidableIronGolem(location.getWorld()); - ironGolem.setPosition(location.getX(), location.getY(), location.getZ()); - getWorld(location).addEntity(ironGolem, CreatureSpawnEvent.SpawnReason.CUSTOM); - return (IronGolem) ironGolem.getBukkitEntity(); - } - - @Override - public Zombie spawnFastZombie(Location location) { - World world = getWorld(location); - FastZombie fastZombie = new FastZombie(world); - fastZombie.setPosition(location.getX(), location.getY(), location.getZ()); - world.addEntity(fastZombie, CreatureSpawnEvent.SpawnReason.CUSTOM); - Zombie zombie = (Zombie) fastZombie.getBukkitEntity(); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnBabyZombie(Location location) { - World world = getWorld(location); - BabyZombie babyZombie = new BabyZombie(world); - babyZombie.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) babyZombie.getBukkitEntity(); - world.addEntity(babyZombie, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnHardZombie(Location location) { - World world = getWorld(location); - HardZombie hardZombie = new HardZombie(world); - hardZombie.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) hardZombie.getBukkitEntity(); - world.addEntity(hardZombie, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnPlayerBuster(Location location) { - World world = getWorld(location); - PlayerBuster playerBuster = new PlayerBuster(world); - playerBuster.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) playerBuster.getBukkitEntity(); - world.addEntity(playerBuster, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnGolemBuster(Location location) { - World world = getWorld(location); - GolemBuster golemBuster = new GolemBuster(world); - golemBuster.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) golemBuster.getBukkitEntity(); - world.addEntity(golemBuster, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnVillagerBuster(Location location) { - World world = getWorld(location); - VillagerBuster villagerBuster = new VillagerBuster(world); - villagerBuster.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) villagerBuster.getBukkitEntity(); - world.addEntity(villagerBuster, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnKnockbackResistantZombies(Location location) { - World world = getWorld(location); - TankerZombie tankerZombie = new TankerZombie(world); - tankerZombie.getAttributeInstance(GenericAttributes.c).setValue(Double.MAX_VALUE); - tankerZombie.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) tankerZombie.getBukkitEntity(); - world.addEntity(tankerZombie, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public Zombie spawnVillagerSlayer(Location location) { - World world = getWorld(location); - VillagerSlayer villagerSlayer = new VillagerSlayer(world); - villagerSlayer.setPosition(location.getX(), location.getY(), location.getZ()); - Zombie zombie = (Zombie) villagerSlayer.getBukkitEntity(); - world.addEntity(villagerSlayer, CreatureSpawnEvent.SpawnReason.CUSTOM); - zombie.setRemoveWhenFarAway(false); - return zombie; - } - - @Override - public void applyFollowRange(Creature zombie) { - EntityInsentient nmsEntity = (EntityInsentient) ((CraftLivingEntity) zombie).getHandle(); - AttributeInstance attributes = nmsEntity.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); - if (attributes.a(uId) == null) { // Check if the attribute is not set - attributes.b(new AttributeModifier(uId, "follow range multiplier", 200.0D, 1)); - } - } - - @Override - public void applyDamageModifier(LivingEntity entity, double value) { - EntityInsentient nmsEntity = (EntityInsentient) ((CraftLivingEntity) entity).getHandle(); - AttributeInstance attributes = nmsEntity.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE); - if (attributes.a(attackDamageUuId) == null) { - attributes.b(new AttributeModifier(attackDamageUuId, "attack damage multiplier", value, 1)); - } - } - - @Override - public void applySpeedModifier(LivingEntity entity, double value) { - EntityInsentient nmsEntity = (EntityInsentient) ((CraftLivingEntity) entity).getHandle(); - AttributeInstance attributes = nmsEntity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); - if (attributes.a(movementSpeedUuId) == null) { - attributes.b(new AttributeModifier(movementSpeedUuId, "movement speed multiplier", value, 1)); - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/FastZombie.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/FastZombie.java deleted file mode 100644 index d9a335e83..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/FastZombie.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 14/08/2014. - */ -public class FastZombie extends EntityZombie { - - public FastZombie(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public FastZombie(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getZombieSpeed())); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); // this one to look at human - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); // this one to target human - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/GoalSelectorCleaner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/GoalSelectorCleaner.java deleted file mode 100644 index 3361f67a2..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/GoalSelectorCleaner.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityCreature; -import net.minecraft.server.v1_8_R3.PathfinderGoalSelector; -import org.bukkit.craftbukkit.v1_8_R3.util.UnsafeList; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Internal helper class - */ -class GoalSelectorCleaner { - - private GoalSelectorCleaner() { - } - - static void clearSelectors(EntityCreature creature) { - UnsafeList goalB = (UnsafeList) CreatureUtils.getPrivateField("b", PathfinderGoalSelector.class, creature.goalSelector); - goalB.clear(); - UnsafeList goalC = (UnsafeList) CreatureUtils.getPrivateField("c", PathfinderGoalSelector.class, creature.goalSelector); - goalC.clear(); - UnsafeList targetB = (UnsafeList) CreatureUtils.getPrivateField("b", PathfinderGoalSelector.class, creature.targetSelector); - targetB.clear(); - UnsafeList targetC = (UnsafeList) CreatureUtils.getPrivateField("c", PathfinderGoalSelector.class, creature.targetSelector); - targetC.clear(); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/GolemBuster.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/GolemBuster.java deleted file mode 100644 index 26ac46ecb..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/GolemBuster.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import java.util.ArrayList; -import java.util.Arrays; -import net.minecraft.server.v1_8_R3.DamageSource; -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.IronGolem; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.EntityDeathEvent; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 14/08/2014. - */ -public class GolemBuster extends EntityZombie { - - public GolemBuster(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public GolemBuster(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getZombieSpeed())); - goalSelector.a(5, new PathfinderGoalBreakDoorFaster(this)); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityIronGolem.class, 8.0F)); // this one to look at IronGolem - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - //this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityPlayer.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); // this one to target - setHealth(5); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(200.0D); - } - - @Override - public boolean damageEntity(DamageSource damagesource, float f) { - if(damagesource != null && damagesource.getEntity() != null && damagesource.getEntity().getBukkitEntity().getType() == EntityType.IRON_GOLEM) { - this.die(); - org.bukkit.inventory.ItemStack[] itemStack = new org.bukkit.inventory.ItemStack[]{new org.bukkit.inventory.ItemStack(org.bukkit.Material.ROTTEN_FLESH)}; - Bukkit.getServer().getPluginManager().callEvent(new EntityDeathEvent((LivingEntity) getBukkitEntity(), new ArrayList<>(Arrays.asList(itemStack)), expToDrop)); - IronGolem golem = (IronGolem) damagesource.getEntity().getBukkitEntity(); - golem.getWorld().spawnEntity(golem.getLocation(), EntityType.PRIMED_TNT); - return true; - } - super.damageEntity(damagesource, f); - return false; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/HardZombie.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/HardZombie.java deleted file mode 100644 index aa3dc76d9..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/HardZombie.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 14/08/2014. - */ -public class HardZombie extends EntityZombie { - - public HardZombie(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public HardZombie(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getZombieSpeed())); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); // this one to look at human - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); // this one to target human - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - setHealth(35); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/PathfinderGoalBreakDoorFaster.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/PathfinderGoalBreakDoorFaster.java deleted file mode 100644 index 91dae3d81..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/PathfinderGoalBreakDoorFaster.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.Block; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; - - -public class PathfinderGoalBreakDoorFaster extends PathfinderGoalBreakDoor { - - private int i = 0; - private int j = -1; - - public PathfinderGoalBreakDoorFaster(EntityInsentient entityinsentient) { - super(entityinsentient); - } - - @Override - public void e() { - super.e(); - a.world.triggerEffect(1010, b, 0); - - ++i; - int i = (int) (this.i / 240.0F * 10.0F); - - if(i != j) { - a.world.c(a.getId(), b, i); - j = i; - } - - if(this.i == 70) { - a.world.setAir(b); - a.world.triggerEffect(1012, b, 0); - a.world.triggerEffect(2001, b, Block.getId(c)); - } - } - -} - diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/PlayerBuster.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/PlayerBuster.java deleted file mode 100644 index 600736fb0..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/PlayerBuster.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import java.util.ArrayList; -import java.util.Arrays; -import net.minecraft.server.v1_8_R3.DamageSource; -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.inventory.ItemStack; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 15/08/2014. - */ -public class PlayerBuster extends EntityZombie { - - public PlayerBuster(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public PlayerBuster(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getZombieSpeed())); - goalSelector.a(5, new PathfinderGoalBreakDoorFaster(this)); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityPlayer.class, 8.0F)); // this one to look at human - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityPlayer.class, true));// this one to target - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - setHealth(1); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(200.0D); - } - - @Override - public boolean damageEntity(DamageSource damagesource, float f) { - if(damagesource != null && damagesource.getEntity() != null && damagesource.getEntity().getBukkitEntity().getType() == EntityType.PLAYER) { - if(CreatureUtils.getPlugin().getUserManager().getUser((Player) damagesource.getEntity().getBukkitEntity()).isSpectator()) { - return true; - } - ItemStack[] itemStack = new ItemStack[]{new ItemStack(Material.ROTTEN_FLESH)}; - Bukkit.getServer().getPluginManager().callEvent(new EntityDeathEvent((LivingEntity) getBukkitEntity(), new ArrayList<>(Arrays.asList(itemStack)), expToDrop)); - getBukkitEntity().getWorld().spawnEntity(getBukkitEntity().getLocation(), EntityType.PRIMED_TNT); - this.die(); - return true; - } - super.damageEntity(damagesource, f); - return false; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/RidableIronGolem.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/RidableIronGolem.java deleted file mode 100644 index 959cb54b1..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/RidableIronGolem.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.IMonster; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalDefendVillage; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveThroughVillage; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomStroll; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; - -/** - * Created by Tom on 17/08/2014. - */ -public class RidableIronGolem extends EntityIronGolem { - - public RidableIronGolem(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public RidableIronGolem(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - - this.a(1.4F, 2.9F); - ((Navigation) getNavigation()).b(true); - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true)); - goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F)); - goalSelector.a(3, new PathfinderGoalMoveThroughVillage(this, 0.6D, true)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); - goalSelector.a(5, new PathfinderGoalRandomStroll(this, 0.6D)); - goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(1, new PathfinderGoalDefendVillage(this)); - targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false)); - targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 0, false, true, IMonster.e)); - setHealth(500); - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(150D); - } - - @Override - protected void dropDeathLoot(boolean flag, int i) { - //do not drop death loot - } - - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/RidableVillager.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/RidableVillager.java deleted file mode 100644 index 914e22a42..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/RidableVillager.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityAgeable; -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalAvoidTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalInteract; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtTradingPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMakeLove; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveIndoors; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalOpenDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalPlay; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomStroll; -import net.minecraft.server.v1_8_R3.PathfinderGoalRestrictOpenDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalTradeWithPlayer; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; - -/** - * Created by Tom on 15/08/2014. - */ -public class RidableVillager extends EntityVillager { - - public RidableVillager(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public RidableVillager(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - - setSize(0.6F, 1.8F); - ((Navigation) getNavigation()).b(true); - ((Navigation) getNavigation()).a(true); - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityZombie.class, 8.0F, 0.6D, 0.6D)); - goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this)); - goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); - goalSelector.a(2, new PathfinderGoalMoveIndoors(this)); - goalSelector.a(3, new PathfinderGoalRestrictOpenDoor(this)); - goalSelector.a(4, new PathfinderGoalOpenDoor(this, true)); - goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 0.6D)); - goalSelector.a(6, new PathfinderGoalMakeLove(this)); - goalSelector.a(8, new PathfinderGoalPlay(this, 0.32D)); - goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F)); - goalSelector.a(9, new PathfinderGoalInteract(this, EntityVillager.class, 5.0F, 0.02F)); - goalSelector.a(9, new PathfinderGoalRandomStroll(this, 0.6D)); - goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); - } - - @Override - public EntityAgeable createChild(EntityAgeable entityAgeable) { - return this.b(entityAgeable); - } - - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/TankerZombie.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/TankerZombie.java deleted file mode 100644 index b122e9399..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/TankerZombie.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 17/12/2015. - */ -public class TankerZombie extends EntityZombie { - - public TankerZombie(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public TankerZombie(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getZombieSpeed())); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); // this one to look at human - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false)); - targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); // this one to target human - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); - targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - setHealth(35); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); - getAttributeInstance(GenericAttributes.c).setValue(0D); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/VillagerBuster.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/VillagerBuster.java deleted file mode 100644 index c39370357..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/VillagerBuster.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import java.util.ArrayList; -import java.util.Collections; -import net.minecraft.server.v1_8_R3.Entity; -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityIronGolem; -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.inventory.ItemStack; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -/** - * Created by Tom on 15/08/2014. - */ -public class VillagerBuster extends EntityZombie { - - public VillagerBuster(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public VillagerBuster(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CreatureUtils.getZombieSpeed(), false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, CreatureUtils.getZombieSpeed())); - goalSelector.a(5, new PathfinderGoalBreakDoorFaster(this)); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityVillager.class, 8.0F)); // this one to look at human - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - //this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityPlayer.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, false)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, true));// this one to target - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - - - setHealth(10); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(200.0D); - } - - @Override - public boolean r(Entity entity) { - if(entity.getBukkitEntity().getType() == EntityType.VILLAGER) { - this.die(); - Bukkit.getServer().getPluginManager().callEvent(new EntityDeathEvent((LivingEntity) getBukkitEntity(), new ArrayList<>(Collections.singletonList(new ItemStack(Material.ROTTEN_FLESH))), 6)); - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - bukkitEntity.getWorld().spawnEntity(bukkitEntity.getLocation(), EntityType.PRIMED_TNT); - return false; - } - return super.r(entity); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/VillagerSlayer.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/VillagerSlayer.java deleted file mode 100644 index a5a2f71dc..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/VillagerSlayer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityVillager; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalBreakDoor; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; - -/** - * @author Plajer - *

- * Created at 02.05.2018 - */ -public class VillagerSlayer extends EntityZombie { - - public VillagerSlayer(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public VillagerSlayer(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - ((Navigation) getNavigation()).b(true); - - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(1, new PathfinderGoalBreakDoor(this)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0f, false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 1.0f)); - goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, true)); - setHealth(70); - - } - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); - getAttributeInstance(GenericAttributes.c).setValue(0D); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/WorkingWolf.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/WorkingWolf.java deleted file mode 100644 index 08addc79f..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/WorkingWolf.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityWolf; -import net.minecraft.server.v1_8_R3.EntityZombie; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalFloat; -import net.minecraft.server.v1_8_R3.PathfinderGoalFollowOwner; -import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLeapAtTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; -import net.minecraft.server.v1_8_R3.PathfinderGoalMeleeAttack; -import net.minecraft.server.v1_8_R3.PathfinderGoalMoveTowardsRestriction; -import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; -import net.minecraft.server.v1_8_R3.PathfinderGoalRandomStroll; -import net.minecraft.server.v1_8_R3.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; - -/** - * Created by Tom on 17/08/2014. - */ -public class WorkingWolf extends EntityWolf { - - public WorkingWolf(org.bukkit.World world) { - this(((CraftWorld) world).getHandle()); - } - - public WorkingWolf(World world) { - super(world); - - GoalSelectorCleaner.clearSelectors(this); - - this.a(1.4F, 2.9F); - ((Navigation) getNavigation()).a(true); - goalSelector.a(0, new PathfinderGoalFloat(this)); - goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F)); - goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, true)); - goalSelector.a(5, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 2.0F)); - goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.5F, false)); - goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); - goalSelector.a(6, new PathfinderGoalRandomStroll(this, 0.6D)); - goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityZombie.class, true)); - targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true)); - - } - - - @Override - protected void initAttributes() { - super.initAttributes(); - getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(70.0D); - } - - -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/BabyZombieSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/BabyZombieSpawner.java deleted file mode 100644 index 110762af5..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/BabyZombieSpawner.java +++ /dev/null @@ -1,64 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class BabyZombieSpawner implements SimpleEnemySpawner { - @Override - public boolean canApplyHolidayEffect() { - return true; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 ? 1D / 3 : 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 ? spawnAmount / 4 : 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5; - } - - @Override - public Creature spawn(Location location) { - return CreatureUtils.getCreatureInitializer().spawnBabyZombie(location); - } - - @Override - public String getName() { - return "BabyZombie"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/FastZombieSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/FastZombieSpawner.java deleted file mode 100644 index 53cec4535..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/FastZombieSpawner.java +++ /dev/null @@ -1,77 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class FastZombieSpawner implements SimpleEnemySpawner { - @Override - public boolean canApplyHolidayEffect() { - return true; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - if(spawnAmount < 5 || arena.getEnemies().isEmpty()) { - return 1; - } - - if(phase == 5 && wave <= 7) { - return 2d / 3; - } - - return 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - return (spawnAmount < 5 || (phase == 5 && wave <= 7) || arena.getEnemies().isEmpty()) ? spawnAmount : 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return arena.getEnemies().isEmpty() || spawnAmount < 5 || (phase == 5 && wave <= 7); - } - - @Override - public Creature spawn(Location location) { - return CreatureUtils.getCreatureInitializer().spawnFastZombie(location); - } - - @Override - public String getName() { - return "FastZombie"; - } - - @Override - public int getPriority() { - return -1; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/GolemBusterSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/GolemBusterSpawner.java deleted file mode 100644 index a941a804d..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/GolemBusterSpawner.java +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class GolemBusterSpawner implements SimpleEnemySpawner { - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5) { - return 1D / 3; - } - if(wave >= 6) { - return 1D / 8; - } - return 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5) { - return spawnAmount / 4; - } - if(wave >= 6) { - return spawnAmount - 4; - } - return 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 || (wave >= 6 && !arena.getIronGolems().isEmpty()); - } - - @Override - public Creature spawn(Location location) { - Creature golemBuster = CreatureUtils.getCreatureInitializer().spawnGolemBuster(location); - golemBuster.getEquipment().setHelmet(new ItemStack(Material.TNT)); - golemBuster.getEquipment().setHelmetDropChance(0.0F); - VersionUtils.setItemInHandDropChance(golemBuster, 0F); - golemBuster.getEquipment().setBoots(XMaterial.IRON_BOOTS.parseItem()); - golemBuster.getEquipment().setLeggings(XMaterial.IRON_LEGGINGS.parseItem()); - golemBuster.getEquipment().setChestplate(XMaterial.IRON_CHESTPLATE.parseItem()); - return golemBuster; - } - - @Override - public String getName() { - return "GolemBuster"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/HalfInvisibleZombieSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/HalfInvisibleZombieSpawner.java deleted file mode 100644 index da08bf84c..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/HalfInvisibleZombieSpawner.java +++ /dev/null @@ -1,79 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class HalfInvisibleZombieSpawner implements SimpleEnemySpawner { - @Override - public int getMinWave() { - return 7; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - return 1D / 8; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - int total = 0; - if(wave > 23) { - total++; - } - if(wave > 15) { - total += spawnAmount - 13; - } else if(wave > 7) { - total += spawnAmount - 5; - } - return total; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return true; - } - - @Override - public Creature spawn(Location location) { - Creature fastZombie = CreatureUtils.getCreatureInitializer().spawnFastZombie(location); - fastZombie.getEquipment().setBoots(new ItemStack(Material.CHAINMAIL_BOOTS)); - fastZombie.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1)); - return fastZombie; - } - - @Override - public String getName() { - return "HalfInvisibleZombie"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/HardZombieSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/HardZombieSpawner.java deleted file mode 100644 index 5209bce0b..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/HardZombieSpawner.java +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class HardZombieSpawner implements SimpleEnemySpawner { - @Override - public int getMinWave() { - return 4; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5 && wave > 14 && wave <= 20) { - return 1D / 3; - } - if(phase == 15 && wave > 8) { - return 1; - } - return 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5 && wave > 14 && wave <= 20) { - return spawnAmount; - } - if(phase == 15 && wave > 8) { - return spawnAmount - 7; - } - return 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 || phase == 15; - } - - @Override - public Creature spawn(Location location) { - Creature hardZombie = CreatureUtils.getCreatureInitializer().spawnHardZombie(location); - hardZombie.getEquipment().setBoots(new ItemStack(Material.DIAMOND_BOOTS)); - hardZombie.getEquipment().setLeggings(new ItemStack(Material.DIAMOND_LEGGINGS)); - hardZombie.getEquipment().setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE)); - hardZombie.getEquipment().setHelmet(new ItemStack(Material.DIAMOND_HELMET)); - return hardZombie; - } - - @Override - public String getName() { - return "HardZombie"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/KnockbackResistantZombieSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/KnockbackResistantZombieSpawner.java deleted file mode 100644 index 5b8a121f5..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/KnockbackResistantZombieSpawner.java +++ /dev/null @@ -1,73 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class KnockbackResistantZombieSpawner implements SimpleEnemySpawner { - @Override - public int getMinWave() { - return 20; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - return 2D / 9; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - return spawnAmount; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5; - } - - @Override - public Creature spawn(Location location) { - Creature tankerZombie = CreatureUtils.getCreatureInitializer().spawnKnockbackResistantZombies(location); - VersionUtils.setItemInHand(tankerZombie, XMaterial.GOLDEN_AXE.parseItem()); - tankerZombie.getEquipment().setBoots(new ItemStack(Material.DIAMOND_BOOTS)); - tankerZombie.getEquipment().setLeggings(new ItemStack(Material.DIAMOND_LEGGINGS)); - tankerZombie.getEquipment().setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE)); - tankerZombie.getEquipment().setHelmet(new ItemStack(Material.DIAMOND_HELMET)); - return tankerZombie; - } - - @Override - public String getName() { - return "KnockbackResistantZombie"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/PlayerBusterSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/PlayerBusterSpawner.java deleted file mode 100644 index 2537626b2..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/PlayerBusterSpawner.java +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class PlayerBusterSpawner implements SimpleEnemySpawner { - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5) { - return 1D / 3; - } - if(wave > 10) { - return 1D / 8; - } - return 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5) { - return spawnAmount / 4; - } - if(wave > 10) { - return spawnAmount - 8; - } - return 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 || wave > 10; - } - - @Override - public Creature spawn(Location location) { - Creature playerBuster = CreatureUtils.getCreatureInitializer().spawnPlayerBuster(location); - playerBuster.getEquipment().setHelmet(new ItemStack(Material.TNT)); - playerBuster.getEquipment().setHelmetDropChance(0.0F); - VersionUtils.setItemInHandDropChance(playerBuster, 0F); - playerBuster.getEquipment().setBoots(XMaterial.GOLDEN_BOOTS.parseItem()); - playerBuster.getEquipment().setLeggings(XMaterial.GOLDEN_LEGGINGS.parseItem()); - playerBuster.getEquipment().setChestplate(XMaterial.GOLDEN_CHESTPLATE.parseItem()); - return playerBuster; - } - - @Override - public String getName() { - return "PlayerBuster"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/SoftHardZombieSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/SoftHardZombieSpawner.java deleted file mode 100644 index 24c9529c2..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/SoftHardZombieSpawner.java +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class SoftHardZombieSpawner implements SimpleEnemySpawner { - @Override - public int getMinWave() { - return 4; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5 && wave > 7 && wave <= 14) { - return 1D / 3; - } - if(phase == 15 && wave > 4 && wave <= 8) { - return 1; - } - return 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5 && wave > 7 && wave <= 14) { - return spawnAmount; - } - if(phase == 15 && wave > 4 && wave <= 8) { - return spawnAmount - 3; - } - return 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 || phase == 15; - } - - @Override - public Creature spawn(Location location) { - Creature hardBuster = CreatureUtils.getCreatureInitializer().spawnHardZombie(location); - hardBuster.getEquipment().setBoots(new ItemStack(Material.IRON_BOOTS)); - hardBuster.getEquipment().setLeggings(new ItemStack(Material.IRON_LEGGINGS)); - hardBuster.getEquipment().setChestplate(new ItemStack(Material.IRON_CHESTPLATE)); - hardBuster.getEquipment().setHelmet(new ItemStack(Material.IRON_HELMET)); - return hardBuster; - } - - @Override - public String getName() { - return "SoftHardZombie"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/VillagerBusterSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/VillagerBusterSpawner.java deleted file mode 100644 index bd0c71b4d..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/VillagerBusterSpawner.java +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class VillagerBusterSpawner implements SimpleEnemySpawner { - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5) { - return 1D / 3; - } - if(wave >= 15) { - return 1D / 8; - } - return 0; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - if(phase == 5) { - return spawnAmount / 4; - } - if(wave >= 15) { - return spawnAmount - 13; - } - return 0; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5 || (wave >= 15 && !arena.getVillagers().isEmpty()); - } - - @Override - public Creature spawn(Location location) { - Creature villagerBuster = CreatureUtils.getCreatureInitializer().spawnVillagerBuster(location); - villagerBuster.getEquipment().setHelmet(new ItemStack(Material.TNT)); - villagerBuster.getEquipment().setHelmetDropChance(0.0F); - VersionUtils.setItemInHandDropChance(villagerBuster, 0F); - villagerBuster.getEquipment().setBoots(XMaterial.LEATHER_BOOTS.parseItem()); - villagerBuster.getEquipment().setLeggings(XMaterial.LEATHER_LEGGINGS.parseItem()); - villagerBuster.getEquipment().setChestplate(XMaterial.LEATHER_CHESTPLATE.parseItem()); - return villagerBuster; - } - - @Override - public String getName() { - return "VillagerBuster"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/VillagerSlayerSpawner.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/VillagerSlayerSpawner.java deleted file mode 100644 index a73c3353c..000000000 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_8_R3/spawner/VillagerSlayerSpawner.java +++ /dev/null @@ -1,74 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.creatures.v1_8_R3.spawner; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -public class VillagerSlayerSpawner implements SimpleEnemySpawner { - @Override - public int getMinWave() { - return 23; - } - - @Override - public double getSpawnRate(Arena arena, int wave, int phase, int spawnAmount) { - return 1D / 6; - } - - @Override - public int getFinalAmount(Arena arena, int wave, int phase, int spawnAmount) { - return spawnAmount; - } - - @Override - public boolean checkPhase(Arena arena, int wave, int phase, int spawnAmount) { - return phase == 5; - } - - @Override - public Creature spawn(Location location) { - Creature villagerSlayer = CreatureUtils.getCreatureInitializer().spawnVillagerSlayer(location); - VersionUtils.setItemInHand(villagerSlayer, XMaterial.EMERALD.parseItem()); - VersionUtils.setItemInHandDropChance(villagerSlayer, 0F); - villagerSlayer.getEquipment().setBoots(new ItemStack(Material.CHAINMAIL_BOOTS)); - villagerSlayer.getEquipment().setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS)); - villagerSlayer.getEquipment().setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE)); - villagerSlayer.getEquipment().setHelmet(new ItemStack(Material.CHAINMAIL_HELMET)); - return villagerSlayer; - } - - @Override - public String getName() { - return "VillagerSlayer"; - } - - @Override - public ItemStack getDropItem() { - return null; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CreatureInitializer.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CreatureInitializer.java index 380f09b01..51b5eab01 100644 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CreatureInitializer.java +++ b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CreatureInitializer.java @@ -1,20 +1,20 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.creatures.v1_9_UP; @@ -24,7 +24,6 @@ import org.bukkit.entity.IronGolem; import org.bukkit.entity.Villager; import org.bukkit.entity.Wolf; -import org.bukkit.entity.Zombie; import plugily.projects.villagedefense.creatures.BaseCreatureInitializer; import plugily.projects.villagedefense.creatures.CreatureUtils; @@ -57,43 +56,4 @@ public IronGolem spawnGolem(Location location) { throw new ClassCastException("IronGolem creature isn't a iron golem"); } - @Override - public Zombie spawnFastZombie(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnBabyZombie(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnHardZombie(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnPlayerBuster(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnGolemBuster(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnVillagerBuster(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnKnockbackResistantZombies(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } - - @Override - public Zombie spawnVillagerSlayer(Location location) { - throw new UnsupportedOperationException("Method isn't used on 1.9 and up"); - } } diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreature.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreature.java index 2e73b7bac..68974b70b 100644 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreature.java +++ b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreature.java @@ -1,20 +1,20 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.creatures.v1_9_UP; @@ -27,11 +27,11 @@ import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.FixedMetadataValue; -import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.arena.Arena; import plugily.projects.villagedefense.arena.managers.spawner.SimpleEnemySpawner; +import plugily.projects.villagedefense.creatures.DoorBreakListener; import java.util.ArrayList; import java.util.List; @@ -44,13 +44,18 @@ */ public class CustomCreature implements SimpleEnemySpawner { + public static final String CREATURE_ID_METADATA = "VD_CREATURE_ID"; + public static final String CREATURE_CUSTOM_NAME_METADATA = "VD_CREATURE_CUSTOM_NAME"; + private final Main plugin; + private final String name; private final int waveMin; private final int waveMax; private final PriorityTarget priorityTarget; private final boolean explodeTarget; private final String key; private final EntityType entityType; + private final boolean doorBulldozing; private final boolean baby; private final boolean breed; private final int age; @@ -66,17 +71,17 @@ public class CustomCreature implements SimpleEnemySpawner { private final ItemStack dropItem; - public CustomCreature(Main plugin, int waveMin, int waveMax, PriorityTarget priorityTarget, boolean explodeTarget, String key, EntityType entityType, boolean baby, boolean breed, int age, boolean ageLook, int expDrop, boolean holidayEffects, List rates, Map attributes, List equipments, ItemStack dropItem) { + public CustomCreature(Main plugin, String name, int waveMin, int waveMax, PriorityTarget priorityTarget, boolean explodeTarget, String key, EntityType entityType, boolean doorBulldozing, + boolean baby, boolean breed, int age, boolean ageLook, int expDrop, boolean holidayEffects, List rates, Map attributes, List equipments, ItemStack dropItem) { + this.name = name; this.priorityTarget = priorityTarget; this.explodeTarget = explodeTarget; - if(ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_8_R3)) { - throw new IllegalStateException("Couldn't create Creature " + key + " as its only for Version 1.9+"); - } this.plugin = plugin; this.waveMin = waveMin; this.waveMax = waveMax; this.key = key; this.entityType = entityType; + this.doorBulldozing = doorBulldozing; this.baby = baby; this.breed = breed; this.age = age; @@ -138,6 +143,10 @@ public EntityType getEntityType() { return entityType; } + public boolean isDoorBulldozing() { + return doorBulldozing; + } + public boolean isBaby() { return baby; } @@ -306,7 +315,11 @@ public Creature spawn(Location location) { } } creature.setRemoveWhenFarAway(false); - creature.setMetadata("PlugilyProjects-VillageDefense-Name", new FixedMetadataValue(plugin, key)); + creature.setMetadata(CREATURE_CUSTOM_NAME_METADATA, new FixedMetadataValue(plugin, name)); + creature.setMetadata(CustomCreature.CREATURE_ID_METADATA, new FixedMetadataValue(plugin, key)); + if(doorBulldozing) { + creature.setMetadata(DoorBreakListener.CREATURE_DOOR_BULLDOZER_METADATA, new FixedMetadataValue(plugin, true)); + } return creature; } else { entity.remove(); diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreatureEvents.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreatureEvents.java index 897583d18..7b7b80942 100644 --- a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreatureEvents.java +++ b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/CustomCreatureEvents.java @@ -1,20 +1,20 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.creatures.v1_9_UP; @@ -22,25 +22,36 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.IronGolem; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.Villager; import org.bukkit.entity.Wolf; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; +import org.jetbrains.annotations.Nullable; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.arena.Arena; import plugily.projects.villagedefense.arena.managers.spawner.EnemySpawner; +import plugily.projects.villagedefense.creatures.CreatureUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.UUID; /** * @author Tigerpanzer_02 @@ -57,6 +68,8 @@ public CustomCreatureEvents(Main plugin) { } + //todo improve the code structure + //todo test pets giving rewards to owner (wolf/golem) @EventHandler public void onCreatureDeathEvent(EntityDeathEvent event) { LivingEntity entity = event.getEntity(); @@ -78,13 +91,105 @@ public void onCreatureDeathEvent(EntityDeathEvent event) { if(customCreature == null) { continue; } - ItemStack itemStack = customCreature.getDropItem(); - event.getDrops().add(itemStack); - event.setDroppedExp(customCreature.getExpDrop()); + arena.removeEnemy((Creature) entity); + arena.changeArenaOptionBy("TOTAL_KILLED_ZOMBIES", 1); + + Player killer = entity.getKiller(); + if(killer == null) { + killer = performKillerDetection(event); + } + applyKillMetadata(event); + Arena killerArena = plugin.getArenaRegistry().getArena(killer); + + if(killerArena != null) { + plugin.getUserManager().addStat(killer, plugin.getStatsStorage().getStatisticType("KILLS")); + plugin.getUserManager().addExperience(killer, 2 * arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); + plugin.getRewardsHandler().performReward(killer, plugin.getRewardsHandler().getRewardType("ZOMBIE_KILL")); + } + + event.setDroppedExp(0); + filterDrops(event, customCreature, killer); + if(killer != null) { + User user = plugin.getUserManager().getUser(killer); + if(user == null || !user.getArena().equals(arena)) { + continue; + } + Map contribution = arena.getAssistHandler().doDistributeAssistRewards(killer, (Creature) entity); + for(Map.Entry entry : contribution.entrySet()) { + double share = entry.getValue() / 100.0; + double multiplier = Math.log(arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); + if(multiplier < 1.0) { + multiplier = 1.0; + } + int amount = (int) Math.ceil(customCreature.getExpDrop() * share * 1.6 * multiplier); + int orbsBoost = plugin.getPermissionsManager().getPermissionCategoryValue("ORBS_BOOSTER", entry.getKey()); + amount += (amount * (orbsBoost / 100)); + User targetUser = plugin.getUserManager().getUser(entry.getKey()); + targetUser.adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), amount); + } + } } } } + @Nullable + private Player performKillerDetection(EntityDeathEvent event) { + EntityDamageEvent cause = event.getEntity().getLastDamageCause(); + if(!(cause instanceof EntityDamageByEntityEvent)) { + return null; + } + Entity entity = ((EntityDamageByEntityEvent) cause).getDamager(); + if(entity instanceof Player) { + return (Player) entity; + } else if(entity instanceof Wolf || entity instanceof IronGolem) { + if(!entity.hasMetadata("VD_OWNER_UUID")) { + return null; + } + UUID uuid = UUID.fromString(entity.getMetadata("VD_OWNER_UUID").get(0).asString()); + return Bukkit.getServer().getPlayer(uuid); + } + return null; + } + + private void applyKillMetadata(EntityDeathEvent event) { + EntityDamageEvent cause = event.getEntity().getLastDamageCause(); + if (!(cause instanceof EntityDamageByEntityEvent)) { + return; + } + Entity entity = ((EntityDamageByEntityEvent) cause).getDamager(); + if (entity instanceof Wolf || entity instanceof IronGolem) { + if (!entity.hasMetadata("VD_OWNER_UUID")) { + return; + } + if (!entity.hasMetadata("VD_ENTITY_KILLS")) { + entity.setMetadata("VD_ENTITY_KILLS", new FixedMetadataValue(plugin, 1)); + } else { + int kills = entity.getMetadata("VD_ENTITY_KILLS").get(0).asInt(); + entity.removeMetadata("VD_ENTITY_KILLS", plugin); + entity.setMetadata("VD_ENTITY_KILLS", new FixedMetadataValue(plugin, kills + 1)); + } + } + } + + private void filterDrops(EntityDeathEvent event, CustomCreature creature, Player player) { + List filtered = new ArrayList<>(); + for (ItemStack itemStack : event.getDrops()) { + if (itemStack == null || !XMaterial.ROTTEN_FLESH.isSimilar(itemStack)) { + continue; + } + itemStack.setAmount(1); + filtered.add(itemStack); + } + event.getDrops().clear(); + if(filtered.isEmpty() || player == null) { + return; + } + User user = plugin.getUserManager().getUser(player); + if(user.isSpectator()) { + return; + } + player.getInventory().addItem(filtered.toArray(new ItemStack[]{})); + } @EventHandler public void onExplosiveHit(EntityDamageByEntityEvent event) { @@ -115,15 +220,39 @@ public void onExplosiveHit(EntityDamageByEntityEvent event) { entityTypes.add(EntityType.valueOf(priorityTarget.toString())); } if(entityTypes.contains(event.getEntity().getType())) { - event.getDamager().getLocation().getWorld().spawnEntity(event.getDamager().getLocation(), EntityType.PRIMED_TNT); + TNTPrimed primed = (TNTPrimed) event.getDamager().getLocation().getWorld().spawnEntity(event.getDamager().getLocation(), EntityType.PRIMED_TNT); + primed.setSource(event.getEntity()); + primed.setMetadata("VD_PRIMED_TNT", new FixedMetadataValue(arena.getPlugin(), true)); event.getDamager().remove(); Bukkit.getServer().getPluginManager().callEvent(new EntityDeathEvent((LivingEntity) event.getDamager(), new ArrayList<>(Collections.singletonList(new ItemStack(Material.ROTTEN_FLESH))), 6)); } } } + @EventHandler + public void onTntDamage(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof TNTPrimed)) { + return; + } + TNTPrimed primed = (TNTPrimed) event.getDamager(); + if(!primed.hasMetadata("VD_PRIMED_TNT")) { + return; + } + if(event.getEntity() instanceof Player) { + User user = plugin.getUserManager().getUser((Player) event.getEntity()); + if(user == null || user.getArena() == null) { + return; + } + //reduce tnt damage by half for players + event.setDamage(event.getDamage() * 0.5); + } else if(CreatureUtils.isEnemy(event.getEntity())) { + //disable friendly fire + event.setCancelled(true); + } + } + public CustomCreature getCustomCreatureFromCreature(Arena arena, Creature creature) { - List metadataValueList = creature.getMetadata("PlugilyProjects-VillageDefense-Name"); + List metadataValueList = creature.getMetadata(CustomCreature.CREATURE_ID_METADATA); if(metadataValueList.isEmpty()) { plugin.getDebugger().debug("Arena {0} Couldn't find creature meta data", arena.getId()); return null; diff --git a/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/RideableCreatureEvents.java b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/RideableCreatureEvents.java new file mode 100644 index 000000000..53aeebfc2 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/creatures/v1_9_UP/RideableCreatureEvents.java @@ -0,0 +1,119 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.creatures.v1_9_UP; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.util.Vector; +import plugily.projects.villagedefense.Main; + +import java.util.Optional; + +/** + * @author Plajer + *

+ * Created at 04.08.2023 + */ +public class RideableCreatureEvents { + + private Main plugin; + + public RideableCreatureEvents(Main plugin) { + if(plugin.getServer().getPluginManager().getPlugin("ProtocolLib") == null) { + return; + } + this.plugin = plugin; + ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.STEER_VEHICLE) { + @Override + public void onPacketReceiving(PacketEvent event) { + handlePreSteer(event); + } + }); + } + + private void handlePreSteer(PacketEvent event) { + Entity vehicle = event.getPlayer().getVehicle(); + if(vehicle == null) { + return; + } + CustomRideableCreature.RideableType type = null; + for(CustomRideableCreature.RideableType rideableType : CustomRideableCreature.RideableType.values()) { + if(rideableType.name().equals(vehicle.getType().name().toUpperCase())) { + type = rideableType; + break; + } + } + if(type == null) { + return; + } + Optional customRideableCreatureOptional = plugin.getEnemySpawnerRegistry().getRideableCreatureByName(type); + if(!customRideableCreatureOptional.isPresent()) { + return; + } + handleSteer(event, vehicle); + } + + private void handleSteer(PacketEvent event, Entity vehicle) { + Player player = event.getPlayer(); + PacketContainer packet = event.getPacket(); + //https://wiki.vg/Protocol#Player_Input + float sideways = packet.getFloat().read(0); + float forward = packet.getFloat().read(1); + boolean jump = packet.getBooleans().read(0); + boolean unmount = packet.getBooleans().read(1); + if(unmount) { + return; + } + Location location = player.getLocation(); + double radians = Math.toRadians(location.getYaw()); + double x = -forward * Math.sin(radians) + sideways * Math.cos(radians); + double z = forward * Math.cos(radians) + sideways * Math.sin(radians); + double multiplier = 0.4; + if (vehicle instanceof Villager) { + multiplier = 0.25; + } + Vector velocity = new Vector(x, 0.0, z).normalize().multiply(multiplier); + velocity.setY(vehicle.getVelocity().getY()); + if(!Double.isFinite(velocity.getX())) { + velocity.setX(0); + } + if(!Double.isFinite(velocity.getZ())) { + velocity.setZ(0); + } + if(jump && vehicle.isOnGround()) { + velocity.setY(0.45); + } + try { + velocity.checkFinite(); + vehicle.setVelocity(velocity); + } catch(Exception ignored) { + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/events/EntityUpgradeListener.java b/src/main/java/plugily/projects/villagedefense/events/EntityUpgradeListener.java index 8ababd92f..11a068517 100644 --- a/src/main/java/plugily/projects/villagedefense/events/EntityUpgradeListener.java +++ b/src/main/java/plugily/projects/villagedefense/events/EntityUpgradeListener.java @@ -1,43 +1,35 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.events; -import org.bukkit.entity.Creature; -import org.bukkit.entity.Entity; +import org.bukkit.Sound; import org.bukkit.entity.EntityType; -import org.bukkit.entity.IronGolem; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Wolf; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEntityEvent; import plugily.projects.villagedefense.Main; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.creatures.CreatureUtils; -import plugily.projects.villagedefense.handlers.upgrade.EntityUpgradeMenu; +import plugily.projects.villagedefense.handlers.upgrade.NewEntityUpgradeManager; -import java.util.ArrayList; +import java.util.UUID; /** * @author Plajer @@ -46,93 +38,37 @@ */ public class EntityUpgradeListener implements Listener { - private final EntityUpgradeMenu upgradeMenu; private final Main plugin; - - public EntityUpgradeListener(EntityUpgradeMenu upgradeMenu) { - this.upgradeMenu = upgradeMenu; - this.plugin = upgradeMenu.getPlugin(); - upgradeMenu.getPlugin().getServer().getPluginManager().registerEvents(this, upgradeMenu.getPlugin()); + public EntityUpgradeListener(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); } @EventHandler - public void onDamage(EntityDamageByEntityEvent event) { - if(!(event.getDamager() instanceof LivingEntity) || !(event.getDamager() instanceof IronGolem)) { + public void onEntityClick(PlugilyPlayerInteractEntityEvent event) { + if((event.getRightClicked().getType() != EntityType.IRON_GOLEM && event.getRightClicked().getType() != EntityType.WOLF) + || VersionUtils.checkOffHand(event.getHand()) + || !event.getPlayer().isSneaking() + || !event.getRightClicked().hasMetadata("VD_OWNER_UUID") + || plugin.getArenaRegistry().getArena(event.getPlayer()) == null) { return; } - switch(event.getDamager().getType()) { - case IRON_GOLEM: - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(!arena.getIronGolems().contains(event.getDamager())) { - continue; - } - event.setDamage(event.getDamage() + upgradeMenu.getTier(event.getDamager(), upgradeMenu.getUpgrade("Damage")) * 2); - } - break; - case WOLF: - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(!arena.getWolves().contains(event.getDamager())) { - continue; - } - int tier = upgradeMenu.getTier(event.getDamager(), upgradeMenu.getUpgrade("Swarm-Awareness")); - if(tier == 0) { - return; - } - double multiplier = 1; - for(Entity entity : plugin.getBukkitHelper().getNearbyEntities(event.getDamager().getLocation(), 3)) { - if(entity instanceof Wolf) { - multiplier += tier * 0.2; - } - } - event.setDamage(event.getDamage() * multiplier); - } - break; - default: - break; - } - } - - @EventHandler - public void onFinalDefense(EntityDeathEvent event) { - if(event.getEntityType() != EntityType.IRON_GOLEM) { + if(plugin.getUserManager().getUser(event.getPlayer()).isSpectator()) { return; } - - LivingEntity livingEntity = event.getEntity(); - - for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(!arena.getIronGolems().contains(livingEntity)) { - continue; - } - int tier = upgradeMenu.getTier(livingEntity, upgradeMenu.getUpgrade("Final-Defense")); - if(tier == 0) { - return; - } - VersionUtils.sendParticles("EXPLOSION_HUGE", arena.getPlayers(), livingEntity.getLocation(), 5); - for(Entity en : plugin.getBukkitHelper().getNearbyEntities(livingEntity.getLocation(), tier * 5)) { - if(CreatureUtils.isEnemy(en)) { - ((Creature) en).damage(10000.0, livingEntity); - } - } - for(Creature zombie : new ArrayList<>(arena.getEnemies())) { - zombie.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 5, 0)); - zombie.damage(0.5, livingEntity); - } - } - } - - @EventHandler - public void onEntityClick(PlugilyPlayerInteractEntityEvent event) { - if((event.getRightClicked().getType() != EntityType.IRON_GOLEM && event.getRightClicked().getType() != EntityType.WOLF) - || VersionUtils.checkOffHand(event.getHand()) || !event.getPlayer().isSneaking() - || event.getRightClicked().getCustomName() == null) { + UUID uuid = UUID.fromString(event.getRightClicked().getMetadata("VD_OWNER_UUID").get(0).asString()); + if(!event.getPlayer().getUniqueId().equals(uuid)) { + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_CANT_UPGRADE_OTHER").asKey().player(event.getPlayer()).sendPlayer(); + event.getPlayer().playSound(event.getPlayer(), Sound.ENTITY_VILLAGER_NO, 1, 1); return; } - - if(plugin.getArenaRegistry().getArena(event.getPlayer()) != null && !upgradeMenu.getPlugin().getUserManager().getUser(event.getPlayer()).isSpectator()) { - upgradeMenu.openUpgradeMenu((LivingEntity) event.getRightClicked(), event.getPlayer()); + if (event.getRightClicked().hasMetadata(NewEntityUpgradeManager.UPGRADES_DISABLED_METADATA)) { + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_CANT_UPGRADE_THIS").asKey().player(event.getPlayer()).sendPlayer(); + event.getPlayer().playSound(event.getPlayer(), Sound.ENTITY_VILLAGER_NO, 1, 1); + return; } + plugin.getEntityUpgradeManager().openUpgradeMenu((LivingEntity) event.getRightClicked(), event.getPlayer()); } } diff --git a/src/main/java/plugily/projects/villagedefense/events/PluginEvents.java b/src/main/java/plugily/projects/villagedefense/events/PluginEvents.java index f3e9b1cc4..c8072e649 100644 --- a/src/main/java/plugily/projects/villagedefense/events/PluginEvents.java +++ b/src/main/java/plugily/projects/villagedefense/events/PluginEvents.java @@ -1,33 +1,34 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.events; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.IronGolem; import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.entity.Villager; @@ -49,19 +50,32 @@ import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerExpChangeEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.inventory.ItemStack; +import plugily.projects.minigamesbox.classic.api.event.player.PlugilyPlayerChooseKitEvent; import plugily.projects.minigamesbox.classic.arena.ArenaState; import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.kits.basekits.Kit; import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEntityEvent; -import plugily.projects.minigamesbox.string.StringFormatUtils; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; import plugily.projects.villagedefense.Main; import plugily.projects.villagedefense.api.event.game.VillageGameSecretWellEvent; import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.BuilderKit; +import plugily.projects.villagedefense.kits.CleanerKit; +import plugily.projects.villagedefense.kits.CrusaderKit; +import plugily.projects.villagedefense.kits.MedicKit; +import plugily.projects.villagedefense.kits.PetsFriend; +import plugily.projects.villagedefense.kits.ShotBowKit; +import plugily.projects.villagedefense.kits.TerminatorKit; +import plugily.projects.villagedefense.kits.TornadoKit; +import plugily.projects.villagedefense.kits.WizardKit; import plugily.projects.villagedefense.utils.Utils; +import java.util.UUID; + /** * Created by Tom on 16/08/2014. */ @@ -74,35 +88,43 @@ public PluginEvents(Main plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); } - @EventHandler - public void onItemPickup(PlayerExpChangeEvent event) { - Player player = event.getPlayer(); - Arena arena = plugin.getArenaRegistry().getArena(player); - if(arena == null) { + public void onConsumeClearBottle(PlayerItemConsumeEvent event) { + if (!plugin.getArenaRegistry().isInArena(event.getPlayer())) { return; } + //Quality of Life - remove empty glass bottles on potion consume + event.getPlayer().getInventory().remove(Material.GLASS_BOTTLE); + } - User user = plugin.getUserManager().getUser(player); - if(user.isSpectator()) { - event.setAmount(0); - return; - } - - int amount = (int) Math.ceil(event.getAmount() * 1.6 * arena.getArenaOption("ZOMBIE_DIFFICULTY_MULTIPLIER")); - - event.setAmount(amount); - - int orbsBoost = plugin.getPermissionsManager().getPermissionCategoryValue("ORBS_BOOSTER", player); - - amount += (amount * (orbsBoost / 100)); - - amount += event.getAmount(); - user.adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), event.getAmount()); - - new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ORBS_PICKUP").asKey().integer(amount).player(player).sendPlayer(); + @EventHandler + public void onKitSelectSound(PlugilyPlayerChooseKitEvent event) { + XSound.UI_BUTTON_CLICK.play(event.getPlayer()); + playKitSound(event.getKit(), event.getPlayer()); } + private void playKitSound(Kit kit, Player player) { + //knight kit omitted + if (kit instanceof BuilderKit) { + player.playSound(player, Sound.BLOCK_WOODEN_DOOR_OPEN, 1, 0.75f); + } else if (kit instanceof CleanerKit) { + player.playSound(player, Sound.BLOCK_LAVA_EXTINGUISH, 1, 1.5f); + } else if (kit instanceof CrusaderKit) { + player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_0, 1, 1); + } else if (kit instanceof MedicKit) { + player.playSound(player, Sound.ENTITY_VILLAGER_CELEBRATE, 1, 1.25f); + } else if (kit instanceof PetsFriend) { + player.playSound(player, Sound.ENTITY_WOLF_WHINE, 1, 1.15f); + } else if (kit instanceof ShotBowKit) { + player.playSound(player, Sound.ENTITY_ARROW_HIT, 1, 0.75f); + } else if (kit instanceof TerminatorKit) { + player.playSound(player, Sound.ENTITY_WITHER_DEATH, 1, 2.0f); + } else if (kit instanceof TornadoKit) { + player.playSound(player, Sound.ENTITY_ENDERMAN_TELEPORT, 1, 0.25f); + } else if (kit instanceof WizardKit) { + player.playSound(player, Sound.AMBIENT_CAVE, 1, 2.0f); + } + } @EventHandler public void onEntityInteractEntity(PlugilyPlayerInteractEntityEvent event) { @@ -126,29 +148,24 @@ public void onEntityInteractEntity(PlugilyPlayerInteractEntityEvent event) { return; } } - if(event.getRightClicked().getType() == EntityType.VILLAGER) { + Entity target = event.getRightClicked(); + if(target.getType() == EntityType.VILLAGER) { event.setCancelled(true); - arena.getShopManager().openShop(event.getPlayer()); - } else if(event.getRightClicked().getType() == EntityType.IRON_GOLEM) { - if(event.getPlayer().isSneaking()) { - return; + arena.getShopManager().openShop(event.getPlayer(), (Villager) target); + } else if(target.getType() == EntityType.IRON_GOLEM || target.getType() == EntityType.WOLF) { + if(target.getType() == EntityType.WOLF) { + Wolf wolf = (Wolf) event.getRightClicked(); + Bukkit.getScheduler().runTask(plugin, () -> wolf.setSitting(false)); } - IronGolem ironGolem = (IronGolem) event.getRightClicked(); - if(ironGolem.getCustomName() != null && ironGolem.getCustomName().contains(event.getPlayer().getName())) { - VersionUtils.setPassenger(event.getRightClicked(), event.getPlayer()); - } else { - new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_CANT_RIDE_OTHER").asKey().player(event.getPlayer()).sendPlayer(); - } - } else if(event.getRightClicked().getType() == EntityType.WOLF) { - Wolf wolf = (Wolf) event.getRightClicked(); - Bukkit.getScheduler().runTask(plugin, () -> wolf.setSitting(false)); if(event.getPlayer().isSneaking()) { return; } - //to prevent wolves sitting - if(wolf.getCustomName() != null && wolf.getCustomName().contains(event.getPlayer().getName())) { + if(!target.hasMetadata("VD_OWNER_UUID") + || event.getPlayer().getUniqueId().equals(UUID.fromString(target.getMetadata("VD_OWNER_UUID").get(0).asString()))) { VersionUtils.setPassenger(event.getRightClicked(), event.getPlayer()); + return; } + new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_CANT_RIDE_OTHER").asKey().player(event.getPlayer()).sendPlayer(); } } @@ -224,18 +241,34 @@ public void onFriendHurt(EntityDamageByEntityEvent event) { event.setCancelled(true); } - @EventHandler(priority = EventPriority.HIGH) + @EventHandler(priority = EventPriority.HIGHEST) public void onCreatureHurt(EntityDamageEvent event) { - if(!(event.getEntity() instanceof Creature) || !plugin.getConfigPreferences().getOption("ZOMBIE_HEALTHBAR")) { + if(!(event.getEntity() instanceof Creature)) { + return; + } + if (event.isCancelled()) { return; } for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { if(!arena.getEnemies().contains(event.getEntity())) { continue; } + event.setCancelled(false); Creature creature = (Creature) event.getEntity(); - creature.setCustomName(StringFormatUtils.getProgressBar((int) creature.getHealth(), (int) VersionUtils.getMaxHealth(creature), - 50, "|", ChatColor.YELLOW + "", ChatColor.GRAY + "")); + creature.setCustomName(CreatureUtils.getHealthNameTagPreDamage(creature, event.getFinalDamage())); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onAssistApply(EntityDamageByEntityEvent event) { + if(!(event.getEntity() instanceof Creature) || !(event.getDamager() instanceof LivingEntity)) { + return; + } + for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if(!arena.getEnemies().contains(event.getEntity())) { + continue; + } + arena.getAssistHandler().doRegisterDamageOnEnemy((LivingEntity) event.getDamager(), (Creature) event.getEntity(), event.getFinalDamage()); } } @@ -249,7 +282,7 @@ public void onSecond(EntityDamageByEntityEvent event) { return; } if(plugin.getArenaRegistry().getArena((Player) projectile.getShooter()) == null || !(event.getEntity() instanceof Player || event.getEntity() instanceof Wolf - || event.getEntity() instanceof IronGolem || event.getEntity() instanceof Villager)) { + || event.getEntity() instanceof IronGolem || event.getEntity() instanceof Villager)) { return; } event.setCancelled(true); @@ -262,7 +295,6 @@ public void onEntityLeash(PlayerLeashEntityEvent event) { } } - @EventHandler(priority = EventPriority.HIGH) public void onBlockBreakEvent(BlockBreakEvent event) { if(plugin.getArenaRegistry().isInArena(event.getPlayer())) { @@ -325,6 +357,7 @@ public void onSecretWellDrop(InventoryPickupItemEvent event) { return; } for(Player player : arena.getPlayers()) { + player.setHealth(VersionUtils.getMaxHealth(player)); VersionUtils.setMaxHealth(player, VersionUtils.getMaxHealth(player) + 2.0); new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_ROTTEN_FLESH_LEVEL_UP").asKey().player(player).sendPlayer(); } @@ -340,13 +373,13 @@ public void onSecretWellDrop(InventoryPickupItemEvent event) { public void onCombust(EntityCombustEvent event) { // Ignore if this is caused by an event lower down the chain. if(event instanceof EntityCombustByEntityEvent || event instanceof EntityCombustByBlockEvent - || !(event.getEntity() instanceof Creature) - || event.getEntity().getWorld().getEnvironment() != World.Environment.NORMAL) { + || !(event.getEntity() instanceof Creature) + || event.getEntity().getWorld().getEnvironment() != World.Environment.NORMAL) { return; } for(Arena arena : plugin.getArenaRegistry().getPluginArenas()) { - if(arena.getEnemies().contains(event.getEntity())) { + if (arena.getEnemies().contains(event.getEntity()) || arena.getSpecialEntities().contains(event.getEntity())) { event.setCancelled(true); break; } diff --git a/src/main/java/plugily/projects/villagedefense/handlers/hologram/ArmorStandHologram.java b/src/main/java/plugily/projects/villagedefense/handlers/hologram/ArmorStandHologram.java new file mode 100644 index 000000000..5eadcd6a7 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/hologram/ArmorStandHologram.java @@ -0,0 +1,268 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.hologram; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; +import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.villagedefense.Main; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +/** + * @author Plajer + *

+ * Created at 06.10.2023 + */ +public class ArmorStandHologram { + + private static final Main plugin = JavaPlugin.getPlugin(Main.class); + private final List armorStands = new ArrayList<>(); + private Item entityItem; + private ItemStack item; + private List lines = new ArrayList<>(); + private Location location; + private PickupHandler pickupHandler = null; + private TouchHandler touchHandler = null; + + public ArmorStandHologram() { + } + + public ArmorStandHologram(Location location) { + this.location = location; + plugin.getNewHologramManager().getHolograms().add(this); + } + + public ArmorStandHologram(Location location, @NotNull String... lines) { + this.location = location; + this.lines = Arrays.asList(lines); + plugin.getNewHologramManager().getHolograms().add(this); + append(); + } + + public ArmorStandHologram(Location location, @NotNull List lines) { + this.location = location; + this.lines = lines; + plugin.getNewHologramManager().getHolograms().add(this); + append(); + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public ItemStack getItem() { + return item; + } + + public Item getEntityItem() { + return entityItem; + } + + @NotNull + public List getLines() { + return lines; + } + + @NotNull + public List getArmorStands() { + return armorStands; + } + + public ArmorStandHologram overwriteLines(@NotNull String... lines) { + this.lines = Arrays.asList(lines); + append(); + return this; + } + + public ArmorStandHologram overwriteLines(@NotNull List lines) { + this.lines = lines; + append(); + return this; + } + + public ArmorStandHologram overwriteLine(@NotNull String line) { + this.lines = Collections.singletonList(line); + append(); + return this; + } + + public ArmorStandHologram appendLines(@NotNull String... lines) { + this.lines.addAll(Arrays.asList(lines)); + append(); + return this; + } + + public ArmorStandHologram appendLines(@NotNull List lines) { + this.lines.addAll(lines); + append(); + return this; + } + + public ArmorStandHologram appendLine(@NotNull String line) { + this.lines.add(line); + append(); + return this; + } + + public ArmorStandHologram appendItem(@NotNull ItemStack item) { + this.item = item; + append(); + return this; + } + + public void delete() { + for (ArmorStand armor : armorStands) { + armor.setCustomNameVisible(false); + armor.remove(); + plugin.getNewHologramManager().getArmorStands().remove(armor); + } + if (entityItem != null) { + entityItem.remove(); + } + plugin.getNewHologramManager().getHolograms().remove(this); + armorStands.clear(); + } + + public boolean isDeleted() { + return entityItem == null && armorStands.isEmpty(); + } + + private void append() { + delete(); + + World world = location.getWorld(); + if (world == null) { + return; + } + + double distanceAbove = -0.27; + double y = location.getY(); + + for (String line : lines) { + y += distanceAbove; + ArmorStand armorStand = getEntityArmorStand(y); + armorStand.setCustomName(line); + plugin.getDebugger().debug("Creating armorstand with name {0}", line); + armorStands.add(armorStand); + plugin.getNewHologramManager().getArmorStands().add(armorStand); + } + + if (item != null && item.getType() != org.bukkit.Material.AIR) { + entityItem = world.dropItem(location, item); + //set random uuid in meta to prevent item merging for multiple holograms being close + ItemMeta meta = entityItem.getItemStack().getItemMeta(); + meta.setLore(Arrays.asList(UUID.randomUUID().toString())); + entityItem.getItemStack().setItemMeta(meta); + entityItem.setMetadata("PLUGILY_HOLOGRAM", new FixedMetadataValue(plugin, true)); + /*if(VersionUtils.isPaper()) { + entityItem.setCanMobPickup(false); + }*/ + entityItem.setCustomNameVisible(false); + + if (ServerVersion.Version.isCurrentEqualOrHigher(ServerVersion.Version.v1_10_R1)) { + entityItem.setGravity(true); + } + + if (ServerVersion.Version.isCurrentHigher(ServerVersion.Version.v1_8_R3)) { + entityItem.setInvulnerable(true); + } + VersionUtils.teleport(entityItem, location); + } + } + + /** + * @param y the y axis of the hologram + * @return {@link ArmorStand} + */ + private ArmorStand getEntityArmorStand(double y) { + Location loc = location.clone(); + loc.setY(y); + + World world = loc.getWorld(); + if (ServerVersion.Version.isCurrentHigher(ServerVersion.Version.v1_8_R1)) { + world.getNearbyEntities(location, 0.2, 0.2, 0.2).forEach(entity -> { + if (entity instanceof ArmorStand && !armorStands.contains(entity) && !plugin.getNewHologramManager().getArmorStands().contains(entity)) { + entity.remove(); + entity.setCustomNameVisible(false); + plugin.getNewHologramManager().getArmorStands().remove(entity); + } + }); + } + ArmorStand stand = (ArmorStand) world.spawnEntity(loc, EntityType.ARMOR_STAND); + stand.setVisible(false); + stand.setGravity(false); + stand.setCustomNameVisible(true); + stand.setMetadata("PLUGILY_HOLOGRAM", new FixedMetadataValue(plugin, true)); + return stand; + } + + public PickupHandler getPickupHandler() { + return pickupHandler; + } + + /** + * Set a handler which triggers on player pickup item event + * + * @param handler which should be executed on pickup + */ + public ArmorStandHologram setPickupHandler(PickupHandler handler) { + plugin.getNewHologramManager().getHolograms().remove(this); + this.pickupHandler = handler; + plugin.getNewHologramManager().getHolograms().add(this); + return this; + } + + public boolean hasPickupHandler() { + return pickupHandler != null; + } + + public TouchHandler getTouchHandler() { + return touchHandler; + } + + public ArmorStandHologram setTouchHandler(TouchHandler handler) { + plugin.getNewHologramManager().getHolograms().remove(this); + this.touchHandler = handler; + plugin.getNewHologramManager().getHolograms().add(this); + return this; + } + + public boolean hasTouchHandler() { + return touchHandler != null; + } + +} \ No newline at end of file diff --git a/src/main/java/plugily/projects/villagedefense/handlers/hologram/NewHologramManager.java b/src/main/java/plugily/projects/villagedefense/handlers/hologram/NewHologramManager.java new file mode 100644 index 000000000..e77fcefa3 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/hologram/NewHologramManager.java @@ -0,0 +1,141 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.hologram; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import plugily.projects.minigamesbox.classic.PluginMain; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyEntityPickupItemEvent; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Plajer + *

+ * Created at 06.10.2023 + */ +public class NewHologramManager implements Listener { + + private final PluginMain plugin; + private final List armorStands = new ArrayList<>(); + private final List holograms = new ArrayList<>(); + public NewHologramManager(PluginMain plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + public List getArmorStands() { + return armorStands; + } + + public List getHolograms() { + return holograms; + } + + @EventHandler + public void onHologramDamage(EntityDamageByEntityEvent event) { + if (!event.getEntity().hasMetadata("PLUGILY_HOLOGRAM")) { + return; + } + if (!(event.getDamager() instanceof Player)) { + return; + } + if (onTouch((Player) event.getDamager(), event.getEntity())) { + event.setCancelled(true); + } + } + + @EventHandler + public void onHologramTouch(PlayerInteractAtEntityEvent event) { + if (!event.getRightClicked().hasMetadata("PLUGILY_HOLOGRAM")) { + return; + } + if (onTouch(event.getPlayer(), event.getRightClicked())) { + event.setCancelled(true); + } + } + + private boolean onTouch(Player player, Entity entity) { + for (ArmorStandHologram hologram : holograms) { + if (!hologram.hasTouchHandler()) { + continue; + } + Item entityItem = hologram.getEntityItem(); + boolean touch = false; + if (entity.equals(entityItem)) { + touch = true; + } + if (!touch) { + for (ArmorStand stand : hologram.getArmorStands()) { + if (entity.equals(stand)) { + touch = true; + break; + } + } + } + if (touch) { + if (plugin.getUserManager().getUser(player).isSpectator()) { + return false; + } + hologram.getTouchHandler().onTouch(player); + return true; + } + } + return false; + } + + @EventHandler + public void onItemPickup(PlugilyEntityPickupItemEvent event) { + if (!event.getItem().hasMetadata("PLUGILY_HOLOGRAM")) { + return; + } + if (!(event.getEntity() instanceof Player)) { + return; + } + Player player = (Player) event.getEntity(); + if (plugin.getUserManager().getUser(player).getArena() == null) { + return; + } + for (ArmorStandHologram hologram : holograms) { + if (!hologram.hasPickupHandler()) { + continue; + } + Item entityItem = hologram.getEntityItem(); + Item item = event.getItem(); + if (item.equals(entityItem)) { + if (plugin.getUserManager().getUser(player).isSpectator()) { + return; + } + event.setCancelled(true); + hologram.getPickupHandler().onPickup(player); + return; + } + } + //pickup not handled for known hologram, cancel it + event.setCancelled(true); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/hologram/PickupHandler.java b/src/main/java/plugily/projects/villagedefense/handlers/hologram/PickupHandler.java new file mode 100644 index 000000000..0818c2a2f --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/hologram/PickupHandler.java @@ -0,0 +1,34 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.hologram; + +import org.bukkit.entity.Player; + +/** + * Interface to handle items which are being picked up by players. + */ +public interface PickupHandler { + + /** + * Called when a player picks up the entity item of a hologram. + * + * @param player the player who picked up the entity item + */ + public void onPickup(Player player); +} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/hologram/TouchHandler.java b/src/main/java/plugily/projects/villagedefense/handlers/hologram/TouchHandler.java new file mode 100644 index 000000000..e49fce856 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/hologram/TouchHandler.java @@ -0,0 +1,32 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.hologram; + +import org.bukkit.entity.Player; + +/** + * @author Plajer + *

+ * Created at 06.10.2023 + */ +public interface TouchHandler { + + void onTouch(Player player); + +} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/powerup/PowerupHandler.java b/src/main/java/plugily/projects/villagedefense/handlers/powerup/PowerupHandler.java deleted file mode 100644 index afda46f1b..000000000 --- a/src/main/java/plugily/projects/villagedefense/handlers/powerup/PowerupHandler.java +++ /dev/null @@ -1,65 +0,0 @@ - -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.handlers.powerup; - -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import plugily.projects.minigamesbox.classic.api.event.player.PlugilyPlayerPowerupPickupEvent; -import plugily.projects.minigamesbox.classic.handlers.powerup.BasePowerup; -import plugily.projects.villagedefense.Main; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.ArenaUtils; - -/** - * @author Tigerpanzer_02 - *

- * Created at 20.12.2021 - */ -public class PowerupHandler implements Listener { - - private final Main plugin; - - public PowerupHandler(Main plugin) { - this.plugin = plugin; - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @EventHandler - public void onPowerUpPickup(PlugilyPlayerPowerupPickupEvent event) { - BasePowerup powerup = event.getPowerup(); - Arena arena = plugin.getArenaRegistry().getArena(event.getArena().getId()); - if(arena == null) { - return; - } - switch(powerup.getKey().toLowerCase()) { - case "map-clean": - ArenaUtils.removeSpawnedEnemies(arena); - break; - case "golem-raid": - for(int i = 0; i < (plugin.getPowerupRegistry().getLongestEffect(powerup) == 0 ? 3 : plugin.getPowerupRegistry().getLongestEffect(powerup)); i++) { - arena.spawnGolem(arena.getStartLocation(), event.getPlayer()); - } - break; - default: - break; - } - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgrade.java b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgrade.java new file mode 100644 index 000000000..d91b82ef8 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgrade.java @@ -0,0 +1,199 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.upgrade; + +import org.bukkit.entity.EntityType; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EntityUpgrade { + + private String id; + private String metadataKey; + private String name; + private List description; + private int slot; + private int cost; + private EntityType applicableEntity; + private boolean special = false; + private boolean hidden = false; + private int surviveWaves = -1; + private String dependsOn; + private Map upgradeData = new HashMap<>(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getMetadataKey() { + return metadataKey; + } + + public void setMetadataKey(String metadataKey) { + this.metadataKey = metadataKey; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getDescription() { + return description; + } + + public void setDescription(List description) { + this.description = description; + } + + public int getSlot() { + return slot; + } + + public void setSlot(int slot) { + this.slot = slot; + } + + public int getCost() { + return cost; + } + + public void setCost(int cost) { + this.cost = cost; + } + + public EntityType getApplicableEntity() { + return applicableEntity; + } + + public void setApplicableEntity(EntityType applicableEntity) { + this.applicableEntity = applicableEntity; + } + + public boolean isSpecial() { + return special; + } + + public void setSpecial(boolean special) { + this.special = special; + } + + public boolean isHidden() { + return hidden; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public int getSurviveWaves() { + return surviveWaves; + } + + public void setSurviveWaves(int surviveWaves) { + this.surviveWaves = surviveWaves; + } + + public String getDependsOn() { + return dependsOn; + } + + public void setDependsOn(String dependsOn) { + this.dependsOn = dependsOn; + } + + public String getDependencyMetadataKey() { + return "VD_" + dependsOn; + } + + public Map getUpgradeData() { + return upgradeData; + } + + public static class Builder { + + private EntityUpgrade upgrade = new EntityUpgrade(); + + public Builder withId(String id) { + upgrade.setId(id); + upgrade.setMetadataKey("VD_" + id); + return this; + } + + public Builder withName(String name) { + upgrade.setName(name); + return this; + } + + public Builder withDescription(List description) { + upgrade.setDescription(description); + return this; + } + + public Builder atSlot(int slot) { + upgrade.setSlot(slot); + return this; + } + + public Builder withCost(int cost) { + upgrade.setCost(cost); + return this; + } + + public Builder withApplicableEntity(EntityType applicableEntity) { + upgrade.setApplicableEntity(applicableEntity); + return this; + } + + public Builder isSpecial() { + upgrade.setSpecial(true); + return this; + } + + public Builder isHidden(int waveUnlock) { + upgrade.setSurviveWaves(waveUnlock); + upgrade.setHidden(true); + return this; + } + + public Builder andDependsOn(String id) { + upgrade.setDependsOn(id); + return this; + } + + public Builder putUpgradeData(String key, double value) { + upgrade.upgradeData.put(key, value); + return this; + } + + public EntityUpgrade build() { + return upgrade; + } + + } +} \ No newline at end of file diff --git a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgradeHandlerEvents.java b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgradeHandlerEvents.java new file mode 100644 index 000000000..c4b0a7cca --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgradeHandlerEvents.java @@ -0,0 +1,460 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.upgrade; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +//todo merge into single event +public class EntityUpgradeHandlerEvents implements Listener { + + private final Main plugin; + private final Map unstoppableStreak = new HashMap<>(); + + public EntityUpgradeHandlerEvents(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onSwarmAwareness(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Wolf wolf)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + EntityUpgrade swarmAwareness1 = plugin.getEntityUpgradeManager().getUpgrade("WOLF_SWARM_AWARENESS_1"); + EntityUpgrade swarmAwareness2 = plugin.getEntityUpgradeManager().getUpgrade("WOLF_SWARM_AWARENESS_2"); + if (!wolf.hasMetadata(swarmAwareness1.getMetadataKey()) + && !wolf.hasMetadata(swarmAwareness2.getMetadataKey())) { + return; + } + double increase = 0; + int nearby = 0; + for (Entity entity : plugin.getBukkitHelper().getNearbyEntities(event.getDamager().getLocation(), 3)) { + if (entity instanceof Wolf) { + nearby++; + } + } + if (event.getDamager().hasMetadata(swarmAwareness2.getMetadataKey())) { + increase = swarmAwareness2.getUpgradeData().get("increase"); + } else { + increase = swarmAwareness1.getUpgradeData().get("increase"); + } + double bonusPercent = Math.min(increase * nearby, 30) / 100.0; + event.setDamage(event.getDamage() + (event.getDamage() * bonusPercent)); + return; + } + } + + @EventHandler + public void onFinalDefense(EntityDeathEvent event) { + if (!(event.getEntity() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade finalDefense = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_FINAL_DEFENSE"); + if (!ironGolem.hasMetadata(finalDefense.getMetadataKey())) { + return; + } + VersionUtils.sendParticles("EXPLOSION_HUGE", arena.getPlayers(), ironGolem.getLocation(), 5); + for (Entity en : plugin.getBukkitHelper().getNearbyEntities(ironGolem.getLocation(), 6)) { + if (CreatureUtils.isEnemy(en)) { + ((Creature) en).damage(KitSpecifications.LETHAL_DAMAGE, ironGolem); + } + } + for (Entity en : plugin.getBukkitHelper().getNearbyEntities(ironGolem.getLocation(), 9)) { + if (CreatureUtils.isEnemy(en)) { + ((Creature) en).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, Integer.MAX_VALUE, 1)); + ((Creature) en).damage(0.5, ironGolem); + } + } + return; + } + } + + @EventHandler + public void onUnstoppableStreak(EntityDeathEvent event) { + if (!(event.getEntity().getKiller() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade unstoppableStreak1 = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_UNSTOPPABLE_STREAK_1"); + EntityUpgrade unstoppableStreak2 = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_UNSTOPPABLE_STREAK_2"); + if (!ironGolem.hasMetadata(unstoppableStreak1.getMetadataKey()) + && !ironGolem.hasMetadata(unstoppableStreak2.getMetadataKey())) { + return; + } + double increaseValue; + if (ironGolem.hasMetadata(unstoppableStreak2.getMetadataKey())) { + increaseValue = unstoppableStreak2.getUpgradeData().get("increase"); + } else { + increaseValue = unstoppableStreak1.getUpgradeData().get("increase"); + } + if (unstoppableStreak.containsKey(ironGolem.getUniqueId())) { + Bukkit.getScheduler().cancelTask(unstoppableStreak.get(ironGolem.getUniqueId())); + } + final double originalDamage = ironGolem.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue(); + ironGolem.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(originalDamage + increaseValue); + int taskId = Bukkit.getScheduler().runTaskLater(plugin, () -> ironGolem.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(originalDamage), 20 * 5).getTaskId(); + unstoppableStreak.put(ironGolem.getUniqueId(), taskId); + return; + } + } + + @EventHandler + public void onToughening(EntityDamageEvent event) { + if (!(event.getEntity() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade toughening = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_TOUGHENING"); + if (!ironGolem.hasMetadata(toughening.getMetadataKey())) { + return; + } + if (event.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION || event.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) { + if (ironGolem.hasMetadata("VD_GOLEM_EXPLOSION_TIME")) { + Instant date = new Date(ironGolem.getMetadata("VD_GOLEM_EXPLOSION_TIME").get(0).asLong()).toInstant(); + if (Duration.between(date, Instant.now()).abs().toSeconds() <= 8) { + event.setDamage(event.getDamage() - (event.getDamage() * 0.3)); + } else { + ironGolem.removeMetadata("VD_GOLEM_EXPLOSION_TIME", plugin); + } + } + ironGolem.setMetadata("VD_GOLEM_EXPLOSION_TIME", new FixedMetadataValue(plugin, System.currentTimeMillis())); + } + if (ironGolem.getHealth() < ironGolem.getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue() * 0.4) { + event.setDamage(event.getDamage() * 0.75); + } + return; + } + } + + @EventHandler + public void onWillToSurvive(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade willToSurvive = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_SURVIVOR"); + if (!ironGolem.hasMetadata(willToSurvive.getMetadataKey())) { + return; + } + double healAmount = event.getDamage() * 0.05; + ironGolem.setHealth(Math.min(ironGolem.getHealth() + healAmount, VersionUtils.getMaxHealth(ironGolem))); + return; + } + } + + @EventHandler + public void onBannerOfCommand(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade bannerOfCommand = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_BANNER_OF_COMMAND"); + for (Entity entity : ironGolem.getNearbyEntities(6, 6, 6)) { + if (!(entity instanceof IronGolem golem)) { + continue; + } + if (golem.hasMetadata(bannerOfCommand.getMetadataKey())) { + event.setDamage(event.getDamage() + (event.getDamage() * 0.1)); + } + } + return; + } + } + + @EventHandler + public void onRemembranceLament(EntityDeathEvent event) { + if (!(event.getEntity() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade remembranceLament = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_LAMENT"); + if (!ironGolem.hasMetadata(remembranceLament.getMetadataKey())) { + return; + } + for (Creature creature : arena.getEnemies()) { + if (KitHelper.executeEnemy(creature, ironGolem)) { + VersionUtils.sendParticles("LAVA", arena.getPlayers(), creature.getLocation(), 20); + } + } + List toHeal = new ArrayList<>(); + toHeal.addAll(arena.getPlayersLeft()); + toHeal.addAll(arena.getVillagers()); + toHeal.addAll(arena.getWolves()); + toHeal.addAll(arena.getIronGolems()); + for (LivingEntity livingEntity : toHeal) { + livingEntity.setHealth(VersionUtils.getMaxHealth(livingEntity)); + } + for (Player player : arena.getPlayers()) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&aOur beloved Iron Golem has died and protected the Village as a final wish, rest in peace.")); + } + } + } + + @EventHandler + public void onDeepWounds(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Wolf wolf) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + EntityUpgrade deepWounds = plugin.getEntityUpgradeManager().getUpgrade("WOLF_DEEP_WOUNDS"); + if (!wolf.hasMetadata(deepWounds.getMetadataKey())) { + return; + } + if (ThreadLocalRandom.current().nextInt(0, 100) <= 25) { + ((LivingEntity) event.getEntity()).addPotionEffect(new PotionEffect(PotionEffectType.POISON, 20 * 3, 0)); + } + } + } + + @EventHandler + public void onWolfPack(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Wolf wolf) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + if (event.getEntity().hasMetadata("VD_WOLF_PACK_MARKED")) { + Instant date = new Date(event.getEntity().getMetadata("VD_WOLF_PACK_MARKED").get(0).asLong()).toInstant(); + if (Duration.between(date, Instant.now()).abs().toSeconds() <= 5) { + event.setDamage(event.getDamage() + (event.getDamage() * 0.1)); + } else { + event.getEntity().removeMetadata("VD_WOLF_PACK_MARKED", plugin); + } + } + EntityUpgrade wolfPack = plugin.getEntityUpgradeManager().getUpgrade("WOLF_WOLF_PACK"); + if (wolf.hasMetadata(wolfPack.getMetadataKey())) { + event.getEntity().removeMetadata("VD_WOLF_PACK_MARKED", plugin); + event.getEntity().setMetadata("VD_WOLF_PACK_MARKED", new FixedMetadataValue(plugin, System.currentTimeMillis())); + } + } + } + + @EventHandler + public void onBloodyRevengeDeath(EntityDeathEvent event) { + if (!(event.getEntity() instanceof Wolf wolf)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + EntityUpgrade bloodyRevenge = plugin.getEntityUpgradeManager().getUpgrade("WOLF_BLOODY_REVENGE"); + for (Wolf arenaWolf : arena.getWolves()) { + if (!arenaWolf.hasMetadata(bloodyRevenge.getMetadataKey())) { + continue; + } + arenaWolf.setMetadata("VD_WOLF_BLOODY_REVENGE", new FixedMetadataValue(plugin, true)); + Bukkit.getScheduler().runTaskLater(plugin, () -> arenaWolf.removeMetadata("VD_WOLF_BLOODY_REVENGE", plugin), 20 * 5); + } + return; + } + } + + @EventHandler + public void onBloodyRevengeAttack(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Wolf wolf) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + if (!wolf.hasMetadata("VD_WOLF_BLOODY_REVENGE")) { + return; + } + double healAmount = event.getDamage() * 0.05; + wolf.setHealth(Math.min(wolf.getHealth() + healAmount, VersionUtils.getMaxHealth(wolf))); + event.setDamage(event.getDamage() + (event.getDamage() * 0.1)); + Vector velocity = event.getEntity().getLocation().getDirection().multiply(-1).normalize().multiply(0.3); + event.getEntity().setVelocity(velocity); + } + } + + @EventHandler + public void onRobber(EntityDeathEvent event) { + if (!(event.getEntity().getKiller() instanceof Wolf wolf)) { + return; + } + if (!wolf.hasMetadata("VD_OWNER_UUID")) { + return; + } + UUID playerId = UUID.fromString(wolf.getMetadata("VD_OWNER_UUID").get(0).asString()); + Player owner = Bukkit.getPlayer(playerId); + User user = plugin.getUserManager().getUser(owner); + if (user == null) { + return; + } + user.adjustStatistic(plugin.getStatsStorage().getStatisticType("ORBS"), ThreadLocalRandom.current().nextInt(4, 12)); + } + + @EventHandler + public void onWolfAlpha(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Wolf wolf)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + EntityUpgrade wolfAlpha = plugin.getEntityUpgradeManager().getUpgrade("WOLF_ALPHA"); + for (Entity entity : wolf.getNearbyEntities(6, 6, 6)) { + if (!(entity instanceof IronGolem golem)) { + continue; + } + if (golem.hasMetadata(wolfAlpha.getMetadataKey())) { + event.setDamage(event.getDamage() + (event.getDamage() * 0.1)); + } + } + return; + } + } + + @EventHandler + public void onMoreThanDeath(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Wolf wolf)) { + return; + } + if (wolf.hasMetadata("VD_WOLF_MORE_THAN_DEATH")) { + event.setDamage(0); + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getWolves().contains(wolf)) { + continue; + } + EntityUpgrade moreThanDeath = plugin.getEntityUpgradeManager().getUpgrade("WOLF_MORE_THAN_DEATH"); + if (!wolf.hasMetadata(moreThanDeath.getMetadataKey())) { + return; + } + if (event.getDamage() >= wolf.getHealth()) { + event.setDamage(0); + wolf.setMetadata("VD_WOLF_MORE_THAN_DEATH", new FixedMetadataValue(plugin, true)); + double defaultValue = wolf.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue(); + wolf.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(defaultValue + (defaultValue * 0.75)); + Bukkit.getScheduler().runTaskLater(plugin, () -> { + wolf.removeMetadata("VD_WOLF_MORE_THAN_DEATH", plugin); + wolf.damage(KitSpecifications.LETHAL_DAMAGE); + }, 20 * 5); + } + } + } + + @EventHandler + public void onIronWillDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade ironWill = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_IRON_WILL"); + if (!ironGolem.hasMetadata(ironWill.getMetadataKey())) { + return; + } + int defaultAmount = plugin.getConfig().getInt("Limit.Spawn.Villagers", 10); + int missing = defaultAmount - arena.getVillagers().size(); + event.setDamage(event.getDamage() + (event.getDamage() * (0.03 * missing))); + return; + } + } + + @EventHandler + public void onIronWillReceiveDamage(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof IronGolem ironGolem)) { + return; + } + for (Arena arena : plugin.getArenaRegistry().getPluginArenas()) { + if (!arena.getIronGolems().contains(ironGolem)) { + continue; + } + EntityUpgrade ironWill = plugin.getEntityUpgradeManager().getUpgrade("GOLEM_IRON_WILL"); + if (!ironGolem.hasMetadata(ironWill.getMetadataKey())) { + return; + } + int defaultAmount = plugin.getConfig().getInt("Limit.Spawn.Villagers", 10); + int missing = defaultAmount - arena.getVillagers().size(); + event.setDamage(event.getDamage() - (event.getDamage() * (0.03 * missing))); + return; + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgradeMenu.java b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgradeMenu.java deleted file mode 100644 index 4d259cb40..000000000 --- a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/EntityUpgradeMenu.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.handlers.upgrade; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; -import org.jetbrains.annotations.Nullable; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.user.User; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.minigamesbox.inventory.normal.NormalFastInv; -import plugily.projects.villagedefense.Main; -import plugily.projects.villagedefense.api.event.player.VillagePlayerEntityUpgradeEvent; -import plugily.projects.villagedefense.creatures.CreatureUtils; -import plugily.projects.villagedefense.events.EntityUpgradeListener; -import plugily.projects.villagedefense.handlers.upgrade.upgrades.Upgrade; -import plugily.projects.villagedefense.handlers.upgrade.upgrades.UpgradeBuilder; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * @author Plajer - *

- * Created at 18.06.2019 - */ -public class EntityUpgradeMenu { - - private final List upgrades = new ArrayList<>(); - private final Main plugin; - - public EntityUpgradeMenu(Main plugin) { - this.plugin = plugin; - new EntityUpgradeListener(this); - registerUpgrade(new UpgradeBuilder("Damage") - .entity(Upgrade.EntityType.BOTH).slot(2, 1).maxTier(4).metadata("VD_Damage") - //2.0 + (tier * 3) - .tierValue(0, 2.0).tierValue(1, 5.0).tierValue(2, 8.0).tierValue(3, 11.0).tierValue(4, 14.0) - .build()); - registerUpgrade(new UpgradeBuilder("Health") - .entity(Upgrade.EntityType.BOTH).slot(2, 2).maxTier(4).metadata("VD_Health") - //100.0 + (100.0 * (tier / 2.0)) - .tierValue(0, 100.0).tierValue(1, 150.0).tierValue(2, 200.0).tierValue(3, 250.0).tierValue(4, 300.0) - .build()); - registerUpgrade(new UpgradeBuilder("Speed") - .entity(Upgrade.EntityType.BOTH).slot(2, 3).maxTier(4).metadata("VD_Speed") - //0.25 + (0.25 * ((double) tier / 5.0)) - .tierValue(0, 0.25).tierValue(1, 0.3).tierValue(2, 0.35).tierValue(3, 0.4).tierValue(4, 0.45) - .build()); - registerUpgrade(new UpgradeBuilder("Swarm-Awareness") - .entity(Upgrade.EntityType.WOLF).slot(3, 4).maxTier(2).metadata("VD_SwarmAwareness") - //tier * 0.2 - .tierValue(0, 0).tierValue(1, 0.2).tierValue(2, 0.4) - .build()); - registerUpgrade(new UpgradeBuilder("Final-Defense") - .entity(Upgrade.EntityType.IRON_GOLEM).slot(3, 4).maxTier(2).metadata("VD_FinalDefense") - //tier * 5 - .tierValue(0, 0).tierValue(1, 5).tierValue(2, 10) - .build()); - } - - /** - * Registers new upgrade - * - * @param upgrade upgrade to registry - */ - public void registerUpgrade(Upgrade upgrade) { - upgrades.add(upgrade); - } - - @Nullable - public Upgrade getUpgrade(String id) { - for(Upgrade upgrade : upgrades) { - if(upgrade.getId().equals(id)) { - return upgrade; - } - } - return null; - } - - /** - * Opens menu with upgrades for wolf or golem - * - * @param livingEntity entity to check upgrades for - * @param player player who will see inventory - */ - public void openUpgradeMenu(LivingEntity livingEntity, Player player) { - NormalFastInv gui = new NormalFastInv(6 * 9, color("UPGRADE_MENU_TITLE")); - gui.addClickHandler(inventoryClickEvent -> inventoryClickEvent.setCancelled(true)); - User user = plugin.getUserManager().getUser(player); - - for(Upgrade upgrade : upgrades) { - if(upgrade.getApplicableFor() != Upgrade.EntityType.BOTH && !livingEntity.getType().toString().equals(upgrade.getApplicableFor().toString())) { - continue; - } - int x = upgrade.getSlotX(); - int y = upgrade.getSlotY(); - gui.setItem(x + y * 9, upgrade.asItemStack(getTier(livingEntity, upgrade)), event -> { - int nextTier = getTier(livingEntity, upgrade) + 1; - int cost = upgrade.getCost(nextTier); - if(nextTier > upgrade.getMaxTier()) { - player.sendMessage(color("UPGRADE_MENU_MAX_TIER")); - return; - } - - int orbs = user.getStatistic("ORBS"); - if(orbs < cost) { - player.sendMessage(color("UPGRADE_MENU_CANNOT_AFFORD")); - return; - } - - user.setStatistic("ORBS", orbs - cost); - player.sendMessage(color("UPGRADE_MENU_UPGRADED_ENTITY").replace("%tier%", Integer.toString(nextTier))); - applyUpgrade(livingEntity, upgrade); - - Bukkit.getPluginManager().callEvent(new VillagePlayerEntityUpgradeEvent(plugin.getArenaRegistry().getArena(player), livingEntity, player, upgrade, nextTier)); - player.closeInventory(); - openUpgradeMenu(livingEntity, player); - }); - for(int i = 0; i < upgrade.getMaxTier(); i++) { - if(i < getTier(livingEntity, upgrade)) { - gui.setItem((x + 1 + i) + y * 9, new ItemBuilder(XMaterial.YELLOW_STAINED_GLASS_PANE.parseItem()).name(" ").build()); - } else { - gui.setItem((x + 1 + i) + y * 9, new ItemBuilder(XMaterial.WHITE_STAINED_GLASS_PANE.parseItem()).name(" ").build()); - } - } - } - applyStatisticsBookOfEntityToGui(gui, livingEntity); - gui.open(player); - } - - private String color(String key) { - return new MessageBuilder(key).asKey().build(); - } - - private void applyStatisticsBookOfEntityToGui(NormalFastInv gui, LivingEntity livingEntity) { - String[] lore = color("UPGRADE_MENU_STATS_ITEM_DESCRIPTION").split(";"); - - for(int a = 0; a < lore.length; a++) { - Upgrade speed = getUpgrade("Speed"); - Upgrade damage = getUpgrade("Damage"); - Upgrade health = getUpgrade("Health"); - - lore[a] = lore[a].replace("%speed%", Double.toString(speed.getValueForTier(getTier(livingEntity, speed)))) - .replace("%damage%", Double.toString(damage.getValueForTier(getTier(livingEntity, damage)))) - .replace("%max_hp%", Double.toString(health.getValueForTier(getTier(livingEntity, health)))) - .replace("%current_hp%", Double.toString(livingEntity.getHealth())); - } - - gui.setItem(4, new ItemBuilder(new ItemStack(Material.BOOK)) - .name(color("UPGRADE_MENU_STATS_ITEM_NAME")) - .lore(lore) - .build()); - } - - /** - * Applies upgrade for target entity - * automatically increments current tier - * - * @param entity target entity - * @param upgrade upgrade to apply - * @return true if applied successfully, false if tier is max and cannot be applied more - */ - public boolean applyUpgrade(Entity entity, Upgrade upgrade) { - List meta = entity.getMetadata(upgrade.getMetadataAccessor()); - - if(meta.isEmpty()) { - entity.setMetadata(upgrade.getMetadataAccessor(), new FixedMetadataValue(plugin, 1)); - applyUpgradeEffect(entity, upgrade, 1); - return true; - } - - if(meta.get(0).asInt() == upgrade.getMaxTier()) { - return false; - } - - int tier = getTier(entity, upgrade) + 1; - entity.setMetadata(upgrade.getMetadataAccessor(), new FixedMetadataValue(plugin, tier)); - applyUpgradeEffect(entity, upgrade, tier); - if(upgrade.getMaxTier() == tier) { - VersionUtils.playSound(entity.getLocation(), "BLOCK_ANVIL_USE"); - VersionUtils.sendParticles("EXPLOSION_LARGE", (Set) null, entity.getLocation(), 5); - } - return true; - } - - private void applyUpgradeEffect(Entity entity, Upgrade upgrade, int tier) { - org.bukkit.Location entityLocation = entity.getLocation(); - - VersionUtils.sendParticles("FIREWORKS_SPARK", null, entityLocation.add(0, 1, 0), 30, 0.7, 0.7, 0.7); - VersionUtils.sendParticles("HEART", (Set) null, entityLocation.add(0, 1.6, 0), 5); - VersionUtils.playSound(entityLocation, "ENTITY_PLAYER_LEVELUP"); - - int[] baseValues = new int[]{getTier(entity, getUpgrade("Health")), getTier(entity, getUpgrade("Speed")), getTier(entity, getUpgrade("Damage"))}; - - if(areAllEqualOrHigher(baseValues) && getMinValue(baseValues) == 4) { - //final mode! rage!!! - VersionUtils.setGlowing(entity, true); - } - - switch(upgrade.getId()) { - case "Damage": - if(entity.getType() == EntityType.WOLF) { - CreatureUtils.getCreatureInitializer().applyDamageModifier((LivingEntity) entity, 2.0 + (tier * 3)); - } - //attribute damage doesn't exist for golems - break; - case "Health": - LivingEntity living = (LivingEntity) entity; - - VersionUtils.setMaxHealth(living, 100.0 + (100.0 * (tier / 2.0))); - living.setHealth(VersionUtils.getMaxHealth(living)); - break; - case "Speed": - CreatureUtils.getCreatureInitializer().applySpeedModifier((LivingEntity) entity, 0.25 + (0.25 * (tier / 5.0))); - break; - case "Swarm-Awareness": - case "Final-Defense": - //do nothing they are used within events - break; - default: - break; - } - } - - public List getUpgrades() { - return upgrades; - } - - private boolean areAllEqualOrHigher(int[] numbers) { - for(int i = 1; i < numbers.length; i++) { - if(numbers[0] < numbers[i]) { - return false; - } - } - return true; - } - - private int getMinValue(int[] numbers) { - int minValue = numbers[0]; - for(int i = 1; i < numbers.length; i++) { - if(numbers[i] < minValue) { - minValue = numbers[i]; - } - } - return minValue; - } - - /** - * @param entity entity to check - * @param upgrade upgrade type - * @return current tier of upgrade for target entity - */ - public int getTier(Entity entity, Upgrade upgrade) { - List meta = entity.getMetadata(upgrade.getMetadataAccessor()); - return meta.isEmpty() ? 0 : meta.get(0).asInt(); - } - - public Main getPlugin() { - return plugin; - } -} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/NewEntityUpgradeManager.java b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/NewEntityUpgradeManager.java new file mode 100644 index 000000000..b58e0c560 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/NewEntityUpgradeManager.java @@ -0,0 +1,652 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.handlers.upgrade; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Golem; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.jetbrains.annotations.Nullable; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.inventory.normal.NormalFastInv; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.ArenaManager; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.PetsFriend; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class NewEntityUpgradeManager { + + public static final String UPGRADES_DISABLED_METADATA = "VD_UPGRADES_DISABLED"; + + private final List registeredUpgrades = new ArrayList<>(); + private final Main plugin; + + public NewEntityUpgradeManager(Main plugin) { + this.plugin = plugin; + registerUpgrades(); + } + + private void registerUpgrades() { + registerGolemUpgrades(); + registerWolfUpgrades(); + } + + private void registerGolemUpgrades() { + for (int i = 0; i < 3; i++) { + EntityUpgrade.Builder builder = new EntityUpgrade.Builder() + .withId("GOLEM_HEALTH_AND_REGEN_" + (i + 1)) + .withName(color("&a&lHEALTH AND REGEN " + toRoman(i + 1))) + .withDescription(listFromStrings( + color("&aUpgrade Max Health to &e&l" + (200 * (i + 1)) + " HP"), + color("&aand Per Wave Regeneration to &e&l" + (2 * (i + 1)) + " HP"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(10 + i) + .putUpgradeData("max_hp", 200 * (i + 1)) + .putUpgradeData("regen", 2 * (i + 1)) + .withCost(150 * (i + 1)); + if (i > 0) { + builder = builder.andDependsOn("GOLEM_HEALTH_AND_REGEN_" + i); + } + registeredUpgrades.add(builder.build()); + } + for (int i = 0; i < 3; i++) { + EntityUpgrade.Builder builder = new EntityUpgrade.Builder() + .withId("GOLEM_DAMAGE_AND_SPEED_" + (i + 1)) + .withName(color("&a&lDAMAGE AND SPEED " + toRoman(i + 1))) + .withDescription(listFromStrings( + color("&aIncrease Damage by &e&l" + (3 + (i * 3)) + " DMG"), + color("&aand Movement Speed by &e&l" + (0.25 + (i * 0.05)) + " MS"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(14 + i) + .putUpgradeData("damage", 3 + (i * 3)) + .putUpgradeData("movement_speed", 0.25 + (i * 0.05)) + .withCost(150 * (i + 1)); + if (i > 0) { + builder = builder.andDependsOn("GOLEM_DAMAGE_AND_SPEED_" + i); + } + registeredUpgrades.add(builder.build()); + } + for (int i = 0; i < 2; i++) { + EntityUpgrade.Builder builder = new EntityUpgrade.Builder() + .withId("GOLEM_UNSTOPPABLE_STREAK_" + (i + 1)) + .withName(color("&6&lUNSTOPPABLE STREAK " + toRoman(i + 1))) + .withDescription(listFromStrings( + color("&aEvery kill increases damage"), + color("&aby &e&l" + (5 + (i * 5)) + "%&a for five seconds"), + color("&aand consecutive kills reset the timer"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(28 + i) + .putUpgradeData("increase", 5 + (i * 5)) + .withCost(200 * (i + 1)); + if (i > 0) { + builder = builder.andDependsOn("GOLEM_UNSTOPPABLE_STREAK_" + i); + } + registeredUpgrades.add(builder.build()); + } + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("GOLEM_FINAL_DEFENSE") + .withName(color("&6&lFINAL DEFENSE")) + .withDescription(listFromStrings( + color("&aOn death &e&lLETHALLY DAMAGE"), + color("&aenemies within six blocks and &e&lPERMA"), + color("&e&lSLOW&a all enemies within nine blocks"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(32) + .withCost(250) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("GOLEM_TOUGHENING") + .withName(color("&6&lTOUGHENING")) + .withDescription(listFromStrings( + color("&aReceive &e&l25% LESS DMG&a while"), + color("&abelow 40% HP and receive &e&l30% LESS DMG"), + color("&afrom explosion if recently damaged"), + color("&aby an explosion within eight seconds"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(33) + .withCost(300) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("GOLEM_IRON_WILL") + .withName(color("&e&l★ &6&lIRON WILL")) + .withDescription(listFromStrings( + color("&aIncrease &e&lDAMAGE and ARMOR"), + color("&aby &e&l3%&a for every one"), + color("&avillager killed in game"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8(★ Special upgrade)"), + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(34) + .withCost(300) + .isSpecial() + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("GOLEM_SURVIVOR") + .withName(color("&b&lWILL TO SURVIVE")) + .withDescription(listFromStrings( + color("&aReceive &e&l5% LIFESTEAL&a and"), + color("&e&l10% MAX HEALTH REGEN&a every wave"), + color("&aUnlocked for surviving three"), + color("&aand more waves in game"), + "", + color("&8(Survivor upgrade)") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(48) + .isHidden(3) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("GOLEM_BANNER_OF_COMMAND") + .withName(color("&b&lBANNER OF COMMAND")) + .withDescription(listFromStrings( + color("&aInspire nearby Iron Golems"), + color("&awith &e&l10% BONUS DMG"), + color("&awithin six blocks radius"), + color("&aUnlocked for surviving five"), + color("&aand more waves in game"), + "", + color("&8(Survivor upgrade)") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(49) + .isHidden(5) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("GOLEM_LAMENT") + .withName(color("&b&lREMEMBRANCE LAMENT")) + .withDescription(listFromStrings( + color("&aOn death &e&lKILL EVERY"), + color("&aalive enemy and &e&lHEAL&a every"), + color("&aalive ally (villager, pet & player)"), + color("&ato 100% HP as a final gift"), + color("&aUnlocked for surviving seven"), + color("&aand more waves in game"), + "", + color("&8(Survivor upgrade)") + )) + .withApplicableEntity(EntityType.IRON_GOLEM) + .atSlot(50) + .isHidden(7) + .build()); + } + + private void registerWolfUpgrades() { + for (int i = 0; i < 3; i++) { + EntityUpgrade.Builder builder = new EntityUpgrade.Builder() + .withId("WOLF_HEALTH_AND_REGEN_" + (i + 1)) + .withName(color("&a&lHEALTH AND REGEN " + toRoman(i + 1))) + .withDescription(listFromStrings( + color("&aUpgrade Max Health to &e&l" + (125 * (i + 1)) + " HP"), + color("&aand Per Wave Regeneration to &e&l" + (1.5 * (i + 1)) + " HP"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(10 + i) + .putUpgradeData("max_hp", 125 * (i + 1)) + .putUpgradeData("regen", 1.5 * (i + 1)) + .withCost(150 * (i + 1)); + if (i > 0) { + builder = builder.andDependsOn("WOLF_HEALTH_AND_REGEN_" + i); + } + registeredUpgrades.add(builder.build()); + } + for (int i = 0; i < 3; i++) { + EntityUpgrade.Builder builder = new EntityUpgrade.Builder() + .withId("WOLF_DAMAGE_AND_SPEED_" + (i + 1)) + .withName(color("&a&lDAMAGE AND SPEED " + toRoman(i + 1))) + .withDescription(listFromStrings( + color("&aIncrease Damage by &e&l" + (2 + (i * 2)) + " DMG"), + color("&aand Movement Speed by &e&l" + (0.25 + (i * 0.05)) + " MS"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(14 + i) + .putUpgradeData("damage", 2 + (i * 2)) + .putUpgradeData("movement_speed", 0.25 + (i * 0.05)) + .withCost(150 * (i + 1)); + if (i > 0) { + builder = builder.andDependsOn("WOLF_DAMAGE_AND_SPEED_" + i); + } + registeredUpgrades.add(builder.build()); + } + for (int i = 0; i < 2; i++) { + EntityUpgrade.Builder builder = new EntityUpgrade.Builder() + .withId("WOLF_SWARM_AWARENESS_" + (i + 1)) + .withName(color("&6&lSWARM AWARENESS " + toRoman(i + 1))) + .withDescription(listFromStrings( + color("&aWolf deals &e&l" + (3 + (i * 2)) + "% BONUS DMG&a per"), + color("&awolf nearby within three blocks"), + color("&aradius capped at 30% BONUS DMG"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(28 + i) + .putUpgradeData("increase", 3 + (i * 2)) + .withCost(200 * (i + 1)); + if (i > 0) { + builder = builder.andDependsOn("WOLF_SWARM_AWARENESS_" + i); + } + registeredUpgrades.add(builder.build()); + } + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("WOLF_BLOODY_REVENGE") + .withName(color("&6&lBLOODY REVENGE")) + .withDescription(listFromStrings( + color("&aOn ally wolf death &e&lENRAGE"), + color("&athe wolf to receive &e&l5% LIFESTEAL"), + color("&e&l10% BONUS DAMAGE&a and &e&lKNOCKBACK"), + color("&afor five seconds"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(32) + .withCost(250) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("WOLF_WOLF_PACK") + .withName(color("&6&lWOLF PACK")) + .withDescription(listFromStrings( + color("&aAttacking an enemy &e&lINCREASES"), + color("&e&lDAMAGE&a dealt by other wolves"), + color("&aby &e&l10% DMG&a for five seconds"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(33) + .withCost(300) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("WOLF_DEEP_WOUNDS") + .withName(color("&e&l★ &6&lDEEP WOUNDS")) + .withDescription(listFromStrings( + color("&aReceive &e&l25% CHANCE&a when"), + color("&aattacking an enemy to apply"), + color("&e&lBLEEDING&a for three seconds"), + color("&e&lCOST:&a %cost_value% orbs"), + "", + color("&8(★ Special upgrade)"), + color("&8Click to purchase") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(34) + .withCost(300) + .isSpecial() + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("WOLF_ROBBER") + .withName(color("&b&lROBBER")) + .withDescription(listFromStrings( + color("&aGenerate &e&l4-12 BONUS ORBS"), + color("&ato owner for every enemy killed"), + color("&aUnlocked for surviving three"), + color("&aand more waves in game"), + "", + color("&8(Survivor upgrade)") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(48) + .isHidden(3) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("WOLF_ALPHA") + .withName(color("&b&lALPHA WOLF")) + .withDescription(listFromStrings( + color("&aInspire nearby Wolves"), + color("&awith &e&l10% BONUS DMG"), + color("&awithin six blocks radius"), + color("&aUnlocked for surviving five"), + color("&aand more waves in game"), + "", + color("&8(Survivor upgrade)") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(49) + .isHidden(5) + .build()); + registeredUpgrades.add(new EntityUpgrade.Builder() + .withId("WOLF_MORE_THAN_DEATH") + .withName(color("&b&lMORE THAN DEATH")) + .withDescription(listFromStrings( + color("&aUpon receiving fatal damage"), + color("&abe &e&lUNKILLABLE&a and receive"), + color("&e&l75% BONUS DMG&a for five seconds"), + color("&athen perish into the shadows"), + color("&aUnlocked for surviving seven"), + color("&aand more waves in game"), + "", + color("&8(Survivor upgrade)") + )) + .withApplicableEntity(EntityType.WOLF) + .atSlot(50) + .isHidden(7) + .build()); + } + + private List listFromStrings(String... lines) { + return new ArrayList<>(Arrays.asList(lines)); + } + + public List getRegisteredUpgrades() { + return registeredUpgrades; + } + + @Nullable + public EntityUpgrade getUpgrade(String id) { + for (EntityUpgrade upgrade : registeredUpgrades) { + if (upgrade.getId().equals(id)) { + return upgrade; + } + } + return null; + } + + /** + * Opens menu with upgrades for wolf or golem + * + * @param livingEntity entity to check upgrades for + * @param player player who will see inventory + */ + public void openUpgradeMenu(LivingEntity livingEntity, Player player) { + NormalFastInv gui = new NormalFastInv(6 * 9, color("&e&lENTITY UPGRADES")); + gui.addClickHandler(inventoryClickEvent -> inventoryClickEvent.setCancelled(true)); + User user = plugin.getUserManager().getUser(player); + + for (EntityUpgrade upgrade : registeredUpgrades) { + if (!upgrade.getApplicableEntity().equals(livingEntity.getType())) { + continue; + } + if (upgrade.isSpecial() && !(user.getKit() instanceof PetsFriend)) { + continue; + } + gui.setItem(upgrade.getSlot(), upgradeAsItem(livingEntity, upgrade), event -> { + event.setCancelled(true); + if (upgrade.isHidden()) { + player.playSound(player, Sound.ENTITY_VILLAGER_NO, 1, 1); + return; + } + if (livingEntity.hasMetadata(upgrade.getMetadataKey())) { + player.playSound(player, Sound.ENTITY_VILLAGER_NO, 1, 1); + return; + } + if (upgrade.getDependsOn() != null && !livingEntity.hasMetadata(upgrade.getDependencyMetadataKey())) { + player.playSound(player, Sound.ENTITY_VILLAGER_NO, 1, 1); + return; + } + int orbs = user.getStatistic("ORBS"); + if (orbs < upgrade.getCost()) { + new MessageBuilder("UPGRADE_MENU_CANNOT_AFFORD").asKey().player(player).sendPlayer(); + player.playSound(player, Sound.ENTITY_VILLAGER_NO, 1, 1); + return; + } + user.setStatistic("ORBS", orbs - upgrade.getCost()); + player.sendMessage(color("&aSuccessfully upgraded entity!")); + user.getArena().changeArenaOptionBy("TOTAL_ORBS_SPENT", orbs); + applyUpgradeWithVisuals(livingEntity, player, upgrade); + + openUpgradeMenu(livingEntity, player); + }); + applyStatisticsBookOfEntityToGui(gui, livingEntity); + } + gui.open(player); + } + + private void applyStatisticsBookOfEntityToGui(NormalFastInv gui, LivingEntity entity) { + List lore = new ArrayList<>(); + double healPower = ArenaManager.DEFAULT_PET_HEAL_POWER; + double defaultHeal = entity instanceof IronGolem ? 2.0 : 1.0; + String prefix = entity instanceof IronGolem ? "GOLEM_" : "WOLF_"; + for (int i = 3; i > 0; i--) { + EntityUpgrade heal = plugin.getEntityUpgradeManager().getUpgrade(prefix + "HEALTH_AND_REGEN_" + i); + if (entity.hasMetadata(heal.getMetadataKey())) { + defaultHeal += heal.getUpgradeData().getOrDefault("regen", 0.0); + break; + } + } + healPower = healPower * defaultHeal; + lore.add("&a&lHEALTH: &7" + entity.getHealth() + "/" + VersionUtils.getMaxHealth(entity) + " (&a&lREGEN &7" + healPower + " HP/wave)"); + lore.add("&a&lDAMAGE: &7" + entity.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue() + " DMG"); + lore.add("&a&lMOVEMENT SPEED: &7" + entity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).getBaseValue() + " MS"); + int totalKills = 0; + if (entity.hasMetadata("VD_ENTITY_KILLS")) { + totalKills = entity.getMetadata("VD_ENTITY_KILLS").get(0).asInt(); + } + lore.add("&a&lKILLS: &7" + totalKills); + gui.setItem(4, new ItemBuilder(new ItemStack(Material.BOOK)) + .name(color("&e&lCURRENT STATISTICS")) + .lore( + lore.stream() + .map(this::color) + .collect(Collectors.toList()) + ) + .build()); + } + + private ItemStack upgradeAsItem(LivingEntity entity, EntityUpgrade upgrade) { + Material icon; + String name = upgrade.getName(); + List lore = upgrade.getDescription(); + if (entity.hasMetadata(upgrade.getMetadataKey())) { + icon = Material.LIME_DYE; + name = color("&a&l✓ ") + name; + } else { + if (upgrade.isHidden()) { + icon = Material.MAGENTA_DYE; + name = color("&c&lSECRET UPGRADE"); + lore = listFromStrings( + color("&aThis upgrade will be"), + color("&aautomatically unlocked when"), + color("&aentity survives " + upgrade.getSurviveWaves() + " waves") + ); + } else { + icon = Material.GRAY_DYE; + name = color("&c&l✘ ") + name; + } + } + lore = lore.stream() + .map(line -> line.replace("%cost_value%", String.valueOf(upgrade.getCost()))) + .collect(Collectors.toList()); + return new ItemBuilder(icon) + .name(name) + .lore(lore) + .build(); + } + + private String toRoman(int number) { + return switch (number) { + case 1 -> "I"; + case 2 -> "II"; + case 3 -> "III"; + default -> "?"; + }; + } + + private String color(String text) { + return ChatColor.translateAlternateColorCodes('&', text); + } + + public boolean applyUpgradeSilent(Entity entity, Player player, EntityUpgrade upgrade) { + List meta = entity.getMetadata(upgrade.getMetadataKey()); + + if (!meta.isEmpty()) { + return false; + } + entity.setMetadata(upgrade.getMetadataKey(), new FixedMetadataValue(plugin, true)); + applyUpgradeEffect(entity, player, upgrade, true); + applyUpgradeOnEntity(entity, upgrade); + return true; + } + + /** + * Applies upgrade for target entity + * + * @param entity target entity + * @param player player which upgraded target + * @param upgrade upgrade to apply + * @return true if applied successfully, false if cannot be applied + */ + public boolean applyUpgradeWithVisuals(Entity entity, Player player, EntityUpgrade upgrade) { + List meta = entity.getMetadata(upgrade.getMetadataKey()); + + if (!meta.isEmpty()) { + return false; + } + entity.setMetadata(upgrade.getMetadataKey(), new FixedMetadataValue(plugin, true)); + applyUpgradeEffect(entity, player, upgrade, false); + applyUpgradeOnEntity(entity, upgrade); + return true; + } + + private void applyUpgradeEffect(Entity entity, Player player, EntityUpgrade upgrade, boolean silent) { + if (!silent) { + applyParticlesAndSounds(entity, upgrade); + } + int totalLevel = 0; + for (EntityUpgrade entityUpgrade : registeredUpgrades) { + if (entityUpgrade.getApplicableEntity() == entity.getType() && entity.hasMetadata(entityUpgrade.getMetadataKey())) { + totalLevel++; + } + } + if (entity instanceof Golem) { + entity.setCustomName(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_GOLEM_NAME").asKey().integer(totalLevel).player(player).build()); + } else if (entity instanceof Wolf) { + entity.setCustomName(new MessageBuilder("IN_GAME_MESSAGES_VILLAGE_WAVE_ENTITIES_WOLF_NAME").asKey().integer(totalLevel).player(player).build()); + } + User user = plugin.getUserManager().getUser(player); + ChatColor targetColor = null; + if (totalLevel >= 13) { + targetColor = ChatColor.RED; + } else if (totalLevel == 12) { + targetColor = ChatColor.GOLD; + } else if (totalLevel == 11) { + targetColor = ChatColor.YELLOW; + } else if (totalLevel == 10) { + targetColor = ChatColor.WHITE; + } + if (targetColor != null) { + try { + for (Player arenaPlayer : user.getArena().getPlayers()) { + plugin.getGlowingEntities().setGlowing(entity, arenaPlayer, ChatColor.GOLD); + } + } catch (Exception ignored) { + } + } + } + + private void applyUpgradeOnEntity(Entity entity, EntityUpgrade upgrade) { + LivingEntity living = (LivingEntity) entity; + if (upgrade.getId().contains("HEALTH_AND_REGEN")) { + VersionUtils.setMaxHealth(living, upgrade.getUpgradeData().get("max_hp")); + living.setHealth(VersionUtils.getMaxHealth(living)); + } else if (upgrade.getId().contains("DAMAGE_AND_SPEED")) { + double baseDamage = living.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).getBaseValue(); + CreatureUtils.getCreatureInitializer().applyDamageModifier((LivingEntity) entity, baseDamage + upgrade.getUpgradeData().get("damage")); + CreatureUtils.getCreatureInitializer().applySpeedModifier((LivingEntity) entity, upgrade.getUpgradeData().get("movement_speed")); + } + } + + private void applyParticlesAndSounds(Entity entity, EntityUpgrade upgrade) { + Location targetLocation = entity.getLocation().clone(); + if (entity instanceof IronGolem) { + targetLocation = targetLocation.add(0, 1.6, 0); + } else { + targetLocation = targetLocation.add(0, 0.75, 0); + } + if (upgrade.getId().contains("HEALTH_AND_REGEN")) { + VersionUtils.sendParticles("HEART", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("DAMAGE_AND_SPEED")) { + VersionUtils.sendParticles("CRIT", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("UNSTOPPABLE_STREAK")) { + VersionUtils.sendParticles("EXPLOSION_LARGE", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("FINAL_DEFENSE") || upgrade.getId().contains("LAMENT")) { + VersionUtils.sendParticles("DAMAGE_INDICATOR", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("SURVIVOR") || upgrade.getId().contains("TOUGHENING")) { + VersionUtils.sendParticles("DRIP_LAVA", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("BANNER_OF_COMMAND") || upgrade.getId().contains("ALPHA")) { + VersionUtils.sendParticles("ENCHANTMENT_TABLE", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("SWARM_AWARENESS")) { + VersionUtils.sendParticles("SOUL", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("BLOODY_REVENGE") || upgrade.getId().contains("PACK")) { + VersionUtils.sendParticles("VILLAGER_ANGRY", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("DEEP_WOUNDS") || upgrade.getId().contains("MORE_THAN_DEATH")) { + VersionUtils.sendParticles("GLOW", null, targetLocation, 15, 0.7, 0.7, 0.7); + } else if (upgrade.getId().contains("ROBBER")) { + VersionUtils.sendParticles("SNEEZE", null, targetLocation, 15, 0.7, 0.7, 0.7); + } + if (upgrade.isHidden()) { + targetLocation.getWorld().playSound(targetLocation, Sound.ENTITY_PLAYER_LEVELUP, 1, 0.25f); + } else if (upgrade.isSpecial()) { + targetLocation.getWorld().playSound(targetLocation, Sound.ENTITY_PLAYER_LEVELUP, 1, 0.5f); + } else { + targetLocation.getWorld().playSound(targetLocation, Sound.ENTITY_PLAYER_LEVELUP, 1, 0.5f); + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/upgrades/Upgrade.java b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/upgrades/Upgrade.java deleted file mode 100644 index 03451a82f..000000000 --- a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/upgrades/Upgrade.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.handlers.upgrade.upgrades; - -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.Main; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Plajer - *

- * Created at 18.06.2019 - */ -public class Upgrade { - - private static Main plugin; - private final String id; - private int slotX; - private int slotY; - private EntityType entityType; - private int maxTier; - private String name; - private List description = new ArrayList<>(); - private String metadataAccessor; - private final String configAccessor; - private final Map tieredValues = new HashMap<>(); - - public Upgrade(String id) { - this.id = id; - configAccessor = "Entity-Upgrades." + id + "-Tiers"; - } - - public static void init(Main plugin) { - Upgrade.plugin = plugin; - } - - public void setEntityType(EntityType entityType) { - this.entityType = entityType; - } - - public void setTierValue(int tier, double value) { - tieredValues.put(tier, value); - } - - public String getId() { - return id; - } - - public int getSlotX() { - return slotX; - } - - public int getSlotY() { - return slotY; - } - - public void setSlot(int x, int y) { - slotX = x; - slotY = y; - } - - public EntityType getApplicableFor() { - return entityType; - } - - public int getMaxTier() { - return maxTier; - } - - public void setMaxTier(int maxTier) { - this.maxTier = maxTier; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public List getDescription() { - return description; - } - - public void setDescription(List description) { - this.description = description; - } - - public String getMetadataAccessor() { - return metadataAccessor; - } - - public void setMetadataAccessor(String metadataAccessor) { - this.metadataAccessor = metadataAccessor; - } - - public double getValueForTier(int tier) { - return tieredValues.getOrDefault(tier, tieredValues.get(maxTier)); - } - - public int getCost(int tier) { - return plugin.getEntityUpgradesConfig().getInt(configAccessor + "." + tier); - } - - public ItemStack asItemStack(int currentTier) { - double valCurrent = tieredValues.get(currentTier); - int nextTier = currentTier + 1; - double valNext = tieredValues.getOrDefault(nextTier, valCurrent); - return new ItemBuilder(XMaterial.BLACK_STAINED_GLASS_PANE.parseItem()) - .name(getName()) - .lore(getDescription().stream().map(lore -> lore = new MessageBuilder(lore).build() - .replace("%cost%", Integer.toString(getCost(nextTier))) - .replace("%tier%", Integer.toString(nextTier)) - .replace("%from%", Double.toString(valCurrent)) - .replace("%to%", Double.toString(valNext))).collect(Collectors.toList())).build(); - } - - public enum EntityType { - BOTH, IRON_GOLEM, WOLF - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/upgrades/UpgradeBuilder.java b/src/main/java/plugily/projects/villagedefense/handlers/upgrade/upgrades/UpgradeBuilder.java deleted file mode 100644 index 8f2459d69..000000000 --- a/src/main/java/plugily/projects/villagedefense/handlers/upgrade/upgrades/UpgradeBuilder.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.handlers.upgrade.upgrades; - -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.villagedefense.Main; - -import java.util.Arrays; -import java.util.List; - -/** - * @author Plajer - *

- * Created at 18.06.2019 - */ -public class UpgradeBuilder { - - private static Main plugin; - private final Upgrade upgrade; - - public UpgradeBuilder(String id) { - upgrade = new Upgrade(id); - upgrade.setName(new MessageBuilder(plugin.getLanguageConfig().getString("Upgrade-Menu.Upgrades." + id + ".Name")).build()); - upgrade.setDescription(Arrays.asList(new MessageBuilder(plugin.getLanguageConfig().getString("Upgrade-Menu.Upgrades." + id + ".Description")).build().split(";"))); - } - - public static void init(Main plugin) { - UpgradeBuilder.plugin = plugin; - } - - //for other usages - public UpgradeBuilder name(String name) { - upgrade.setName(new MessageBuilder(name).build()); - return this; - } - - //for other usages - public UpgradeBuilder lore(List lore) { - upgrade.setDescription(lore); - return this; - } - - public UpgradeBuilder slot(int x, int y) { - upgrade.setSlot(x, y); - return this; - } - - public UpgradeBuilder entity(Upgrade.EntityType type) { - upgrade.setEntityType(type); - return this; - } - - public UpgradeBuilder maxTier(int maxTier) { - upgrade.setMaxTier(maxTier); - return this; - } - - public UpgradeBuilder metadata(String metaAccessor) { - upgrade.setMetadataAccessor(metaAccessor); - return this; - } - - public UpgradeBuilder tierValue(int tier, double val) { - upgrade.setTierValue(tier, val); - return this; - } - - public Upgrade build() { - return upgrade; - } - -} \ No newline at end of file diff --git a/src/main/java/plugily/projects/villagedefense/kits/BuilderKit.java b/src/main/java/plugily/projects/villagedefense/kits/BuilderKit.java new file mode 100644 index 000000000..6f349e11d --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/BuilderKit.java @@ -0,0 +1,385 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.MaterialUtils; +import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; +import plugily.projects.villagedefense.utils.ProtocolUtils; +import plugily.projects.villagedefense.utils.Utils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Plajer + *

+ * Created at 11.08.2023 + */ +public class BuilderKit extends PremiumKit implements AbilitySource, Listener { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_BUILDER_"; + private final Map knockbackResistantArenas = new HashMap<>(); + + public BuilderKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Builder"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Builder.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Builder.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_NAME", new Message("Kit.Content.Builder.Game-Item.Fence.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_DESCRIPTION", new Message("Kit.Content.Builder.Game-Item.Fence.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_NAME", new Message("Kit.Content.Builder.Game-Item.Door.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_DESCRIPTION", new Message("Kit.Content.Builder.Game-Item.Door.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_NAME", new Message("Kit.Content.Builder.Game-Item.Earthed.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_DESCRIPTION", new Message("Kit.Content.Builder.Game-Item.Earthed.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_ACTIVATE", new Message("Kit.Content.Builder.Game-Item.Earthed.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_ACTIVE_ACTION_BAR", new Message("Kit.Content.Builder.Game-Item.Earthed.Active-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_PROTECTED_BY_ACTION_BAR", new Message("Kit.Content.Builder.Game-Item.Earthed.Knock-Protected-By-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_NAME", new Message("Kit.Content.Builder.Game-Item.Blockage.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_DESCRIPTION", new Message("Kit.Content.Builder.Game-Item.Blockage.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_ACTIVATE", new Message("Kit.Content.Builder.Game-Item.Blockage.Activate", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.builder"); + } + + @Override + public void giveKitItems(Player player) { + ArmorHelper.setColouredArmor(Color.RED, player); + player.getInventory().addItem(WeaponHelper.getEnchanted(new ItemStack(Material.STONE_SWORD), new org.bukkit.enchantments.Enchantment[]{org.bukkit.enchantments.Enchantment.DURABILITY}, new int[]{10})); + + player.getInventory().setItem(2, new ItemBuilder(new ItemStack(XMaterial.OAK_FENCE.parseMaterial(), 3)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_DESCRIPTION")) + .build()); + player.getInventory().setItem(3, new ItemBuilder(new ItemStack(getMaterial(), 2)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_DESCRIPTION")) + .build()); + player.getInventory().setItem(4, new ItemBuilder(XMaterial.CLAY_BALL.parseMaterial()) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_DESCRIPTION")) + .build()); + player.getInventory().setItem(5, new ItemBuilder(XMaterial.IRON_BARS.parseMaterial()) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_DESCRIPTION")) + .build()); + player.getInventory().setItem(6, new ItemStack(Material.SADDLE)); + player.getInventory().setItem(8, new ItemStack(Material.COOKED_BEEF, 10)); + } + + @Override + public Material getMaterial() { + return Utils.getCachedDoor(null); + } + + @Override + public void reStock(Player player) { + Arena arena = (Arena) getPlugin().getUserManager().getUser(player).getArena(); + int fences = (int) Settings.PASSIVE_FENCE_COUNT.getForArenaState(arena); + player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.OAK_FENCE.parseMaterial(), fences)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_DESCRIPTION")) + .build()); + if (arena.getWave() % (int) Settings.PASSIVE_DOOR_MODULO.getForArenaState(arena) == 0) { + player.getInventory().addItem(new ItemBuilder(new ItemStack(getMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_DESCRIPTION")) + .build()); + } + if (arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_PASSIVE_POWER_INCREASED").asKey().send(player); + } else if (arena.getWave() == KitSpecifications.GameTimeState.LATE.getStartWave()) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_PASSIVE_POWER_INCREASED").asKey().send(player); + } + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if (!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), BuilderKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if (displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_NAME").asKey().build())) { + onEarthedCast(stack, user); + } else if (displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_NAME").asKey().build())) { + onBlockageCast(stack, user); + } else if (displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FENCE_NAME").asKey().build())) { + onBarrierPlace(stack, user); + } + } + + private void onEarthedCast(ItemStack stack, User user) { + if (!user.checkCanCastCooldownAndMessage("builder_earthed")) { + return; + } + int cooldown = 20; + user.setCooldown("builder_earthed", cooldown); + int castTime = 10; + user.setCooldown("builder_earthed_running", castTime); + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_ACTIVATE").asKey().send(user.getPlayer()); + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_ACTIVE_ACTION_BAR"); + List buffMessages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_EARTHED_PROTECTED_BY_ACTION_BAR"); + Arena arena = (Arena) user.getArena(); + knockbackResistantArenas.put(arena, user.getPlayer()); + new BukkitRunnable() { + int tick = 0; + int messageIndex = 0; + int buffMessageIndex = 0; + + @Override + public void run() { + if (tick % 10 == 0) { + for (Player player : arena.getPlayersLeft()) { + VersionUtils.sendParticles("CRIT_MAGIC", null, player.getLocation(), 5, 0, 0, 0); + VersionUtils.sendActionBar(player, buffMessages.get(buffMessageIndex) + .replace("%player%", user.getPlayer().getName())); + } + VersionUtils.sendActionBar(user.getPlayer(), messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("builder_earthed_running")))); + messageIndex++; + buffMessageIndex++; + if (messageIndex > messages.size() - 1) { + messageIndex = 0; + } + if (buffMessageIndex > buffMessages.size() - 1) { + buffMessageIndex = 0; + } + } + if (tick >= 20 * castTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(user.getPlayer(), ""); + cancel(); + knockbackResistantArenas.remove(arena); + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private void onBlockageCast(ItemStack stack, User user) { + if (!user.checkCanCastCooldownAndMessage("builder_blockage")) { + return; + } + if (KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = (int) Settings.ABILITY_BLOCKAGE_COOLDOWN.getForArenaState((Arena) user.getArena()); + user.setCooldown("builder_blockage", cooldown); + int castTime = 15; + user.setCooldown("builder_blockage_running", cooldown); + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOCKAGE_ACTIVATE").asKey().send(user.getPlayer()); + for (Creature enemy : ((Arena) user.getArena()).getEnemies()) { + enemy.setMetadata("VD_DOOR_BLOCK_BAN", new FixedMetadataValue(getPlugin(), true)); + enemy.setMetadata("VD_DOOR_BLOCK_BAN_SOURCE", new FixedMetadataValue(getPlugin(), user.getPlayer().getUniqueId())); + } + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + for (Creature enemy : ((Arena) user.getArena()).getEnemies()) { + enemy.removeMetadata("VD_DOOR_BLOCK_BAN", getPlugin()); + enemy.removeMetadata("VD_DOOR_BLOCK_BAN_SOURCE", getPlugin()); + } + }, 20L * castTime); + } + + private void onBarrierPlace(ItemStack stack, User user) { + Player player = user.getPlayer(); + Block block = null; + for (Block blocks : player.getLastTwoTargetBlocks(null, 5)) { + if (blocks.getType() == Material.AIR) { + block = blocks; + } + } + if (block == null) { + XSound.ENTITY_VILLAGER_NO.play(player); + return; + } + getPlugin().getBukkitHelper().takeOneItem(player, stack); + + XSound.ENTITY_VILLAGER_YES.play(player); + ZombieBarrier zombieBarrier = new ZombieBarrier(); + zombieBarrier.setLocation(block.getLocation()); + + VersionUtils.sendParticles("FIREWORKS_SPARK", user.getArena().getPlayers(), block.getLocation(), 20); + int castTime = (int) Settings.PASSIVE_FENCE_CAST_TIME.getForArenaState((Arena) user.getArena()); + final Block finalBlock = block; + new BukkitRunnable() { + int time = castTime; + + @Override + public void run() { + time -= 1; + if (time <= 9) { + int stage = 9 - time; + ProtocolUtils.sendBlockBreakAnimation(finalBlock, stage); + } + + if (time <= 0) { + ProtocolUtils.removeBlockBreakAnimation(finalBlock); + finalBlock.setType(Material.AIR); + XSound.BLOCK_WOOD_BREAK.play(finalBlock.getLocation()); + Location loc = finalBlock.getLocation().clone(); + //centered location, more or less accurate + loc.add(loc.getX() > 0 ? 0.5 : -0.5, 0.0, loc.getZ() > 0 ? 0.5 : -0.5); + finalBlock.getWorld().spawnParticle(XParticle.getParticle("EXPLOSION_LARGE"), loc, 1); + cancel(); + } + } + }.runTaskTimer(getPlugin(), 20, 20); + block.setType(XMaterial.OAK_FENCE.parseMaterial()); + } + + @EventHandler + public void onEarthedDamage(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) { + return; + } + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena((Player) event.getEntity()); + if (arena == null || !knockbackResistantArenas.containsKey(arena)) { + return; + } + arena.getAssistHandler().doRegisterBuffOnAlly(knockbackResistantArenas.get(arena), (Player) event.getEntity()); + Vector vector = new Vector(); + event.getEntity().setVelocity(vector); + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> event.getEntity().setVelocity(vector), 1L); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onDoorPlace(BlockPlaceEvent event) { + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(event.getPlayer()); + if (arena == null) { + return; + } + if (getPlugin().getUserManager().getUser(event.getPlayer()).isSpectator()) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if (!displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_DOOR_NAME").asKey().build())) { + event.setCancelled(true); + return; + } + List locations = arena.getMapRestorerManager().getGameDoorLocations(); + Location above = event.getBlock().getLocation().add(0, 1, 0); + if ((!locations.contains(event.getBlock().getLocation()) && !locations.contains(above)) + || !MaterialUtils.isDoor(stack.getType())) { + XSound.ENTITY_VILLAGER_NO.play(event.getPlayer()); + event.setCancelled(true); + return; + } + XSound.ENTITY_VILLAGER_YES.play(event.getPlayer()); + //to override world guard protection + event.setCancelled(false); + } + + private enum Settings { + PASSIVE_FENCE_COUNT(1, 2, 3), PASSIVE_FENCE_CAST_TIME(10, 12, 14), PASSIVE_DOOR_MODULO(5, 3, 2), + ABILITY_BLOCKAGE_COOLDOWN(0, 40, 30); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch (KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + + private static class ZombieBarrier { + private Location location; + private int seconds = 10; + + void setLocation(Location location) { + this.location = location; + } + + void decrementSeconds() { + seconds--; + } + + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/CleanerKit.java b/src/main/java/plugily/projects/villagedefense/kits/CleanerKit.java new file mode 100644 index 000000000..cd10c3ca3 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/CleanerKit.java @@ -0,0 +1,312 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Creature; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.arena.ArenaState; +import plugily.projects.minigamesbox.classic.arena.PluginArena; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.handlers.language.TitleBuilder; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.List; +import java.util.Random; + +/** + * Created by Tom on 18/08/2014. + */ +public class CleanerKit extends PremiumKit implements Listener, AbilitySource { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_CLEANER_"; + //this metadata must be given to every enemy killed by poplust to avoid recursive calls and stack overflow in the listener + private static final String KILL_METADATA = "VD_POPLUST_DEATH"; + private final Random random = new Random(); + + public CleanerKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Cleaner"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + schedulePopAwe(); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Cleaner.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Cleaner.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_NAME", new Message("Kit.Content.Cleaner.Game-Item.Cleansing-Stick.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_DESCRIPTION", new Message("Kit.Content.Cleaner.Game-Item.Cleansing-Stick.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_ACTIVATE", new Message("Kit.Content.Cleaner.Game-Item.Cleansing-Stick.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_NAME", new Message("Kit.Content.Cleaner.Game-Item.Poplust.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_DESCRIPTION", new Message("Kit.Content.Cleaner.Game-Item.Poplust.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_ACTIVATE", new Message("Kit.Content.Cleaner.Game-Item.Poplust.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_ACTIVE_ACTION_BAR", new Message("Kit.Content.Cleaner.Game-Item.Poplust.Active-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_ACTIVE_TITLE", new Message("Kit.Content.Cleaner.Game-Item.Poplust.Active-Title", "")); + } + + private void schedulePopAwe() { + //passive only works for alive players not dead ones + Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> { + for(PluginArena pluginArena : getPlugin().getArenaRegistry().getArenas()) { + Arena arena = (Arena) pluginArena; + if(arena.getArenaState() != ArenaState.IN_GAME || arena.getEnemies().isEmpty()) { + continue; + } + for(Player player : arena.getPlayersLeft()) { + if(!(getPlugin().getUserManager().getUser(player).getKit() instanceof CleanerKit)) { + continue; + } + executeRandomPops(arena, player, (int) Settings.PASSIVE_POP_COUNT.getForArenaState(arena)); + } + } + }, 20 * 5L, 20 * 5L); + } + + private void executeRandomPops(Arena arena, Player player, int amount) { + for(int i = 0; i < amount; i++) { + Creature enemy = arena.getEnemies().get(random.nextInt(arena.getEnemies().size())); + if(KitHelper.executeEnemy(enemy, player)) { + VersionUtils.sendParticles("LAVA", arena.getPlayers(), enemy.getLocation(), 20); + } + } + player.playSound(player, Sound.BLOCK_LAVA_POP, 1, 1); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.cleaner"); + } + + @Override + public void giveKitItems(Player player) { + ArmorHelper.setColouredArmor(Color.YELLOW, player); + player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); + + player.getInventory().setItem(3, new ItemBuilder(new ItemStack(XMaterial.BLAZE_ROD.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_DESCRIPTION")) + .build()); + player.getInventory().setItem(4, new ItemBuilder(new ItemStack(XMaterial.SUNFLOWER.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_DESCRIPTION")) + .build()); + player.getInventory().setItem(5, new ItemStack(Material.SADDLE)); + player.getInventory().setItem(8, new ItemStack(Material.COOKED_BEEF, 10)); + } + + @Override + public Material getMaterial() { + return Material.BLAZE_POWDER; + } + + @Override + public void reStock(Player player) { + Arena arena = (Arena) getPlugin().getUserManager().getUser(player).getArena(); + if(arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_PASSIVE_POWER_INCREASED").asKey().send(player); + } else if(arena.getWave() == KitSpecifications.GameTimeState.LATE.getStartWave()) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_PASSIVE_POWER_INCREASED").asKey().send(player); + } + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if(!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), CleanerKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_NAME").asKey().build())) { + onCleansingCast(stack, user); + } else if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_NAME").asKey().build())) { + onPoplustPreCast(stack, user); + } + } + + private void onCleansingCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("cleaner_cleansing")) { + return; + } + int cooldown = getCleansingCooldown((Arena) user.getArena()); + user.setCooldown("cleaner_cleansing", cooldown); + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), cooldown * 20); + + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_CLEANSING_STICK_ACTIVATE").asKey().send(user.getPlayer()); + int popsPerCycle = 5; + int splitAmount = (int) Settings.CLEANSING_POP_COUNT.getForArenaState((Arena) user.getArena()) / popsPerCycle; + for(int i = 0; i < splitAmount; i++) { + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + XSound.BLOCK_LAVA_POP.play(user.getPlayer()); + executeRandomPops((Arena) user.getArena(), user.getPlayer(), popsPerCycle); + }, 10L * splitAmount); + } + } + + private int getCleansingCooldown(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return getKitsConfig().getInt("Kit-Cooldown.Cleaner.Cleansing-Wand.III", 35); + case MID: + return getKitsConfig().getInt("Kit-Cooldown.Cleaner.Cleansing-Wand.II", 40); + case EARLY: + default: + return getKitsConfig().getInt("Kit-Cooldown.Cleaner.Cleansing-Wand.I", 45); + } + } + + private void onPoplustPreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("cleaner_poplust")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + onPoplustCast(stack, user); + } + + private void onPoplustCast(ItemStack stack, User user) { + Arena arena = (Arena) user.getArena(); + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Cleaner.Poplust", 75); + user.setCooldown("cleaner_poplust", cooldown); + final int castTime = (int) Settings.POPLUST_CAST_TIME.getForArenaState(arena); + user.setCooldown("cleaner_poplust_running", castTime); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_ACTIVATE").asKey().send(user.getPlayer()); + + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_ACTIVE_ACTION_BAR"); + Player player = user.getPlayer(); + player.setMetadata("VD_CLEANER_POPLUST", new FixedMetadataValue(getPlugin(), true)); + new BukkitRunnable() { + int tick = 0; + int messageIndex = 0; + + @Override + public void run() { + if(tick % 10 == 0) { + VersionUtils.sendActionBar(player, messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("cleaner_poplust_running")))); + new TitleBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_POPLUST_ACTIVE_TITLE").asKey().send(player); + messageIndex++; + if(messageIndex > messages.size() - 1) { + messageIndex = 0; + } + } + if (tick >= 20 * castTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + cancel(); + player.removeMetadata("VD_CLEANER_POPLUST", getPlugin()); + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + } + + @EventHandler + public void onPoplustDamage(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Player)) { + return; + } + Player damager = (Player) event.getDamager(); + if(getPlugin().getArenaRegistry().getArena(damager) == null) { + return; + } + User user = getPlugin().getUserManager().getUser(damager); + if (!damager.hasMetadata("VD_CLEANER_POPLUST") || user.isSpectator() || !CreatureUtils.isEnemy(event.getEntity()) + || event.getEntity().hasMetadata(KILL_METADATA)) { + return; + } + LivingEntity entity = (LivingEntity) event.getEntity(); + Arena arena = ((Arena) user.getArena()); + arena.getAssistHandler().doRegisterBuffOnAlly(damager, user.getPlayer()); + if (KitHelper.canExecuteEnemy(entity, user.getPlayer())) { + entity.setMetadata(KILL_METADATA, new FixedMetadataValue(getPlugin(), true)); + KitHelper.executeEnemy(entity, user.getPlayer()); + XSound.BLOCK_LAVA_POP.play(user.getPlayer()); + VersionUtils.sendParticles("LAVA", user.getArena().getPlayers(), entity.getLocation(), 15); + } + } + + private enum Settings { + PASSIVE_POP_COUNT(1, 2, 3), CLEANSING_POP_COUNT(10, 15, 20), POPLUST_CAST_TIME(0, 7, 11); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/CrusaderKit.java b/src/main/java/plugily/projects/villagedefense/kits/CrusaderKit.java new file mode 100644 index 000000000..54c8cd563 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/CrusaderKit.java @@ -0,0 +1,480 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.WorldBorder; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.actionbar.ActionBar; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.ParticleDisplay; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.ActionBarPriority; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @author Plajer + *

+ * Created at 30.08.2023 + */ +public class CrusaderKit extends PremiumKit implements AbilitySource, Listener { + + private static final String COURAGE_METADATA = "VD_CRUSADER_COURAGE"; + private static final String UNKILLABLE_METADATA = "VD_CRUSADER_UNKILLABLE"; + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_CRUSADER_"; + private List kitPlayers = new ArrayList<>(); + + public CrusaderKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Crusader"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Crusader.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Crusader.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_NAME", new Message("Kit.Content.Crusader.Game-Item.Courageous.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_DESCRIPTION", new Message("Kit.Content.Crusader.Game-Item.Courageous.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_ACTIVATE", new Message("Kit.Content.Crusader.Game-Item.Courageous.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_AURA_ACTION_BAR", new Message("Kit.Content.Crusader.Game-Item.Crusader.Aura-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_STACKS", new Message("Kit.Content.Crusader.Game-Item.Courageous.Stacks.Base", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_STACKS_MAX", new Message("Kit.Content.Crusader.Game-Item.Courageous.Stacks.Max", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_NAME", new Message("Kit.Content.Crusader.Game-Item.Glory-To-The-King.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_DESCRIPTION", new Message("Kit.Content.Crusader.Game-Item.Glory-To-The-King.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_ACTIVATE", new Message("Kit.Content.Crusader.Game-Item.Glory-To-The-King.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_ACTIVE_ACTION_BAR", new Message("Kit.Content.Crusader.Game-Item.Glory-To-The-King.Active-Action-Bar", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return player.hasPermission("villagedefense.kit.crusader") || getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player); + } + + @Override + public void giveKitItems(Player player) { + ArmorHelper.setArmor(player, ArmorHelper.ArmorType.IRON); + ItemStack itemStack = XMaterial.IRON_SWORD.parseItem(); + itemStack.addUnsafeEnchantment(Enchantment.DAMAGE_ALL, 3); + itemStack.addUnsafeEnchantment(Enchantment.DAMAGE_UNDEAD, 2); + itemStack.addUnsafeEnchantment(Enchantment.DURABILITY, 10); + player.getInventory().addItem(itemStack); + + player.getInventory().setItem(3, new ItemBuilder(new ItemStack(XMaterial.GOAT_HORN.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_DESCRIPTION")) + .build()); + + player.getInventory().setItem(4, new ItemBuilder(new ItemStack(XMaterial.NETHER_STAR.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_DESCRIPTION")) + .build()); + + player.getInventory().setItem(5, new ItemStack(Material.SADDLE)); + player.getInventory().setItem(8, new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 6)); + User user = getPlugin().getUserManager().getUser(player); + doDisplayCourageBar(user); + } + + @Override + public Material getMaterial() { + return Material.MAGMA_CREAM; + } + + @Override + public void reStock(Player player) { + User user = getPlugin().getUserManager().getUser(player); + doDisplayCourageBar(user); + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); + if (arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_PASSIVE_POWER_INCREASED").asKey().send(player); + } else if (arena.getWave() == KitSpecifications.GameTimeState.LATE.getStartWave()) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_PASSIVE_POWER_INCREASED").asKey().send(player); + } + } + + private void doDisplayCourageBar(User user) { + getPlugin().getActionBarManager().clearActionBarsFromPlayer(user.getPlayer()); + new BukkitRunnable() { + @Override + public void run() { + int stacks = 0; + if (user.getPlayer().hasMetadata(COURAGE_METADATA)) { + stacks = user.getPlayer().getMetadata(COURAGE_METADATA).get(0).asInt(); + } + MessageBuilder message; + if (stacks >= 50) { + message = new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_STACKS_MAX").asKey(); + } else { + message = new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_STACKS").asKey().integer(stacks); + } + getPlugin().getActionBarManager().addActionBar(user.getPlayer(), new ActionBar(message, ActionBar.ActionBarType.DISPLAY, ActionBarPriority.LOW_PRIORITY)); + if (!getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + cancel(); + getPlugin().getActionBarManager().clearActionBarsFromPlayer(user.getPlayer()); + } + } + }.runTaskTimer(getPlugin(), 0, 5); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onUnkillableDamage(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) { + return; + } + User user = getPlugin().getUserManager().getUser((Player) event.getEntity()); + if (user == null || user.getArena() == null || user.isSpectator() || !(user.getKit() instanceof CrusaderKit)) { + return; + } + if (user.getPlayer().hasMetadata(UNKILLABLE_METADATA) && user.getPlayer().getHealth() - event.getDamage() <= 0) { + event.setDamage(0); + user.getPlayer().setHealth(1); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlastDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof TNTPrimed)) { + return; + } + TNTPrimed primed = (TNTPrimed) event.getDamager(); + if (!primed.hasMetadata("VD_PRIMED_TNT")) { + return; + } + if (!(event.getEntity() instanceof Player)) { + return; + } + User user = getPlugin().getUserManager().getUser((Player) event.getEntity()); + if (user == null || user.getArena() == null || !(user.getKit() instanceof CrusaderKit)) { + return; + } + KitSpecifications.GameTimeState state = KitSpecifications.getTimeState((Arena) user.getArena()); + if (state == KitSpecifications.GameTimeState.EARLY) { + return; + } + event.setDamage(0); + } + + @EventHandler + public void onIronWillCast(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + Player damager = (Player) event.getDamager(); + User user = getPlugin().getUserManager().getUser(damager); + if (user.isSpectator() || !(user.getKit() instanceof CrusaderKit)) { + return; + } + if (((Arena) user.getArena()).getSpecialEntities().contains(event.getEntity())) { + return; + } + String metadata = "VD_CRUSADER_HITS"; + if (damager.hasMetadata(metadata)) { + int totalHits = damager.getMetadata(metadata).get(0).asInt(); + totalHits++; + if (totalHits == 3) { + damager.playSound(damager, Sound.BLOCK_ANVIL_PLACE, 0.2f, 1.5f); + Creature enemy = ((Creature) event.getEntity()); + CreatureUtils.doStunEnemy(enemy, (int) Settings.PASSIVE_STUN_DURATION.getForArenaState((Arena) user.getArena())); + damager.removeMetadata(metadata, getPlugin()); + doIncreaseCourage(damager, (int) Settings.PASSIVE_STACKS_AMOUNT.getForArenaState((Arena) user.getArena())); + return; + } + damager.setMetadata(metadata, new FixedMetadataValue(getPlugin(), totalHits)); + } else { + damager.setMetadata(metadata, new FixedMetadataValue(getPlugin(), 1)); + } + } + + private void doIncreaseCourage(Player player, int amount) { + if (player.hasMetadata(COURAGE_METADATA)) { + int stacks = player.getMetadata(COURAGE_METADATA).get(0).asInt(); + stacks += amount; + stacks = Math.min(stacks, 50); + player.setMetadata(COURAGE_METADATA, new FixedMetadataValue(getPlugin(), stacks)); + } else { + player.setMetadata(COURAGE_METADATA, new FixedMetadataValue(getPlugin(), amount)); + } + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if (!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), CrusaderKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if (displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_NAME").asKey().build())) { + event.setCancelled(true); + onCourageousCast(stack, user); + } else if (displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_NAME").asKey().build())) { + event.setCancelled(true); + onGloryToTheKingCast(stack, user); + } + } + + private void onCourageousCast(ItemStack stack, User user) { + if (!user.checkCanCastCooldownAndMessage("crusader_courageous")) { + return; + } + int cooldown = 5; + user.setCooldown("crusader_courageous", cooldown); + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), cooldown * 20); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_ACTIVATE").asKey().send(user.getPlayer()); + + int stacks = 0; + Player player = user.getPlayer(); + if (player.hasMetadata(COURAGE_METADATA)) { + stacks = player.getMetadata(COURAGE_METADATA).get(0).asInt(); + } + player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 20 * 5, 1)); + if (stacks >= 5) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 20 * 5, 1)); + } + if (stacks >= 35) { + KitHelper.healPlayer(player, VersionUtils.getMaxHealth(player) * 0.6); + } else if (stacks >= 25) { + KitHelper.healPlayer(player, VersionUtils.getMaxHealth(player) * 0.3); + } else if (stacks >= 15) { + KitHelper.healPlayer(player, VersionUtils.getMaxHealth(player) * 0.15); + } + if (stacks >= 50) { + doPrepareBurnAura(user); + } + playRandomHorn(player); + player.removeMetadata(COURAGE_METADATA, getPlugin()); + } + + private void playRandomHorn(Player player) { + switch (ThreadLocalRandom.current().nextInt(0, 7)) { + case 0 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_0, .75f, 1); + case 1 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_1, .75f, 1); + case 2 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_2, .75f, 1.25f); + case 3 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_3, .75f, 1.5f); + case 4 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_4, .75f, 1.25f); + case 5 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_5, .75f, 1.75f); + case 6 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_6, .75f, 1.5f); + case 7 -> player.playSound(player, Sound.ITEM_GOAT_HORN_SOUND_7, .75f, 1.5f); + } + } + + private void doPrepareBurnAura(User user) { + int castTime = 8; + user.setCooldown("crusader_burn_aura", 8); + Player player = user.getPlayer(); + getPlugin().getActionBarManager().addActionBar(player, new ActionBar(LANGUAGE_ACCESSOR + "GAME_ITEM_COURAGEOUS_AURA_ACTION_BAR", castTime)); + new BukkitRunnable() { + int tick = 0; + + @Override + public void run() { + //apply effects only once per second, particles every tick + XParticle.circle(3.5, 28, ParticleDisplay.simple(player.getLocation().add(0, 0.5, 0), XParticle.getParticle("SMOKE_NORMAL"))); + if (tick % 20 == 0) { + for (Entity entity : player.getNearbyEntities(3.5, 3.5, 3.5)) { + if (!CreatureUtils.isEnemy(entity) || entity.equals(player)) { + continue; + } + entity.setFireTicks(25); + } + } + if (tick >= 20 * castTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + cancel(); + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private void onGloryToTheKingCast(ItemStack stack, User user) { + if (!user.checkCanCastCooldownAndMessage("crusader_glorytotheking")) { + return; + } + if (KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + Player player = user.getPlayer(); + player.setMetadata(UNKILLABLE_METADATA, new FixedMetadataValue(getPlugin(), true)); + int castTime = 10; + int cooldown = getUltimateCooldown((Arena) user.getArena()); + user.setCooldown("crusader_glorytotheking", cooldown); + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> player.removeMetadata(UNKILLABLE_METADATA, getPlugin()), 20L * castTime); + KitHelper.scheduleAbilityCooldown(stack, player, castTime, cooldown); + XSound.BLOCK_PORTAL_TRIGGER.play(player, 1f, 0f); + player.removeMetadata(COURAGE_METADATA, getPlugin()); + user.setCooldown("crusader_glorytotheking_running", castTime); + + getPlugin().getActionBarManager().addActionBar(player, new ActionBar(LANGUAGE_ACCESSOR + "GAME_ITEM_GLORY_TO_THE_KING_ACTIVE_ACTION_BAR", castTime)); + setWorldBorder(player, true); + new BukkitRunnable() { + int tick = 0; + boolean border = true; + + @Override + public void run() { + if (tick >= 20 * (castTime - 2) && tick % 5 == 0) { + border = !border; + setWorldBorder(player, border); + } + if (tick >= 20 * castTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + cancel(); + setWorldBorder(player, false); + if (getPlugin().getArenaRegistry().isInArena(user.getPlayer()) && !user.isSpectator()) { + XSound.ITEM_SHIELD_BREAK.play(player); + KitHelper.healPlayer(player, VersionUtils.getMaxHealth(player) * 0.5); + } + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private void setWorldBorder(Player player, boolean warn) { + if (ServerVersion.Version.isCurrentEqualOrLower(ServerVersion.Version.v1_16_R3)) { + doLegacyBorder(player, warn); + } else { + doNewBorder(player, warn); + } + } + + @Deprecated + //testme + private void doLegacyBorder(Player player, boolean warn) { + PacketContainer container = new PacketContainer(PacketType.Play.Server.WORLD_BORDER); + WorldBorder border = player.getWorld().getWorldBorder(); + container.getWorldBorderActions().write(0, EnumWrappers.WorldBorderAction.INITIALIZE); + container.getDoubles().write(0, player.getLocation().getX()); + container.getDoubles().write(1, player.getLocation().getZ()); + container.getDoubles().write(2, border.getSize()); + container.getDoubles().write(3, border.getSize()); + container.getIntegers().write(0, 29999984); + container.getIntegers().write(1, 0); + container.getIntegers().write(2, (int) (warn ? border.getSize() : border.getWarningDistance())); + container.getLongs().write(0, 0L); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, container); + } + + private void doNewBorder(Player player, boolean warn) { + PacketContainer container = new PacketContainer(PacketType.Play.Server.INITIALIZE_BORDER); + WorldBorder border = player.getWorld().getWorldBorder(); + container.getDoubles().write(0, player.getLocation().getX()); + container.getDoubles().write(1, player.getLocation().getZ()); + container.getDoubles().write(2, warn ? 0 : border.getSize()); + container.getDoubles().write(3, warn ? 0 : border.getSize()); + container.getIntegers().write(0, warn ? 1 : 29999984); + container.getIntegers().write(1, 0); + container.getIntegers().write(2, warn ? 5 : border.getWarningDistance()); + container.getLongs().write(0, 0L); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, container); + } + + private int getUltimateCooldown(Arena arena) { + switch (KitSpecifications.getTimeState(arena)) { + case LATE: + return 25; + case MID: + return 40; + case EARLY: + default: + return 0; + } + } + + private enum Settings { + PASSIVE_STUN_DURATION(2, 4, 5), PASSIVE_STACKS_AMOUNT(1, 2, 4), ULTIMATE_HEAL_POWER(0, 4, 5); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch (KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/free/KnightKit.java b/src/main/java/plugily/projects/villagedefense/kits/KnightKit.java similarity index 66% rename from src/main/java/plugily/projects/villagedefense/kits/free/KnightKit.java rename to src/main/java/plugily/projects/villagedefense/kits/KnightKit.java index ada30f677..818fb4a99 100644 --- a/src/main/java/plugily/projects/villagedefense/kits/free/KnightKit.java +++ b/src/main/java/plugily/projects/villagedefense/kits/KnightKit.java @@ -1,22 +1,22 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -package plugily.projects.villagedefense.kits.free; +package plugily.projects.villagedefense.kits; import org.bukkit.Material; import org.bukkit.entity.Player; diff --git a/src/main/java/plugily/projects/villagedefense/kits/MedicKit.java b/src/main/java/plugily/projects/villagedefense/kits/MedicKit.java new file mode 100644 index 000000000..c8320f7de --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/MedicKit.java @@ -0,0 +1,339 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Color; +import org.bukkit.EntityEffect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Golem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; +import org.bukkit.scheduler.BukkitRunnable; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.ParticleDisplay; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.arena.ArenaUtils; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by Tom on 1/12/2015. + */ +public class MedicKit extends PremiumKit implements Listener, AbilitySource { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_MEDIC_"; + + public MedicKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Medic"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Medic.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Medic.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_NAME", new Message("Kit.Content.Medic.Game-Item.Aura.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_DESCRIPTION", new Message("Kit.Content.Medic.Game-Item.Aura.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_ACTIVE_ACTION_BAR", new Message("Kit.Content.Medic.Game-Item.Aura.Active-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_HEALED_BY_ACTION_BAR", new Message("Kit.Content.Medic.Game-Item.Aura.Healed-By-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_NAME", new Message("Kit.Content.Medic.Game-Item.Homecoming.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_DESCRIPTION", new Message("Kit.Content.Medic.Game-Item.Homecoming.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_ACTIVATE", new Message("Kit.Content.Medic.Game-Item.Homecoming.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_RESPAWNED_BY_TITLE", new Message("Kit.Content.Medic.Game-Item.Homecoming.Respawned-By-Title", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_RESPAWNED_BY_SUBTITLE", new Message("Kit.Content.Medic.Game-Item.Homecoming.Respawned-By-Subtitle", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.medic"); + } + + @Override + public void giveKitItems(Player player) { + player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); + ArmorHelper.setColouredArmor(Color.WHITE, player); + player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); + player.getInventory().addItem(VersionUtils.getPotion(PotionType.REGEN, 1, true)); + + player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.GHAST_TEAR.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_DESCRIPTION")) + .build()); + player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.GOLD_NUGGET.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_DESCRIPTION")) + .build()); + } + + @Override + public Material getMaterial() { + return Material.GHAST_TEAR; + } + + @Override + public void reStock(Player player) { + User user = getPlugin().getUserManager().getUser(player); + Arena arena = (Arena) user.getArena(); + int heal = (int) Settings.PASSIVE_HEAL_POWER.getForArenaState(arena); + for(Player arenaPlayer : arena.getPlayersLeft()) { + double maxHealth = VersionUtils.getMaxHealth(arenaPlayer); + //todo useless?? all players are healed before next wave + if(arenaPlayer.getHealth() + heal > maxHealth) { + arenaPlayer.setHealth(maxHealth); + arenaPlayer.setFoodLevel(20); + } else { + arenaPlayer.setHealth(arenaPlayer.getHealth() + heal); + } + arena.getAssistHandler().doRegisterBuffOnAlly(player, arenaPlayer); + } + for(Villager villager : arena.getVillagers()) { + villager.setHealth(Math.min(villager.getHealth() + heal, VersionUtils.getMaxHealth(villager))); + villager.setCustomName(CreatureUtils.getHealthNameTag(villager)); + } + if(arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_NAME").asKey().build()).send(player); + } else if(arena.getWave() == KitSpecifications.GameTimeState.LATE.getStartWave()) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_NAME").asKey().build()).send(player); + } + } + + @EventHandler + public void onCreatureHit(EntityDamageByEntityEvent e) { + if(!(e.getEntity() instanceof Creature) || !(e.getDamager() instanceof Player)) { + return; + } + User user = getPlugin().getUserManager().getUser((Player) e.getDamager()); + if(!(user.getKit() instanceof MedicKit) || Math.random() > 0.1) { + return; + } + healNearbyPlayers(user.getPlayer(), e.getDamager()); + } + + private void healNearbyPlayers(Player source, Entity en) { + for(Entity entity : en.getNearbyEntities(5, 5, 5)) { + if(!(entity instanceof Player)) { + continue; + } + KitHelper.healPlayer(source, (Player) entity, 1.0); + } + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if(!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), MedicKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_NAME").asKey().build())) { + onHomecomingPreCast(stack, user); + } else if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_NAME").asKey().build())) { + onAuraPreCast(stack, user); + } + } + + private void onHomecomingPreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("medic_homecoming")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Medic.Homecoming", 60); + user.setCooldown("medic_homecoming", cooldown); + + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), cooldown * 20); + onHomecomingCast(user); + } + + private void onHomecomingCast(User user) { + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_ACTIVATE").asKey().send(user.getPlayer()); + List left = user.getArena().getPlayersLeft(); + user.getPlayer().playEffect(EntityEffect.valueOf("TOTEM_RESURRECT")); + + String title = new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_RESPAWNED_BY_TITLE").asKey().player(user.getPlayer()).build(); + String subTitle = new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_HOMECOMING_RESPAWNED_BY_SUBTITLE").asKey().player(user.getPlayer()).build(); + for(Player arenaPlayer : user.getArena().getPlayers()) { + if(left.contains(arenaPlayer)) { + continue; + } + VersionUtils.sendTitles(arenaPlayer, title, subTitle, 5, 40, 5); + arenaPlayer.playEffect(EntityEffect.valueOf("TOTEM_RESURRECT")); + int amplifier = (int) Settings.HEAL_AURA_POWER.getForArenaState((Arena) user.getArena()); + arenaPlayer.addPotionEffect(new PotionEffect(PotionEffectType.HEALTH_BOOST, 30 * 20, amplifier)); + arenaPlayer.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 30 * 20, amplifier)); + ((Arena) user.getArena()).getAssistHandler().doRegisterBuffOnAlly(user.getPlayer(), arenaPlayer); + } + ArenaUtils.bringDeathPlayersBack((Arena) user.getArena()); + } + + private void onAuraPreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("medic_aura")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = getAuraCooldown((Arena) user.getArena()); + user.setCooldown("medic_aura", cooldown); + int castTime = 10; + user.setCooldown("medic_aura_running", castTime); + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + onAuraCast(user, castTime); + } + + private int getAuraCooldown(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return getKitsConfig().getInt("Kit-Cooldown.Medic.Aura.II", 15); + case MID: + return getKitsConfig().getInt("Kit-Cooldown.Medic.Aura.I", 30); + case EARLY: + default: + return 0; + } + } + + public void onAuraCast(User user, int castTime) { + Player player = user.getPlayer(); + player.playSound(player, Sound.ENTITY_PLAYER_LEVELUP, 1, 1.5f); + + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_ACTIVE_ACTION_BAR"); + List healingMessages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_AURA_HEALED_BY_ACTION_BAR"); + new BukkitRunnable() { + int tick = 0; + int messageIndex = 0; + int healingMessageIndex = 0; + + @Override + public void run() { + //apply effects only once per second, particles every 5 ticks + if(tick % 5 == 0 && ServerVersion.Version.isCurrentEqualOrHigher(ServerVersion.Version.v1_9_R1)) { + XParticle.circle(3.5, 18, ParticleDisplay.simple(player.getLocation().add(0, 0.5, 0), XParticle.getParticle("HEART"))); + } + if(tick % 10 == 0) { + int heal = (int) Settings.HEAL_AURA_POWER.getForArenaState((Arena) user.getArena()); + for(LivingEntity entity : getNearbyAllies(player)) { + entity.setHealth(Math.min(entity.getHealth() + heal, VersionUtils.getMaxHealth(entity))); + VersionUtils.sendParticles("HEART", null, entity.getLocation(), 5, 0, 0, 0); + if(!entity.equals(player) && entity instanceof Player) { + VersionUtils.sendActionBar((Player) entity, healingMessages.get(healingMessageIndex) + .replace("%player%", user.getPlayer().getName())); + } + ((Arena) user.getArena()).getAssistHandler().doRegisterBuffOnAlly(player, entity); + } + player.setHealth(Math.min(player.getHealth() + heal, VersionUtils.getMaxHealth(player))); + VersionUtils.sendActionBar(player, messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("medic_aura_running")))); + messageIndex++; + healingMessageIndex++; + if(messageIndex > messages.size() - 1) { + messageIndex = 0; + } + if(healingMessageIndex > healingMessages.size() - 1) { + healingMessageIndex = 0; + } + } + if(tick >= 20 * castTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + cancel(); + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private List getNearbyAllies(Player player) { + return player.getNearbyEntities(3.5, 3.5, 3.5) + .stream() + .filter(e -> e instanceof Player || e instanceof Wolf || e instanceof Golem) + .map(e -> (LivingEntity) e) + .collect(Collectors.toList()); + } + + private enum Settings { + HEAL_AURA_POWER(0, 2, 4), PASSIVE_HEAL_POWER(2, 3, 4), AMPLIFIER_POWER(0, 1, 2); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/PetsFriend.java b/src/main/java/plugily/projects/villagedefense/kits/PetsFriend.java new file mode 100644 index 000000000..44fc44d27 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/PetsFriend.java @@ -0,0 +1,268 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Creature; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.handlers.upgrade.EntityUpgrade; +import plugily.projects.villagedefense.handlers.upgrade.NewEntityUpgradeManager; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * @author Plajer + *

+ * Created at 11.08.2023 + */ +public class PetsFriend extends PremiumKit implements AbilitySource, Listener { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_PETS_FRIEND_"; + private final Random random = new Random(); + + public PetsFriend() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("PetsFriend"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Pets-Friend.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Pets-Friend.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_NAME", new Message("Kit.Content.Pets-Friend.Game-Item.Fight-Or-Flight.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_DESCRIPTION", new Message("Kit.Content.Pets-Friend.Game-Item.Fight-Or-Flight.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_ACTIVATE", new Message("Kit.Content.Pets-Friend.Game-Item.Fight-Or-Flight.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_NAME", new Message("Kit.Content.Pets-Friend.Game-Item.Unstoppable-Beasts.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_DESCRIPTION", new Message("Kit.Content.Pets-Friend.Game-Item.Unstoppable-Beasts.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_ACTIVATE", new Message("Kit.Content.Pets-Friend.Game-Item.Unstoppable-Beasts.Activate", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.petsfriend"); + } + + @Override + public void giveKitItems(Player player) { + player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); + ArmorHelper.setArmor(player, ArmorHelper.ArmorType.LEATHER); + + player.getInventory().setItem(3, new ItemBuilder(new ItemStack(XMaterial.BONE.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_DESCRIPTION")) + .build()); + player.getInventory().setItem(4, new ItemBuilder(new ItemStack(XMaterial.SHEARS.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_DESCRIPTION")) + .build()); + + player.getInventory().setItem(5, new ItemStack(Material.SADDLE)); + player.getInventory().setItem(8, new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); + if(arena == null) { + return; + } + org.bukkit.Location start = arena.getStartLocation(); + for(int i = 0; i < 2; i++) { + arena.spawnWolfForce(start, player); + } + arena.spawnGolemForce(start, player); + } + + @Override + public Material getMaterial() { + return Material.BONE; + } + + @Override + public void reStock(Player player) { + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); + NewEntityUpgradeManager upgradeManager = ((Main) getPlugin()).getEntityUpgradeManager(); + if(arena.getWave() % (int) Settings.PASSIVE_WOLVES_MODULO.getForArenaState(arena) == 0) { + Creature wolf = arena.spawnWolfForce(arena.getStartLocation(), player); + List wolfUpgrades = upgradeManager.getRegisteredUpgrades() + .stream() + .filter(u -> u.getApplicableEntity() == EntityType.WOLF) + .collect(Collectors.toList()); + if(KitSpecifications.getTimeState(arena) != KitSpecifications.GameTimeState.EARLY) { + EntityUpgrade randomUpgrade = rollRandomUpgrade(wolfUpgrades); + upgradeManager.applyUpgradeWithVisuals(wolf, player, randomUpgrade); + } + } + if(arena.getWave() % (int) Settings.PASSIVE_GOLEMS_MODULO.getForArenaState(arena) == 0) { + Creature golem = arena.spawnGolem(arena.getStartLocation(), player); + List golemUpgrades = upgradeManager.getRegisteredUpgrades() + .stream() + .filter(u -> u.getApplicableEntity() == EntityType.IRON_GOLEM) + .collect(Collectors.toList()); + if(KitSpecifications.getTimeState(arena) != KitSpecifications.GameTimeState.EARLY) { + EntityUpgrade randomUpgrade = rollRandomUpgrade(golemUpgrades); + upgradeManager.applyUpgradeWithVisuals(golem, player, randomUpgrade); + } + } + } + + private EntityUpgrade rollRandomUpgrade(List upgrades) { + while (true) { + EntityUpgrade upgrade = upgrades.get(random.nextInt(upgrades.size())); + if (upgrade.isSpecial() || upgrade.isHidden() || upgrade.getDependsOn() != null) { + continue; + } + return upgrade; + } + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if(!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), PetsFriend.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_NAME").asKey().build())) { + onFightOrFlightCast(stack, user); + } else if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_NAME").asKey().build())) { + onUnstoppableBeastsCast(stack, user); + } + } + + private void onFightOrFlightCast(ItemStack stack, User user) { + String abilityId = "petsfriend_fightorflight"; + if(!user.checkCanCastCooldownAndMessage(abilityId)) { + return; + } + int castTime = 10; + int cooldown = 30; + user.setCooldown(abilityId, cooldown); + + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + Arena arena = ((Arena) user.getArena()); + List pets = arena.getWolves() + .stream() + .filter(w -> w.hasMetadata("VD_OWNER_UUID") + && w.getMetadata("VD_OWNER_UUID").get(0).asString().equals(user.getPlayer().getUniqueId().toString())) + .collect(Collectors.toList()); + pets.addAll( + arena.getIronGolems() + .stream() + .filter(w -> w.hasMetadata("VD_OWNER_UUID") + && w.getMetadata("VD_OWNER_UUID").get(0).asString().equals(user.getPlayer().getUniqueId().toString())) + .collect(Collectors.toList()) + ); + for(Creature pet : arena.getWolves()) { + pet.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 20 * castTime, 1, false, false)); + pet.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 20 * castTime, + (int) Settings.ABILITY_FIGHT_OR_FLIGHT_DAMAGE_AMPLIFIER.getForArenaState((Arena) user.getArena()), false, false)); + } + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FIGHT_OR_FLIGHT_ACTIVATE").asKey().send(user.getPlayer()); + } + + private void onUnstoppableBeastsCast(ItemStack stack, User user) { + String abilityId = "petsfriend_unstoppablebeasts"; + if(!user.checkCanCastCooldownAndMessage(abilityId)) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = 140; + user.setCooldown(abilityId, cooldown); + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), cooldown * 20); + + NewEntityUpgradeManager upgradeManager = ((Main) getPlugin()).getEntityUpgradeManager(); + Arena arena = (Arena) user.getArena(); + Creature wolf = arena.spawnWolfForce(arena.getStartLocation(), user.getPlayer()); + upgradeManager.getRegisteredUpgrades() + .stream() + .filter(u -> u.getApplicableEntity() == EntityType.WOLF) + .filter(u -> !u.isHidden()) + .forEach(upgrade -> upgradeManager.applyUpgradeSilent(wolf, user.getPlayer(), upgrade)); + wolf.getWorld().playSound(wolf.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 0.5f); + Creature golem = arena.spawnGolemForce(arena.getStartLocation(), user.getPlayer()); + upgradeManager.getRegisteredUpgrades() + .stream() + .filter(u -> u.getApplicableEntity() == EntityType.IRON_GOLEM) + .filter(u -> !u.isHidden()) + .forEach(upgrade -> upgradeManager.applyUpgradeSilent(golem, user.getPlayer(), upgrade)); + golem.getWorld().playSound(golem.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 0.5f); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_UNSTOPPABLE_BEASTS_ACTIVATE").asKey().send(user.getPlayer()); + } + + private enum Settings { + PASSIVE_WOLVES_MODULO(3, 2, 1), PASSIVE_GOLEMS_MODULO(4, 3, 2), PASSIVE_UPGRADES_TIER(0, 1, 2), + ABILITY_FIGHT_OR_FLIGHT_DAMAGE_AMPLIFIER(1, 2, 3); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/ShotBowKit.java b/src/main/java/plugily/projects/villagedefense/kits/ShotBowKit.java new file mode 100644 index 000000000..b9fdca113 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/ShotBowKit.java @@ -0,0 +1,265 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * @author Plajer + *

+ * Created at 30.08.2023 + */ +public class ShotBowKit extends PremiumKit implements AbilitySource, Listener { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_SHOT_BOW_"; + private static final String ARROW_RAIN_KNOCK_METADATA = "VD_SHOTBOW_KNOCKBACK"; + private final Random random = new Random(); + + public ShotBowKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("ShotBow"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Shot-Bow.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Shot-Bow.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_ARROW_RAIN_NAME", new Message("Kit.Content.Shot-Bow.Game-Item.Arrow-Rain.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_ARROW_RAIN_DESCRIPTION", new Message("Kit.Content.Shot-Bow.Game-Item.Arrow-Rain.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_ARROW_RAIN_ACTIVATE", new Message("Kit.Content.Shot-Bow.Game-Item.Arrow-Rain.Activate", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.shotbow"); + } + + @Override + public void giveKitItems(Player player) { + player.getInventory().addItem(WeaponHelper.getEnchantedBow(new Enchantment[]{Enchantment.DURABILITY, Enchantment.ARROW_KNOCKBACK, Enchantment.ARROW_INFINITE}, new int[]{10, 1, 1})); + player.getInventory().setItem(9, new ItemStack(getMaterial(), 1)); + ArmorHelper.setColouredArmor(Color.YELLOW, player); + player.getInventory().setItem(4, new ItemBuilder(new ItemStack(XMaterial.STICK.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_ARROW_RAIN_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_ARROW_RAIN_DESCRIPTION")) + .build()); + + player.getInventory().setItem(5, new ItemStack(Material.SADDLE)); + player.getInventory().setItem(8, new ItemStack(XMaterial.COOKED_BEEF.parseMaterial(), 8)); + } + + @Override + public Material getMaterial() { + return Material.ARROW; + } + + @Override + public void reStock(Player player) { + //no restock for this kit + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if(!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), ShotBowKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_ARROW_RAIN_NAME").asKey().build())) { + onArrowRainCast(stack, user); + } + } + + private void onArrowRainCast(ItemStack stack, User user) { + String abilityId = "shotbow_arrowrain"; + if(!user.checkCanCastCooldownAndMessage(abilityId)) { + return; + } + if (KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = 20; + user.setCooldown(abilityId, cooldown); + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), 20 * cooldown); + + for(int i = 0; i < Settings.ABILITY_ARROW_RAIN_COUNT.getForArenaState((Arena) user.getArena()); i++) { + Player player = user.getPlayer(); + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + Arrow pr = player.launchProjectile(Arrow.class); + pr.setMetadata(ARROW_RAIN_KNOCK_METADATA, new FixedMetadataValue(getPlugin(), true)); + pr.setVelocity(player.getLocation().getDirection().multiply(4)); + pr.setBounce(false); + pr.setShooter(player); + pr.setCritical(true); + }, 4L * (2L * i)); + } + } + + @EventHandler + public void onArrowDamage(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Arrow) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + Arrow arrow = (Arrow) event.getDamager(); + if(!(arrow.getShooter() instanceof Player)) { + return; + } + Player shooter = (Player) arrow.getShooter(); + User user = getPlugin().getUserManager().getUser(shooter); + if(user == null || user.getArena() == null || !(user.getKit() instanceof ShotBowKit)) { + return; + } + //large knockback for arrow rain ability + if(arrow.hasMetadata(ARROW_RAIN_KNOCK_METADATA)) { + event.getEntity().setVelocity(user.getPlayer().getLocation().getDirection().multiply(5)); + KitHelper.executeEnemy((LivingEntity) event.getEntity(), shooter); + return; + } + Arena arena = (Arena) user.getArena(); + double oneshotChance = Settings.PASSIVE_INSTAKILL_CHANCE.getForArenaState(arena); + double chance = random.nextDouble(); + if(chance <= oneshotChance) { + KitHelper.executeEnemy((LivingEntity) event.getEntity(), shooter); + XSound.BLOCK_NOTE_BLOCK_HARP.play(user.getPlayer()); + return; + } + //apply effective arrows passive from mid game + if(KitSpecifications.getTimeState(arena) == KitSpecifications.GameTimeState.EARLY) { + return; + } + doApplyEffectiveArrows((LivingEntity) event.getEntity(), shooter); + } + + private void doApplyEffectiveArrows(LivingEntity target, Player source) { + int choice = random.nextInt(4) + 1; + switch(choice) { + case 1: { + //lightning aoe + target.getWorld().strikeLightningEffect(target.getLocation()); + KitHelper.maxHealthPercentDamage(target, source, 10.0); + List enemies = target.getNearbyEntities(1.5, 1.5, 1.5) + .stream() + .filter(e -> !target.equals(e)) + .filter(CreatureUtils::isEnemy) + .collect(Collectors.toList()); + for(Entity entity : enemies) { + if(!CreatureUtils.isEnemy(entity)) { + continue; + } + KitHelper.maxHealthPercentDamage((LivingEntity) entity, source, 10.0); + } + break; + } + case 2: + //slowness + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 10, 1)); + break; + case 3: { + //shared combust + List enemies = target.getNearbyEntities(1.5, 1.5, 1.5) + .stream() + .filter(e -> !target.equals(e)) + .filter(CreatureUtils::isEnemy) + .map(e -> (LivingEntity) e) + .collect(Collectors.toList()); + for(LivingEntity enemy : enemies) { + enemy.setFireTicks(20 * 10); + enemy.damage(0, source); + } + break; + } + case 4: + default: + //weakness + target.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 20 * 10, 1)); + break; + } + } + + private enum Settings { + PASSIVE_INSTAKILL_CHANCE(0.1, 0.2, 0.3), ABILITY_ARROW_RAIN_COUNT(0, 8, 12); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/TerminatorKit.java b/src/main/java/plugily/projects/villagedefense/kits/TerminatorKit.java new file mode 100644 index 000000000..cb594a7b7 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/TerminatorKit.java @@ -0,0 +1,337 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.ParticleDisplay; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; +import plugily.projects.villagedefense.utils.NumberUtils; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * Created by Tom on 18/07/2015. + */ +public class TerminatorKit extends PremiumKit implements Listener, AbilitySource { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_TERMINATOR_"; + private final Random random = new Random(); + + public TerminatorKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Terminator"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getKitRegistry().registerKit(this); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Terminator.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Terminator.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_TERMINUS_NAME", new Message("Kit.Content.Terminator.Game-Item.Terminus.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_TERMINUS_DESCRIPTION", new Message("Kit.Content.Terminator.Game-Item.Terminus.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_NAME", new Message("Kit.Content.Terminator.Game-Item.Neverdeath.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_DESCRIPTION", new Message("Kit.Content.Terminator.Game-Item.Neverdeath.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_ACTIVATE", new Message("Kit.Content.Terminator.Game-Item.Neverdeath.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_NAME", new Message("Kit.Content.Terminator.Game-Item.Motors-Overcharge.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_DESCRIPTION", new Message("Kit.Content.Terminator.Game-Item.Motors-Overcharge.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_ACTIVATE", new Message("Kit.Content.Terminator.Game-Item.Motors-Overcharge.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_ACTIVE_ACTION_BAR", new Message("Kit.Content.Terminator.Game-Item.Motors-Overcharge.Active-Action-Bar", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return player.hasPermission("villagedefense.kit.terminator") || getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player); + } + + @Override + public void giveKitItems(Player player) { + player.getInventory().setItem(3, new ItemBuilder(XMaterial.DIAMOND_SWORD.parseItem()) + .enchantment(Enchantment.DURABILITY, 100) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_TERMINUS_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_TERMINUS_DESCRIPTION")) + .build()); + player.getInventory().setItem(4, new ItemBuilder(new ItemStack(XMaterial.CHARCOAL.parseMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_DESCRIPTION")) + .build()); + player.getInventory().setItem(5, new ItemBuilder(new ItemStack(XMaterial.TRIPWIRE_HOOK.parseMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_DESCRIPTION")) + .build()); + + player.getInventory().setItem(8, new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); + ArmorHelper.setArmor(player, ArmorHelper.ArmorType.IRON); + } + + @Override + public Material getMaterial() { + return Material.ANVIL; + } + + @Override + public void reStock(Player player) { + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); + if(arena.getWave() > 1 && arena.getWave() <= 30 && arena.getWave() % 5 == 0) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_TERMINUS_NAME").asKey().build()).send(player); + } + if(arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_NAME").asKey().build()).send(player); + } + } + + @EventHandler + public void onPreSwordDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + if (event.isCancelled()) { + return; + } + Player damager = (Player) event.getDamager(); + if(!KitHelper.isInGameWithKitAndItemInHand(damager, TerminatorKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(damager); + User user = getPlugin().getUserManager().getUser(damager); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_TERMINUS_NAME").asKey().build())) { + onSwordDamage(event, user); + } + } + + private void onSwordDamage(EntityDamageByEntityEvent event, User user) { + Arena arena = (Arena) user.getArena(); + double onHitBurnChance = getOnHitBurnChance(arena.getWave()); + double onHitInstakillChance = arena.getWave() >= 10 ? 0.05 : 0; + double onHitSharedCombustChance = arena.getWave() >= 20 ? 0.2 : 0; + double onHitLargeKnockbackChance = arena.getWave() >= 25 ? 0.35 : 0; + double onHitLifestealPercent = arena.getWave() >= 15 ? 0.06 : 0; + double maxHealthBonusDamage = getMaxHealthBonusDamage(arena.getWave()); + double chance = random.nextDouble(); + LivingEntity entity = (LivingEntity) event.getEntity(); + if(chance <= onHitBurnChance) { + entity.setFireTicks(20 * 3); + } + double steal = event.getDamage() * onHitLifestealPercent; + //filter out large lifesteals from insta kills or such + if(steal > 0 && steal < 100) { + KitHelper.healPlayer(user.getPlayer(), steal); + } + if(chance <= onHitInstakillChance) { + KitHelper.executeEnemy(entity, user.getPlayer()); + return; + } + if(chance <= onHitSharedCombustChance) { + List enemies = entity.getNearbyEntities(1.5, 1.5, 1.5) + .stream() + .filter(e -> !entity.equals(e)) + .filter(CreatureUtils::isEnemy) + .map(e -> (LivingEntity) e) + .collect(Collectors.toList()); + for(LivingEntity enemy : enemies) { + enemy.setFireTicks(20 * 3); + enemy.damage(0, user.getPlayer()); + } + } + if(chance <= onHitLargeKnockbackChance) { + entity.setVelocity(user.getPlayer().getLocation().getDirection().multiply(2.5)); + } + double bonusDamage = VersionUtils.getMaxHealth(entity) * maxHealthBonusDamage; + event.setDamage(event.getDamage() + bonusDamage); + } + + private double getOnHitBurnChance(int wave) { + if(wave >= 15) { + return 0.4; + } else if(wave >= 5) { + return 0.2; + } + return 0; + } + + private double getMaxHealthBonusDamage(int wave) { + if(wave < 30) { + return 0; + } + int val = wave - 29; + return NumberUtils.clamp(val, 1, 40) / 100.0; + } + + @EventHandler + public void onEntityDamage(EntityDamageByEntityEvent event) { + if (!event.getDamager().hasMetadata("VD_TERMINATOR_NO_DAMAGE")) { + return; + } + event.setCancelled(true); + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if(!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), TerminatorKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_NAME").asKey().build())) { + onNeverdeathCast(stack, user); + } else if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_NAME").asKey().build())) { + onMotorsOverchargePreCast(stack, user); + } + } + + private void onNeverdeathCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("terminator_neverdeath")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Terminator.Neverdeath", 20); + user.setCooldown("terminator_neverdeath", cooldown); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_NEVERDEATH_ACTIVATE").asKey().send(user.getPlayer()); + + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), cooldown * 20); + + double missingHealthPercent = 1.0 - (user.getPlayer().getHealth() / VersionUtils.getMaxHealth(user.getPlayer())); + user.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 20 * 15, (int) Math.floor(missingHealthPercent * 10.0))); + } + + private void onMotorsOverchargePreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("terminator_overcharge")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Terminator.Motors-Overcharge", 60); + user.setCooldown("terminator_overcharge", cooldown); + int castTime = 10; + user.setCooldown("terminator_overcharge_running", castTime); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_ACTIVATE").asKey().send(user.getPlayer()); + + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + onMotorsOverchargeCast(user); + } + + private void onMotorsOverchargeCast(User user) { + int castTime = 10; + Player player = user.getPlayer(); + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * castTime, 3)); + + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_MOTORS_OVERCHARGE_ACTIVE_ACTION_BAR"); + new BukkitRunnable() { + int tick = 0; + int messageIndex = 0; + + @Override + public void run() { + if(ServerVersion.Version.isCurrentEqualOrHigher(ServerVersion.Version.v1_9_R1)) { + XParticle.circle(3, 26, ParticleDisplay.simple(player.getLocation().add(0, 0.35, 0), XParticle.getParticle("SMOKE_NORMAL"))); + } + List enemies = player.getNearbyEntities(2.5, 2.5, 2.5) + .stream() + .filter(CreatureUtils::isEnemy) + .collect(Collectors.toList()); + for(Entity enemy : enemies) { + LivingEntity livingEntity = (LivingEntity) enemy; + if(tick >= 20 * castTime) { + Vector oppositeDirection = enemy.getLocation().subtract(player.getLocation()).toVector(); + enemy.setVelocity(oppositeDirection.normalize().multiply(2.0)); + KitHelper.executeEnemy(livingEntity, player); + continue; + } + Vector direction = player.getLocation().subtract(enemy.getLocation()).toVector(); + if (enemy instanceof Ageable ageable) { + ageable.setBaby(); + } + if (!enemy.hasMetadata("VD_TERMINATOR_NO_DAMAGE")) { + ((LivingEntity) enemy).setCollidable(false); + enemy.setMetadata("VD_TERMINATOR_NO_DAMAGE", new FixedMetadataValue(getPlugin(), true)); + } + enemy.setVelocity(direction.normalize().multiply(1.0)); + if(tick % 20 == 0) { + KitHelper.maxHealthPercentDamage(livingEntity, player, 35.0); + } + } + if(tick % 10 == 0) { + VersionUtils.sendActionBar(player, messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("terminator_overcharge_running")))); + messageIndex++; + if(messageIndex > messages.size() - 1) { + messageIndex = 0; + } + } + if(user.isSpectator() || user.getArena() == null || !player.isOnline()) { + cancel(); + return; + } + if(tick >= 20 * castTime) { + VersionUtils.sendActionBar(player, ""); + player.getWorld().spawnParticle(XParticle.getParticle("EXPLOSION_LARGE"), player.getLocation(), 3); + cancel(); + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/TornadoKit.java b/src/main/java/plugily/projects/villagedefense/kits/TornadoKit.java new file mode 100644 index 000000000..8cabeb1f7 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/TornadoKit.java @@ -0,0 +1,399 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Bukkit; +import org.bukkit.EntityEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Creature; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; +import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.ParticleDisplay; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by Tom on 30/12/2015. + */ +public class TornadoKit extends PremiumKit implements Listener, AbilitySource { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_TORNADO_"; + private static final int TORNADO_MAX_HEIGHT = 5; + private static final double TORNADO_MAX_RADIUS = 4; + private static final double TORNADO_RADIUS_INCREMENT = TORNADO_MAX_RADIUS / TORNADO_MAX_HEIGHT; + private final List ultimateUsers = new ArrayList<>(); + + public TornadoKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Tornado"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + getPlugin().getKitRegistry().registerKit(this); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Tornado.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Tornado.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_NAME", new Message("Kit.Content.Tornado.Game-Item.Tornado.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_DESCRIPTION", new Message("Kit.Content.Tornado.Game-Item.Tornado.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_NAME", new Message("Kit.Content.Tornado.Game-Item.Monsoon.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_DESCRIPTION", new Message("Kit.Content.Tornado.Game-Item.Monsoon.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_ACTIVE_ACTION_BAR", new Message("Kit.Content.Tornado.Game-Item.Monsoon.Active-Action-Bar", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_NAME", new Message("Kit.Content.Tornado.Game-Item.Final-Flight.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_DESCRIPTION", new Message("Kit.Content.Tornado.Game-Item.Final-Flight.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_ACTIVE_ACTION_BAR", new Message("Kit.Content.Tornado.Game-Item.Final-Flight.Active-Action-Bar", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return player.hasPermission("villagedefense.kit.tornado") || getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player); + } + + @Override + public void giveKitItems(Player player) { + ArmorHelper.setArmor(player, ArmorHelper.ArmorType.GOLD); + player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); + + player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 10)); + player.getInventory().addItem(new ItemStack(Material.SADDLE)); + player.getInventory().addItem(new ItemBuilder(new ItemStack(getMaterial(), 5)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_DESCRIPTION")) + .build()); + player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.OXEYE_DAISY.parseMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_DESCRIPTION")) + .build()); + player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.FEATHER.parseMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_DESCRIPTION")) + .build()); + } + + @Override + public Material getMaterial() { + return XMaterial.COBWEB.parseMaterial(); + } + + @Override + public void reStock(Player player) { + int amount = (int) Settings.RESTOCK_AMOUNT.getForArenaState((Arena) getPlugin().getArenaRegistry().getArena(player)); + player.getInventory().addItem(new ItemBuilder(new ItemStack(getMaterial(), amount)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_DESCRIPTION")) + .build()); + + Arena arena = (Arena) getPlugin().getUserManager().getUser(player).getArena(); + if(arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_DESCRIPTION").asKey().build()).send(player); + } else if(arena.getWave() == KitSpecifications.GameTimeState.LATE.getStartWave()) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_DESCRIPTION").asKey().build()).send(player); + } + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + if(user.isSpectator() || !(user.getKit() instanceof TornadoKit)) { + return; + } + Player player = event.getPlayer(); + if(!getPlugin().getArenaRegistry().isInArena(player)) { + return; + } + + ItemStack stack = VersionUtils.getItemInHand(player); + if(!ItemUtils.isItemStackNamed(stack)) { + return; + } + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equalsIgnoreCase(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_TORNADO_NAME").asKey().build())) { + onTornadoCast(stack, user); + } else if(displayName.equalsIgnoreCase(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_NAME").asKey().build())) { + onMonsoonPreCast(stack, user); + } else if(displayName.equalsIgnoreCase(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_NAME").asKey().build())) { + onFinalFlightPreCast(stack, user); + } + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Player)) { + return; + } + Player damager = (Player) event.getDamager(); + if(getPlugin().getArenaRegistry().getArena(damager) == null) { + return; + } + User user = getPlugin().getUserManager().getUser(damager); + if(user.isSpectator() || !(user.getKit() instanceof TornadoKit) + || !ultimateUsers.contains(damager) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + LivingEntity livingEntity = (LivingEntity) event.getEntity(); + new BukkitRunnable() { + int tick = 0; + + @Override + public void run() { + if(tick % 5 == 0) { + livingEntity.setVelocity(new Vector(0, 0.5, 0)); + } + + if(tick % 20 == 0) { + KitHelper.maxHealthPercentDamage(livingEntity, user.getPlayer(), 25.0); + } + if(tick >= 20 * 4 || livingEntity.isDead()) { + this.cancel(); + return; + } + tick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private void onTornadoCast(ItemStack stack, User user) { + getPlugin().getBukkitHelper().takeOneItem(user.getPlayer(), stack); + XSound.ENTITY_FIREWORK_ROCKET_LAUNCH.play(user.getPlayer(), 1f, 0f); + new BukkitRunnable() { + final Vector vector = user.getPlayer().getLocation().getDirection(); + Location location = user.getPlayer().getLocation(); + int angle; + int times = 0; + int pierce = 0; + + @Override + public void run() { + int lines = 3; + for(int l = 0; l < lines; l++) { + for(double y = 0; y < TORNADO_MAX_HEIGHT; y += 0.5) { + double radius = y * TORNADO_RADIUS_INCREMENT, + radians = Math.toRadians(360.0 / lines * l + y * 25 - angle), + x = Math.cos(radians) * radius, + z = Math.sin(radians) * radius; + VersionUtils.sendParticles("CLOUD", null, location.clone().add(x, y, z), 1, 0, 0, 0); + } + } + pierce += pushAndDamageNearbyEnemies(location, vector); + location = location.add(vector.getX() / (3 + Math.random() / 2), 0, vector.getZ() / (3 + Math.random() / 2)); + angle += 50; + times++; + + if(pierce >= 20 || times > 55) { + cancel(); + } + } + }.runTaskTimer(getPlugin(), 1, 1); + } + + private int pushAndDamageNearbyEnemies(Location location, Vector vector) { + int pierce = 0; + for(LivingEntity entity : getNearbyEnemies(location, 2)) { + pierce++; + + Vector velocity = vector.multiply(1.5).setY(0).add(new Vector(0, 1, 0)); + if(VersionUtils.isPaper() && (vector.getX() > 4.0 || vector.getZ() > 4.0)) { + velocity = vector.setX(2.0).setZ(1.0); // Paper's sh*t + } + entity.damage(5.0); + entity.setVelocity(velocity); + } + return pierce; + } + + private void onMonsoonPreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("tornado_monsoon")) { + return; + } + final int castTime = (int) Settings.MONSOON_CAST_TIME.getForArenaState((Arena) user.getArena()); + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Tornado.Monsoon", 20); + user.setCooldown("tornado_monsoon", cooldown); + user.setCooldown("tornado_monsoon_running", castTime); + + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + onMonsoonCast(user); + } + + private void onMonsoonCast(User user) { + Player player = user.getPlayer(); + final int spellTime = (int) Settings.MONSOON_CAST_TIME.getForArenaState((Arena) user.getArena()); + + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_MONSOON_ACTIVE_ACTION_BAR"); + new BukkitRunnable() { + int spellTick = 0; + int messageIndex = 0; + + @Override + public void run() { + if(ServerVersion.Version.isCurrentEqualOrHigher(ServerVersion.Version.v1_9_R1)) { + XParticle.circle(4, 15, ParticleDisplay.simple(player.getLocation().add(0, 0.5, 0), XParticle.getParticle("CLOUD"))); + } + if(spellTick % 5 == 0) { + for(LivingEntity entity : getNearbyEnemies(player.getLocation(), 4)) { + Vector vector = entity.getLocation().toVector().subtract(player.getLocation().toVector()).normalize(); + vector.add(new Vector(0, 0.1, 0)); + entity.setVelocity(vector.multiply(1.5)); + entity.playEffect(EntityEffect.HURT); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 9999, 2, false, true)); + ((Arena) user.getArena()).getAssistHandler().doRegisterDebuffOnEnemy(player, (Creature) entity); + } + XSound.BLOCK_SNOW_STEP.play(player, 1f, 0f); + } + if(spellTick % 10 == 0) { + VersionUtils.sendActionBar(player, messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("tornado_monsoon_running")))); + messageIndex++; + if(messageIndex > messages.size() - 1) { + messageIndex = 0; + } + } + if(spellTick >= 20 * spellTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + cancel(); + return; + } + spellTick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private List getNearbyEnemies(Location location, int radius) { + return location.getWorld() + .getNearbyEntities(location, radius, radius, radius) + .stream() + .filter(CreatureUtils::isEnemy) + .map(e -> (LivingEntity) e) + .collect(Collectors.toList()); + } + + private void onFinalFlightPreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("tornado_final_flight")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Tornado.Final-Flight", 45); + user.setCooldown("tornado_final_flight", cooldown); + int castTime = 10; + user.setCooldown("tornado_final_flight_running", castTime); + + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + onFinalFlightCast(user); + } + + private void onFinalFlightCast(User user) { + Player player = user.getPlayer(); + final int spellTime = 10; + ultimateUsers.add(user.getPlayer()); + + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FINAL_FLIGHT_ACTIVE_ACTION_BAR"); + new BukkitRunnable() { + int spellTick = 0; + int messageIndex = 0; + + @Override + public void run() { + if(spellTick % 10 == 0) { + VersionUtils.sendActionBar(player, messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("tornado_final_flight_running")))); + messageIndex++; + if(messageIndex > messages.size() - 1) { + messageIndex = 0; + } + } + if(spellTick >= 20 * spellTime || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + ultimateUsers.remove(user.getPlayer()); + cancel(); + return; + } + spellTick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> ultimateUsers.remove(user.getPlayer()), spellTime * 20L); + } + + private enum Settings { + RESTOCK_AMOUNT(2, 3, 5), MONSOON_CAST_TIME(6, 9, 12); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return earlyValue; + case MID: + return midValue; + case EARLY: + default: + return lateValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/WizardKit.java b/src/main/java/plugily/projects/villagedefense/kits/WizardKit.java new file mode 100644 index 000000000..ef3a567b9 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/WizardKit.java @@ -0,0 +1,371 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits; + +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import plugily.projects.minigamesbox.classic.handlers.language.Message; +import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; +import plugily.projects.minigamesbox.classic.handlers.language.MessageManager; +import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; +import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; +import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; +import plugily.projects.minigamesbox.classic.utils.version.ServerVersion; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; +import plugily.projects.minigamesbox.classic.utils.version.xseries.ParticleDisplay; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XParticle; +import plugily.projects.minigamesbox.classic.utils.version.xseries.XSound; +import plugily.projects.villagedefense.arena.Arena; +import plugily.projects.villagedefense.creatures.CreatureUtils; +import plugily.projects.villagedefense.kits.ability.AbilitySource; +import plugily.projects.villagedefense.kits.utils.KitHelper; +import plugily.projects.villagedefense.kits.utils.KitSpecifications; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Plajer + *

+ * Created at 01.03.2018 + *

+ */ +public class WizardKit extends PremiumKit implements Listener, AbilitySource { + + private static final String LANGUAGE_ACCESSOR = "KIT_CONTENT_WIZARD_"; + private final List abilityUsers = new ArrayList<>(); + + public WizardKit() { + registerMessages(); + setName(new MessageBuilder(LANGUAGE_ACCESSOR + "NAME").asKey().build()); + setKey("Wizard"); + List description = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "DESCRIPTION"); + setDescription(description); + getPlugin().getKitRegistry().registerKit(this); + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + } + + private void registerMessages() { + MessageManager manager = getPlugin().getMessageManager(); + manager.registerMessage(LANGUAGE_ACCESSOR + "NAME", new Message("Kit.Content.Wizard.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "DESCRIPTION", new Message("Kit.Content.Wizard.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_NAME", new Message("Kit.Content.Wizard.Game-Item.Wand.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_DESCRIPTION", new Message("Kit.Content.Wizard.Game-Item.Wand.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_NAME", new Message("Kit.Content.Wizard.Game-Item.Flower.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_DESCRIPTION", new Message("Kit.Content.Wizard.Game-Item.Flower.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_ACTIVATE", new Message("Kit.Content.Wizard.Game-Item.Flower.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_NAME", new Message("Kit.Content.Wizard.Game-Item.Bloodlust.Name", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_DESCRIPTION", new Message("Kit.Content.Wizard.Game-Item.Bloodlust.Description", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_ACTIVATE", new Message("Kit.Content.Wizard.Game-Item.Bloodlust.Activate", "")); + manager.registerMessage(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_ACTIVE_ACTION_BAR", new Message("Kit.Content.Wizard.Game-Item.Bloodlust.Active-Action-Bar", "")); + } + + @Override + public boolean isUnlockedByPlayer(Player player) { + return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.wizard"); + } + + @Override + public void giveKitItems(Player player) { + player.getInventory().setItem(3, new ItemBuilder(getMaterial()) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_DESCRIPTION")) + .build()); + player.getInventory().setItem(4, new ItemBuilder(new ItemStack(XMaterial.POPPY.parseMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_DESCRIPTION")) + .build()); + player.getInventory().setItem(5, new ItemBuilder(new ItemStack(XMaterial.SPIDER_EYE.parseMaterial(), 1)) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_DESCRIPTION")) + .build()); + + ArmorHelper.setColouredArmor(Color.fromRGB(100, 149, 237), player); + player.getInventory().setItem(8, new ItemStack(Material.SADDLE)); + } + + @Override + public Material getMaterial() { + return Material.BLAZE_ROD; + } + + @Override + public void reStock(Player player) { + Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); + boolean giveItem; + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + giveItem = arena.getWave() % 2 == 0; + break; + case MID: + case EARLY: + default: + giveItem = arena.getWave() % 3 == 0; + break; + } + if(giveItem) { + player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.POPPY.parseMaterial())) + .name(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_NAME").asKey().build()) + .lore(getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_DESCRIPTION")) + .build()); + } + if(arena.getWave() == KitSpecifications.GameTimeState.MID.getStartWave()) { + new MessageBuilder("KIT_ABILITY_UNLOCKED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_NAME").asKey().build()).send(player); + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_NAME").asKey().build()).send(player); + } else if(arena.getWave() == KitSpecifications.GameTimeState.LATE.getStartWave()) { + new MessageBuilder("KIT_ABILITY_POWER_INCREASED").asKey().value(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_NAME").asKey().build()).send(player); + } + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Player)) { + return; + } + Player damager = (Player) event.getDamager(); + if(getPlugin().getArenaRegistry().getArena(damager) == null) { + return; + } + User user = getPlugin().getUserManager().getUser(damager); + if(user.isSpectator() || !(user.getKit() instanceof WizardKit) + || !abilityUsers.contains(damager) || !CreatureUtils.isEnemy(event.getEntity())) { + return; + } + LivingEntity entity = (LivingEntity) event.getEntity(); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 3, 3, false, true)); + entity.setFireTicks(20 * 3); + ((Arena) user.getArena()).getAssistHandler().doRegisterDebuffOnEnemy(user.getPlayer(), (Creature) entity); + } + + @Override + @EventHandler + public void onAbilityCast(PlugilyPlayerInteractEvent event) { + if(!KitHelper.isInGameWithKitAndItemInHand(event.getPlayer(), WizardKit.class)) { + return; + } + ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); + User user = getPlugin().getUserManager().getUser(event.getPlayer()); + String displayName = ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()); + if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_NAME").asKey().build())) { + event.setCancelled(true); + onBloodlustPreCast(stack, user); + } else if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_NAME").asKey().build())) { + event.setCancelled(true); + onCorruptingFlowerCast(stack, user); + } else if(displayName.equals(new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_WAND_NAME").asKey().build())) { + event.setCancelled(true); + onWandPreCast(stack, user); + } + } + + private void onBloodlustPreCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("wizard_bloodlust")) { + return; + } + if(KitSpecifications.getTimeState((Arena) user.getArena()) == KitSpecifications.GameTimeState.EARLY) { + new MessageBuilder("KIT_LOCKED_TILL").asKey().integer(16).send(user.getPlayer()); + return; + } + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Wizard.Bloodlust", 70); + user.setCooldown("wizard_bloodlust", cooldown); + int castTime = 15; + user.setCooldown("wizard_bloodlust_running", castTime); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_ACTIVATE").asKey().send(user.getPlayer()); + + KitHelper.scheduleAbilityCooldown(stack, user.getPlayer(), castTime, cooldown); + onBloodlustCast(user); + } + + private void onBloodlustCast(User user) { + Player player = user.getPlayer(); + player.getWorld().strikeLightningEffect(player.getLocation()); + XSound.ENTITY_WITHER_SPAWN.playRepeatedly(getPlugin(), user.getPlayer(), 0.75f, 2f, 3, 25); + + List messages = getPlugin().getLanguageManager().getLanguageListFromKey(LANGUAGE_ACCESSOR + "GAME_ITEM_BLOODLUST_ACTIVE_ACTION_BAR"); + new BukkitRunnable() { + int damageTick = 0; + int messageIndex = 0; + + @Override + public void run() { + //apply effects only once per second, particles every tick + XParticle.circle(3.5, 28, ParticleDisplay.simple(player.getLocation().add(0, 0.5, 0), XParticle.getParticle("SMOKE_NORMAL"))); + int soundLimit = 5; + if(damageTick % 20 == 0) { + double totalDamage = 0; + for(Entity entity : player.getNearbyEntities(3.5, 3.5, 3.5)) { + if(!CreatureUtils.isEnemy(entity) || entity.equals(player)) { + continue; + } + LivingEntity livingEntity = (LivingEntity) entity; + double damageDone = KitHelper.maxHealthPercentDamage(livingEntity, player, 10.0); + livingEntity.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20, 3, false, true)); + VersionUtils.sendParticles("SUSPENDED", null, entity.getLocation(), 1, 0, 0, 0); + totalDamage += damageDone; + if(soundLimit > 0) { + XSound.ENTITY_WITHER_HURT.play(user.getPlayer(), 0.15f, 0f); + soundLimit--; + } + } + KitHelper.healPlayer(player, totalDamage * 0.08); + } + if(damageTick % 10 == 0) { + VersionUtils.sendActionBar(player, messages.get(messageIndex) + .replace("%number%", String.valueOf(user.getCooldown("wizard_bloodlust_running")))); + messageIndex++; + if(messageIndex > messages.size() - 1) { + messageIndex = 0; + } + } + if(damageTick >= 20 * 15 || !getPlugin().getArenaRegistry().isInArena(user.getPlayer()) || user.isSpectator()) { + //reset action bar + VersionUtils.sendActionBar(player, ""); + cancel(); + return; + } + damageTick++; + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private void onCorruptingFlowerCast(ItemStack stack, User user) { + if(!user.checkCanCastCooldownAndMessage("wizard_flower")) { + return; + } + getPlugin().getBukkitHelper().takeOneItem(user.getPlayer(), stack); + abilityUsers.add(user.getPlayer()); + int cooldown = getKitsConfig().getInt("Kit-Cooldown.Wizard.Flower", 15); + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> abilityUsers.remove(user.getPlayer()), cooldown * 20L); + user.setCooldown("wizard_flower", cooldown); + new MessageBuilder(LANGUAGE_ACCESSOR + "GAME_ITEM_FLOWER_ACTIVATE").asKey().send(user.getPlayer()); + XSound.ENCHANT_THORNS_HIT.play(user.getPlayer(), 1f, 0f); + + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), cooldown * 20); + } + + private void onWandPreCast(ItemStack stack, User user) { + //no cooldown message, this ability is spammy no need for such message + if(user.getCooldown("wizard_staff") > 0) { + return; + } + double cooldown = Settings.WAND_COOLDOWN.getForArenaState((Arena) user.getArena()); + user.setCooldown("wizard_staff", cooldown); + + VersionUtils.setMaterialCooldown(user.getPlayer(), stack.getType(), (int) (cooldown * 20)); + onWandCast(user); + } + + private void onWandCast(User user) { + if(ServerVersion.Version.isCurrentEqualOrHigher(ServerVersion.Version.v1_9_R1)) { + XParticle.drawLine(user.getPlayer(), 40, 1, ParticleDisplay.of(XParticle.getParticle("FLAME"))); + } + final int finalPierce = (int) Settings.DEFAULT_PIERCE.getForArenaState((Arena) user.getArena()); + new BukkitRunnable() { + final Location location = user.getPlayer().getLocation(); + final Vector direction = location.getDirection().normalize(); + double positionModifier = 0; + int pierce = finalPierce; + boolean anyHit = false; + boolean anyKill = false; + + @Override + public void run() { + positionModifier += 1.5; + double x = direction.getX() * positionModifier, + y = direction.getY() * positionModifier, + z = direction.getZ() * positionModifier; + location.add(x, y, z); + boolean localHit = false; + boolean localKill = false; + for(Entity entity : location.getChunk().getEntities()) { + if(pierce <= 0 || !CreatureUtils.isEnemy(entity) || entity.getLocation().distance(location) >= 1.5 || entity.equals(user.getPlayer())) { + continue; + } + LivingEntity livingEntity = (LivingEntity) entity; + double maxHealthPercent = Settings.WAND_PERCENT_DAMAGE.getForArenaState((Arena) user.getArena()); + KitHelper.maxHealthPercentDamage(livingEntity, user.getPlayer(), maxHealthPercent); + localHit = true; + if (entity.isDead() || ((LivingEntity) entity).getHealth() <= 0) { + localKill = true; + } + VersionUtils.sendParticles("DAMAGE_INDICATOR", null, entity.getLocation(), 1, 0, 0, 0); + pierce--; + } + if (localKill && !anyKill) { + XSound.ENTITY_ARROW_HIT_PLAYER.play(user.getPlayer()); + anyKill = true; + anyHit = true; + } + if (localHit && !anyHit) { + XSound.BLOCK_NOTE_BLOCK_HARP.play(user.getPlayer()); + anyHit = true; + } + location.subtract(x, y, z); + if(positionModifier > 40 || pierce <= 0) { + cancel(); + } + } + }.runTaskTimer(getPlugin(), 0, 1); + } + + private enum Settings { + DEFAULT_PIERCE(4, 5, 6), WAND_COOLDOWN(1, 0.75, 0.5), WAND_PERCENT_DAMAGE(20.0, 25.0, 30.0); + + private final double earlyValue; + private final double midValue; + private final double lateValue; + + Settings(double earlyValue, double midValue, double lateValue) { + this.earlyValue = earlyValue; + this.midValue = midValue; + this.lateValue = lateValue; + } + + public double getForArenaState(Arena arena) { + switch(KitSpecifications.getTimeState(arena)) { + case LATE: + return lateValue; + case MID: + return midValue; + case EARLY: + default: + return earlyValue; + } + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/ability/AbilitiesRegistry.java b/src/main/java/plugily/projects/villagedefense/kits/ability/AbilitiesRegistry.java new file mode 100644 index 000000000..c63861a4e --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/ability/AbilitiesRegistry.java @@ -0,0 +1,34 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.ability; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Plajer + *

+ * Created at 16.08.2023 + */ +public class AbilitiesRegistry { + + private final List abilities = new ArrayList<>(); + private final List influences = new ArrayList<>(); + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/ability/Ability.java b/src/main/java/plugily/projects/villagedefense/kits/ability/Ability.java new file mode 100644 index 000000000..3fbcdbdbb --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/ability/Ability.java @@ -0,0 +1,38 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.ability; + +import plugily.projects.minigamesbox.classic.user.User; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +/** + * @author Plajer + *

+ * Created at 16.08.2023 + */ +public class Ability { + + private AbilitySource sourceKit; + private boolean consumable; + private Predicate canCast; + private Consumer onCast; + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/ability/AbilityInfluence.java b/src/main/java/plugily/projects/villagedefense/kits/ability/AbilityInfluence.java new file mode 100644 index 000000000..1b23b78db --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/ability/AbilityInfluence.java @@ -0,0 +1,34 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.ability; + +import plugily.projects.minigamesbox.classic.user.User; + +/** + * @author Plajer + *

+ * Created at 16.08.2023 + */ +public class AbilityInfluence { + + private User abilityCaster; + private AbilitySource sourceKit; + private String abilityId; + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/ability/AbilitySource.java b/src/main/java/plugily/projects/villagedefense/kits/ability/AbilitySource.java new file mode 100644 index 000000000..e96721872 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/ability/AbilitySource.java @@ -0,0 +1,34 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.ability; + +import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; + +/** + * @author Plajer + *

+ * Created at 04.08.2023 + *

+ * Interface that aims to unify all kits abilities together in the upcoming future. + */ +public interface AbilitySource { + + void onAbilityCast(PlugilyPlayerInteractEvent event); + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/free/LightTankKit.java b/src/main/java/plugily/projects/villagedefense/kits/free/LightTankKit.java deleted file mode 100644 index aa218258d..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/free/LightTankKit.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.free; - -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.FreeKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 18/08/2014. - */ -public class LightTankKit extends FreeKit { - - public LightTankKit() { - setName(new MessageBuilder("KIT_CONTENT_LIGHT_TANK_NAME").asKey().build()); - setKey("LightTank"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_LIGHT_TANK_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return true; - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - ArmorHelper.setArmor(player, ArmorHelper.ArmorType.IRON); - VersionUtils.setMaxHealth(player, 26.0); - player.setHealth(26.0); - } - - @Override - public Material getMaterial() { - return Material.LEATHER_CHESTPLATE; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/ArcherKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/ArcherKit.java deleted file mode 100644 index 252eba1d4..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/ArcherKit.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; - -import java.util.List; - -/** - * Created by Tom on 14/08/2014. - */ -public class ArcherKit extends LevelKit { - - public ArcherKit() { - setLevel(getKitsConfig().getInt("Required-Level.Archer")); - setName(new MessageBuilder("KIT_CONTENT_ARCHER_NAME").asKey().build()); - setKey("Archer"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_ARCHER_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.archer"); - } - - @Override - public void giveKitItems(Player player) { - ArmorHelper.setColouredArmor(Color.GREEN, player); - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - player.getInventory().addItem(WeaponHelper.getEnchantedBow(Enchantment.DURABILITY, 10)); - player.getInventory().addItem(new ItemStack(Material.ARROW, 64)); - player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 10)); - } - - @Override - public Material getMaterial() { - return Material.BOW; - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(new ItemStack(Material.ARROW, 15)); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/GolemFriendKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/GolemFriendKit.java deleted file mode 100644 index cd2ac5112..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/GolemFriendKit.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; - -import java.util.List; - -/** - * Created by Tom on 21/07/2015. - */ -public class GolemFriendKit extends LevelKit { - - public GolemFriendKit() { - setName(new MessageBuilder("KIT_CONTENT_GOLEM_FRIEND_NAME").asKey().build()); - setKey("GolemFriend"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_GOLEM_FRIEND_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.GolemFriend")); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.golemfriend"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - ArmorHelper.setColouredArmor(Color.WHITE, player); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); - if(arena != null) { - spawnGolem(player, arena); - } - } - - @Override - public Material getMaterial() { - return Material.IRON_INGOT; - } - - @Override - public void reStock(Player player) { - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); - if(arena != null && arena.getWave() % 5 == 0) { - spawnGolem(player, arena); - } - } - - private void spawnGolem(Player player, Arena arena) { - arena.spawnGolem(arena.getStartLocation(), player); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/HardcoreKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/HardcoreKit.java deleted file mode 100644 index 490887d21..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/HardcoreKit.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 28/07/2015. - */ -public class HardcoreKit extends LevelKit { - - public HardcoreKit() { - setName(new MessageBuilder("KIT_CONTENT_HARDCORE_NAME").asKey().build()); - setKey("Hardcore"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_HARDCORE_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.Hardcore")); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.hardcore"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - ArmorHelper.setColouredArmor(Color.WHITE, player); - player.getInventory().addItem(VersionUtils.getPotion(PotionType.INSTANT_HEAL, 2, true)); - player.getInventory().addItem(new ItemStack(Material.COOKIE, 10)); - VersionUtils.setMaxHealth(player, 10.0); - } - - @Override - public Material getMaterial() { - return XMaterial.PLAYER_HEAD.parseMaterial(); - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(VersionUtils.getPotion(PotionType.INSTANT_HEAL, 2, true)); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/HealerKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/HealerKit.java deleted file mode 100644 index 3d6266720..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/HealerKit.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 18/08/2014. - */ -public class HealerKit extends LevelKit { - - public HealerKit() { - setName(new MessageBuilder("KIT_CONTENT_HEALER_NAME").asKey().build()); - setKey("Healer"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_HEALER_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.Healer")); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.healer"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - ArmorHelper.setColouredArmor(Color.WHITE, player); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - player.getInventory().addItem(VersionUtils.getPotion(PotionType.INSTANT_HEAL, 2, true)); - player.getInventory().addItem(VersionUtils.getPotion(PotionType.REGEN, 1, true)); - } - - @Override - public Material getMaterial() { - return XMaterial.POPPY.parseMaterial(); - } - - @Override - public void reStock(Player player) { - for(int i = 0; i < 2; i++) { - player.getInventory().addItem(VersionUtils.getPotion(PotionType.INSTANT_HEAL, 2, true)); - } - for(int i = 0; i < 2; i++) { - player.getInventory().addItem(VersionUtils.getPotion(PotionType.REGEN, 1, true)); - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/LooterKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/LooterKit.java deleted file mode 100644 index 2d96fcf3f..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/LooterKit.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -import java.util.List; - -/** - * Created by Tom on 21/07/2015. - */ -public class LooterKit extends LevelKit implements Listener { - - public LooterKit() { - setName(new MessageBuilder("KIT_CONTENT_LOOTER_NAME").asKey().build()); - setKey("Looter"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_LOOTER_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.Looter")); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.looter"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - ArmorHelper.setColouredArmor(Color.ORANGE, player); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - } - - @Override - public Material getMaterial() { - return Material.ROTTEN_FLESH; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } - - @EventHandler - public void onDeath(EntityDeathEvent event) { - org.bukkit.entity.LivingEntity entity = event.getEntity(); - if(!(CreatureUtils.isEnemy(entity)) || entity.getKiller() == null) { - return; - } - Player player = entity.getKiller(); - if(getPlugin().getArenaRegistry().getArena(player) == null) { - return; - } - if(getPlugin().getUserManager().getUser(player).getKit() instanceof LooterKit) { - player.getInventory().addItem(new ItemStack(getMaterial(), 1)); - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/MediumTankKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/MediumTankKit.java deleted file mode 100644 index 888486b4b..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/MediumTankKit.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 19/08/2014. - */ -public class MediumTankKit extends LevelKit { - - public MediumTankKit() { - setName(new MessageBuilder("KIT_CONTENT_MEDIUM_TANK_NAME").asKey().build()); - setKey("MediumTank"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_MEDIUM_TANK_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.MediumTank")); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= this.getLevel() || player.hasPermission("villagedefense.kit.mediumtank"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - ArmorHelper.setArmor(player, ArmorHelper.ArmorType.IRON); - VersionUtils.setMaxHealth(player, 32.0); - player.setHealth(32.0); - } - - @Override - public Material getMaterial() { - return Material.IRON_CHESTPLATE; - } - - @Override - public void reStock(Player player) { - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/PuncherKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/PuncherKit.java deleted file mode 100644 index f8554486e..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/PuncherKit.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 18/08/2014. - */ -public class PuncherKit extends LevelKit { - - public PuncherKit() { - setName(new MessageBuilder("KIT_CONTENT_PUNCHER_NAME").asKey().build()); - setKey("Puncher"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_PUNCHER_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.Puncher")); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.puncher"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getEnchanted(XMaterial.DIAMOND_SHOVEL.parseItem(), new Enchantment[]{ - Enchantment.DURABILITY, Enchantment.KNOCKBACK, Enchantment.DAMAGE_ALL}, new int[]{10, 5, 2})); - ArmorHelper.setColouredArmor(Color.BLACK, player); - player.getInventory().addItem(WeaponHelper.getEnchantedBow(Enchantment.DURABILITY, 5)); - player.getInventory().addItem(new ItemStack(Material.ARROW, 25)); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - } - - @Override - public Material getMaterial() { - return XMaterial.DIAMOND_SHOVEL.parseMaterial(); - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/RunnerKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/RunnerKit.java deleted file mode 100644 index 94aedd81a..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/RunnerKit.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 18/08/2014. - */ -public class RunnerKit extends LevelKit { - - public RunnerKit() { - setLevel(getKitsConfig().getInt("Required-Level.Runner")); - setName(new MessageBuilder("KIT_CONTENT_RUNNER_NAME").asKey().build()); - setKey("Runner"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_RUNNER_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.runner"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getEnchanted(new ItemStack(Material.STICK), new Enchantment[]{ - Enchantment.KNOCKBACK, Enchantment.DAMAGE_UNDEAD, Enchantment.DURABILITY}, new int[]{2, 1, 10})); - ArmorHelper.setColouredArmor(Color.BLUE, player); - player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 2)); - player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 1)); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - } - - @Override - public Material getMaterial() { - return XMaterial.FIREWORK_ROCKET.parseMaterial(); - } - - @Override - public void reStock(Player player) { - player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 2)); - player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 1)); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/TerminatorKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/TerminatorKit.java deleted file mode 100644 index cacbc2a81..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/TerminatorKit.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 18/07/2015. - */ -public class TerminatorKit extends LevelKit { - - public TerminatorKit() { - setName(new MessageBuilder("KIT_CONTENT_TERMINATOR_NAME").asKey().build()); - setKey("Terminator"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_TERMINATOR_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.Terminator")); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.terminator"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - player.getInventory().addItem(WeaponHelper.getEnchanted(new ItemStack(Material.BONE), new Enchantment[]{Enchantment.DAMAGE_ALL, Enchantment.KNOCKBACK}, new int[]{3, 7})); - ArmorHelper.setColouredArmor(Color.BLACK, player); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - player.getInventory().addItem(VersionUtils.getPotion(PotionType.STRENGTH, 2, true)); - player.getInventory().addItem(VersionUtils.getPotion(PotionType.REGEN, 1, true)); - } - - @Override - public Material getMaterial() { - return Material.ANVIL; - } - - @Override - public void reStock(Player player) { - for(int i = 0; i < 2; i++) { - player.getInventory().addItem(VersionUtils.getPotion(PotionType.STRENGTH, 2, true)); - } - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/WorkerKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/WorkerKit.java deleted file mode 100644 index c31c57456..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/WorkerKit.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.utils.Utils; - -import java.util.List; - -/** - * Created by Tom on 19/07/2015. - */ -public class WorkerKit extends LevelKit implements Listener { - - public WorkerKit() { - setLevel(getKitsConfig().getInt("Required-Level.Worker")); - setName(new MessageBuilder("KIT_CONTENT_WORKER_NAME").asKey().build()); - setKey("Worker"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_WORKER_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getUserManager().getUser(player).getStatistic("LEVEL") >= getLevel() || player.hasPermission("villagedefense.kit.worker"); - } - - @Override - public void giveKitItems(Player player) { - ArmorHelper.setColouredArmor(Color.PURPLE, player); - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - player.getInventory().addItem(WeaponHelper.getEnchantedBow(Enchantment.DURABILITY, 10)); - player.getInventory().addItem(new ItemStack(XMaterial.ARROW.parseMaterial(), 64)); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_BEEF.parseMaterial(), 10)); - player.getInventory().addItem(new ItemStack(getMaterial(), 2)); - } - - @Override - public Material getMaterial() { - return Utils.getCachedDoor(null); - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(new ItemStack(getMaterial())); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onDoorPlace(BlockPlaceEvent event) { - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(event.getPlayer()); - if(arena == null) { - return; - } - if(getPlugin().getUserManager().getUser(event.getPlayer()).isSpectator() || !arena.getMapRestorerManager().getGameDoorLocations() - .containsKey(event.getBlock().getLocation())) { - event.setCancelled(true); - return; - } - if(VersionUtils.getItemInHand(event.getPlayer()).getType() != Utils.getCachedDoor(event.getBlock())) { - event.setCancelled(true); - return; - } - //to override world guard protection - event.setCancelled(false); - new MessageBuilder("KIT_CONTENT_WORKER_GAME_ITEM_CHAT").asKey().player(event.getPlayer()).sendPlayer(); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/level/ZombieFinderKit.java b/src/main/java/plugily/projects/villagedefense/kits/level/ZombieFinderKit.java deleted file mode 100644 index 1f5e38a13..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/level/ZombieFinderKit.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.level; - -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Creature; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.LevelKit; -import plugily.projects.minigamesbox.classic.user.User; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; - -import java.util.List; -import java.util.Random; - -/** - * Created by Tom on 21/07/2015. - */ -public class ZombieFinderKit extends LevelKit implements Listener { - - public ZombieFinderKit() { - setName(new MessageBuilder("KIT_CONTENT_ZOMBIE_TELEPORTER_NAME").asKey().build()); - setKey("ZombieFinder"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_ZOMBIE_TELEPORTER_DESCRIPTION"); - setDescription(description); - setLevel(getKitsConfig().getInt("Required-Level.ZombieFinder")); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return true; - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - player.getInventory().addItem(new ItemBuilder(WeaponHelper.getEnchanted(new ItemStack(Material.BOOK), new Enchantment[]{Enchantment.DAMAGE_ALL}, new int[]{1})) - .name(new MessageBuilder("KIT_CONTENT_ZOMBIE_TELEPORTER_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_ZOMBIE_TELEPORTER_GAME_ITEM_DESCRIPTION")) - .build()); - } - - @Override - public Material getMaterial() { - return Material.FISHING_ROD; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } - - @EventHandler - public void onTeleport(PlugilyPlayerInteractEvent event) { - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(event.getPlayer()); - if(arena == null || !ItemUtils.isItemStackNamed(event.getItem()) || event.getItem().getType() != Material.BOOK - || !ComplementAccessor.getComplement().getDisplayName(event.getItem().getItemMeta()).equals(new MessageBuilder("KIT_CONTENT_ZOMBIE_TELEPORTER_GAME_ITEM_GUI").asKey().build())) { - return; - } - User user = getPlugin().getUserManager().getUser(event.getPlayer()); - if(user.isSpectator()) { - new MessageBuilder("IN_GAME_SPECTATOR_SPECTATOR_WARNING").asKey().player(user.getPlayer()).sendPlayer(); - return; - } - if(!(user.getKit() instanceof ZombieFinderKit)) { - return; - } - double zombieCooldown = user.getCooldown("zombie"); - if(zombieCooldown > 0 && !user.isSpectator()) { - new MessageBuilder("KIT_COOLDOWN").asKey().integer((int) zombieCooldown).player(user.getPlayer()).sendPlayer(); - return; - } - if(arena.getEnemies().isEmpty()) { - new MessageBuilder("KIT_CONTENT_ZOMBIE_TELEPORTER_TELEPORT_NOT_FOUND").asKey().player(user.getPlayer()).sendPlayer(); - return; - } - - Creature creature = arena.getEnemies().get(arena.getEnemies().size() == 1 ? 0 : getPlugin().getRandom().nextInt(arena.getEnemies().size())); - VersionUtils.teleport(creature, event.getPlayer().getLocation()); - creature.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 20 * 30, 0)); - new MessageBuilder("KIT_CONTENT_ZOMBIE_TELEPORTER_TELEPORT_ZOMBIE").asKey().player(user.getPlayer()).sendPlayer(); - VersionUtils.playSound(event.getPlayer().getLocation(), "ENTITY_ZOMBIE_DEATH"); - user.setCooldown("zombie", getKitsConfig().getInt("Kit-Cooldown.Zombie-Finder", 30)); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/BlockerKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/BlockerKit.java deleted file mode 100644 index f07684de4..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/BlockerKit.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; -import plugily.projects.minigamesbox.classic.arena.PluginArena; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; - -import java.util.List; - -/** - * Created by Tom on 17/12/2015. - */ -public class BlockerKit extends PremiumKit implements Listener { - - public BlockerKit() { - setName(new MessageBuilder("KIT_CONTENT_BLOCKER_NAME").asKey().build()); - setKey("Blocker"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_BLOCKER_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.blocker"); - } - - @Override - public void giveKitItems(Player player) { - ArmorHelper.setColouredArmor(Color.RED, player); - player.getInventory().addItem(WeaponHelper.getEnchanted(new ItemStack(Material.STONE_SWORD), new org.bukkit.enchantments.Enchantment[]{org.bukkit.enchantments.Enchantment.DURABILITY}, new int[]{10})); - player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 10)); - player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.OAK_FENCE.parseMaterial(), 3)) - .name(new MessageBuilder("KIT_CONTENT_BLOCKER_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_BLOCKER_GAME_ITEM_DESCRIPTION")) - .build()); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - - } - - @Override - public Material getMaterial() { - return Material.BARRIER; - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.OAK_FENCE.parseMaterial(), 3)) - .name(new MessageBuilder("KIT_CONTENT_BLOCKER_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_BLOCKER_GAME_ITEM_DESCRIPTION")) - .build()); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onBarrierPlace(PlugilyPlayerInteractEvent event) { - if(event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - - Player player = event.getPlayer(); - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); - if(arena == null) - return; - - ItemStack stack = VersionUtils.getItemInHand(player); - if(!ItemUtils.isItemStackNamed(stack) || !ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()) - .equalsIgnoreCase(new MessageBuilder("KIT_CONTENT_BLOCKER_GAME_ITEM_NAME").asKey().build())) { - return; - } - if(!(getPlugin().getUserManager().getUser(player).getKit() instanceof BlockerKit)) { - return; - } - Block block = null; - for(Block blocks : player.getLastTwoTargetBlocks(null, 5)) { - if(blocks.getType() == Material.AIR) { - block = blocks; - } - } - if(block == null) { - new MessageBuilder("KIT_CONTENT_BLOCKER_PLACE_FAIL").asKey().player(player).sendPlayer(); - return; - } - getPlugin().getBukkitHelper().takeOneItem(player, stack); - event.setCancelled(false); - - new MessageBuilder("KIT_CONTENT_BLOCKER_PLACE_SUCCESS").asKey().player(player).sendPlayer(); - ZombieBarrier zombieBarrier = new ZombieBarrier(); - zombieBarrier.setLocation(block.getLocation()); - - VersionUtils.sendParticles("FIREWORKS_SPARK", arena.getPlayers(), zombieBarrier.location, 20); - removeBarrierLater(zombieBarrier, arena); - block.setType(XMaterial.OAK_FENCE.parseMaterial()); - } - - private void removeBarrierLater(ZombieBarrier zombieBarrier, PluginArena arena) { - new BukkitRunnable() { - @Override - public void run() { - zombieBarrier.decrementSeconds(); - - if(zombieBarrier.seconds <= 0) { - zombieBarrier.location.getBlock().setType(Material.AIR); - VersionUtils.sendParticles("FIREWORKS_SPARK", arena.getPlayers(), zombieBarrier.location, 20); - cancel(); - } - } - }.runTaskTimer(getPlugin(), 20, 20); - } - - private static class ZombieBarrier { - private Location location; - private int seconds = 10; - - void setLocation(Location location) { - this.location = location; - } - - void decrementSeconds() { - seconds--; - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/CleanerKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/CleanerKit.java deleted file mode 100644 index 3b5432be8..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/CleanerKit.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.user.User; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.villagedefense.arena.Arena; -import plugily.projects.villagedefense.arena.ArenaUtils; - -import java.util.List; - -/** - * Created by Tom on 18/08/2014. - */ -public class CleanerKit extends PremiumKit implements Listener { - - public CleanerKit() { - setName(new MessageBuilder("KIT_CONTENT_CLEANER_NAME").asKey().build()); - setKey("Cleaner"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_CLEANER_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.cleaner"); - } - - @Override - public void giveKitItems(Player player) { - ArmorHelper.setColouredArmor(Color.YELLOW, player); - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.WOOD, 10)); - player.getInventory().addItem(new ItemBuilder(Material.BLAZE_ROD) - .name(new MessageBuilder("KIT_CONTENT_CLEANER_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_CLEANER_GAME_ITEM_DESCRIPTION")) - .build()); - player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 10)); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - } - - @Override - public Material getMaterial() { - return Material.BLAZE_POWDER; - } - - @Override - public void reStock(Player player) { - } - - @EventHandler - public void onClean(PlugilyPlayerInteractEvent event) { - ItemStack itemStack = event.getItem(); - if(itemStack == null || itemStack.getType() != Material.BLAZE_ROD) - return; - - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(event.getPlayer()); - if(arena == null || !ItemUtils.isItemStackNamed(itemStack) - || !ComplementAccessor.getComplement().getDisplayName(itemStack.getItemMeta()) - .contains(new MessageBuilder("KIT_CONTENT_CLEANER_GAME_ITEM_NAME").asKey().build())) { - return; - } - User user = getPlugin().getUserManager().getUser(event.getPlayer()); - if(!(user.getKit() instanceof CleanerKit)) { - return; - } - if(user.isSpectator()) { - new MessageBuilder("IN_GAME_SPECTATOR_SPECTATOR_WARNING").asKey().player(user.getPlayer()).sendPlayer(); - return; - } - double cooldown = user.getCooldown("clean"); - if(cooldown > 0 && !user.isSpectator()) { - new MessageBuilder("KIT_COOLDOWN").asKey().integer((int) cooldown).player(user.getPlayer()).sendPlayer(); - return; - } - if(arena.getEnemies().isEmpty()) { - new MessageBuilder("KIT_CONTENT_CLEANER_CLEANED_NOTHING").asKey().player(user.getPlayer()).sendPlayer(); - return; - } - int amount = getKitsConfig().getInt("Kit-Settings.Cleaner.Base-Amount", 10); - if(amount < arena.getEnemies().size()) { - int increaseUnit = arena.getWave() / Math.max(1, getKitsConfig().getInt("Kit-Settings.Cleaner.Increase-After-Wave", 5)); - amount += increaseUnit * Math.max(0, getKitsConfig().getInt("Kit-Settings.Cleaner.Increase-Amount", 5)); - amount = Math.min(amount, getKitsConfig().getInt("Kit-Settings.Cleaner.Max-Amount", 50)); - } - ArenaUtils.removeSpawnedEnemies(arena, amount, getKitsConfig().getDouble("Kit-Settings.Cleaner.Max-Health", 2048)); - - VersionUtils.playSound(event.getPlayer().getLocation(), "ENTITY_ZOMBIE_DEATH"); - new MessageBuilder("KIT_CONTENT_CLEANER_CLEANED_MAP").asKey().arena(arena).player(user.getPlayer()).sendArena(); - user.setCooldown("clean", getKitsConfig().getInt("Kit-Cooldown.Cleaner", 60)); - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/DogFriendKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/DogFriendKit.java deleted file mode 100644 index 6a2bdf124..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/DogFriendKit.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.arena.Arena; - -import java.util.List; - -/** - * Created by Tom on 18/07/2015. - */ -public class DogFriendKit extends PremiumKit { - - public DogFriendKit() { - setName(new MessageBuilder("KIT_CONTENT_DOG_FRIEND_NAME").asKey().build()); - setKey("DogFriend"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_DOG_FRIEND_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.dogfriend"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - ArmorHelper.setArmor(player, ArmorHelper.ArmorType.LEATHER); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); - if(arena == null) { - return; - } - org.bukkit.Location start = arena.getStartLocation(); - for(int i = 0; i < 3; i++) { - arena.spawnWolf(start, player); - } - } - - @Override - public Material getMaterial() { - return Material.BONE; - } - - @Override - public void reStock(Player player) { - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); - if(arena != null) { - arena.spawnWolf(arena.getStartLocation(), player); - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/HeavyTankKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/HeavyTankKit.java deleted file mode 100644 index 348dceb43..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/HeavyTankKit.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 19/08/2014. - */ -public class HeavyTankKit extends PremiumKit { - - public HeavyTankKit() { - setName(new MessageBuilder("KIT_CONTENT_HEAVY_TANK_NAME").asKey().build()); - setKey("HeavyTank"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_HEAVY_TANK_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.heavytank"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getEnchanted(new ItemStack(Material.STICK), new Enchantment[]{Enchantment.DURABILITY, Enchantment.DAMAGE_ALL}, new int[]{10, 2})); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - VersionUtils.setMaxHealth(player, 40.0); - player.setHealth(40.0); - ArmorHelper.setArmor(player, ArmorHelper.ArmorType.IRON); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - } - - @Override - public Material getMaterial() { - return Material.DIAMOND_CHESTPLATE; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/MedicKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/MedicKit.java deleted file mode 100644 index ea4864be2..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/MedicKit.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.user.User; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.List; - -/** - * Created by Tom on 1/12/2015. - */ -public class MedicKit extends PremiumKit implements Listener { - - public MedicKit() { - setName(new MessageBuilder("KIT_CONTENT_MEDIC_NAME").asKey().build()); - setKey("Medic"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_MEDIC_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.medic"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - ArmorHelper.setColouredArmor(Color.WHITE, player); - player.getInventory().addItem(new ItemStack(XMaterial.COOKED_PORKCHOP.parseMaterial(), 8)); - player.getInventory().addItem(VersionUtils.getPotion(PotionType.REGEN, 1, true)); - } - - @Override - public Material getMaterial() { - return Material.GHAST_TEAR; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } - - @EventHandler - public void onCreatureHit(EntityDamageByEntityEvent e) { - if(!(e.getEntity() instanceof Creature) || !(e.getDamager() instanceof Player)) { - return; - } - User user = getPlugin().getUserManager().getUser((Player) e.getDamager()); - if(!(user.getKit() instanceof MedicKit) || Math.random() > 0.1) { - return; - } - healNearbyPlayers(e.getDamager()); - } - - private void healNearbyPlayers(Entity en) { - for(Entity entity : en.getNearbyEntities(5, 5, 5)) { - if(!(entity instanceof Player)) { - continue; - } - - Player player = (Player) entity; - double newHealth = player.getHealth() + 1; - double maxHealth = VersionUtils.getMaxHealth(player); - - if(maxHealth > newHealth) { - player.setHealth(newHealth); - } else { - player.setHealth(maxHealth); - } - - VersionUtils.sendParticles("HEART", player, player.getLocation(), 20); - } - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/NakedKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/NakedKit.java deleted file mode 100644 index fec96bd69..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/NakedKit.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionType; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Created by Tom on 8/02/2015. - */ -public class NakedKit extends PremiumKit implements Listener { - - private final List armorTypes = new ArrayList<>(); - - public NakedKit() { - setName(new MessageBuilder("KIT_CONTENT_WILD_NAKED_NAME").asKey().build()); - setKey("Naked"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_WILD_NAKED_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - setupArmorTypes(); - } - - private void setupArmorTypes() { - armorTypes.addAll(Arrays.asList( - Material.LEATHER_BOOTS, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_HELMET, - XMaterial.GOLDEN_BOOTS.parseMaterial(), XMaterial.GOLDEN_CHESTPLATE.parseMaterial(), XMaterial.GOLDEN_LEGGINGS.parseMaterial(), XMaterial.GOLDEN_HELMET.parseMaterial(), - Material.DIAMOND_BOOTS, Material.DIAMOND_LEGGINGS, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_HELMET, - Material.IRON_CHESTPLATE, Material.IRON_BOOTS, Material.IRON_HELMET, Material.IRON_LEGGINGS, - Material.CHAINMAIL_BOOTS, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_HELMET) - ); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return player.hasPermission("villagedefense.kit.naked") || getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player); - } - - @Override - public void giveKitItems(Player player) { - ItemStack itemStack = new ItemStack(getMaterial()); - itemStack.addUnsafeEnchantment(Enchantment.DAMAGE_ALL, 6); - itemStack.addUnsafeEnchantment(Enchantment.DAMAGE_UNDEAD, 2); - itemStack.addUnsafeEnchantment(Enchantment.DURABILITY, 10); - player.getInventory().addItem(itemStack); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - } - - @Override - public Material getMaterial() { - return Material.IRON_SWORD; - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(VersionUtils.getPotion(PotionType.INSTANT_HEAL, 1, true)); - } - - @EventHandler - public void onArmor(InventoryClickEvent event) { - if(!(event.getWhoClicked() instanceof Player)) { - return; - } - Player who = (Player) event.getWhoClicked(); - if(!getPlugin().getArenaRegistry().isInArena(who)) { - return; - } - if(!(getPlugin().getUserManager().getUser(who).getKit() instanceof NakedKit)) { - return; - } - ClickType clickType = event.getClick(); - if(clickType == ClickType.DROP || clickType == ClickType.CONTROL_DROP) { - return; - } - Inventory inventory = event.getClickedInventory(); - if(inventory == null || inventory.getType() != InventoryType.PLAYER) { - return; - } - - boolean hasArmor = false; - ItemStack itemStack = event.getCurrentItem(); - if(itemStack != null && armorTypes.contains(itemStack.getType())) { - hasArmor = true; - } else if(clickType == ClickType.NUMBER_KEY) { - ItemStack hotbarItem = who.getInventory().getItem(event.getHotbarButton()); - if(hotbarItem != null && armorTypes.contains(hotbarItem.getType())) { - hasArmor = true; - } - } - if(hasArmor) { - new MessageBuilder("KIT_CONTENT_WILD_NAKED_CANNOT_WEAR_ARMOR").asKey().send(who); - event.setCancelled(true); - } - } - - @EventHandler - public void onArmorClick(PlugilyPlayerInteractEvent event) { - if(!getPlugin().getArenaRegistry().isInArena(event.getPlayer())) { - return; - } - if(!(getPlugin().getUserManager().getUser(event.getPlayer()).getKit() instanceof NakedKit) || !event.hasItem()) { - return; - } - if(armorTypes.contains(event.getItem().getType())) { - event.setCancelled(true); - new MessageBuilder("KIT_CONTENT_WILD_NAKED_CANNOT_WEAR_ARMOR").asKey().player(event.getPlayer()).sendPlayer(); - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/PremiumHardcoreKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/PremiumHardcoreKit.java deleted file mode 100644 index b2fc89699..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/PremiumHardcoreKit.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; - -import java.util.List; - -/** - * Created by Tom on 28/07/2015. - */ -public class PremiumHardcoreKit extends PremiumKit { - - public PremiumHardcoreKit() { - setName(new MessageBuilder("KIT_CONTENT_PREMIUM_HARDCORE_NAME").asKey().build()); - setKey("PremiumHardcore"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_PREMIUM_HARDCORE_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.premiumhardcore"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getEnchanted(new ItemStack(getMaterial()), - new Enchantment[]{Enchantment.DAMAGE_ALL}, new int[]{11})); - VersionUtils.setMaxHealth(player, 6); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - } - - @Override - public Material getMaterial() { - return Material.DIAMOND_SWORD; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } - - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/ShotBowKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/ShotBowKit.java deleted file mode 100644 index e545a36f9..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/ShotBowKit.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Arrow; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.inventory.ItemStack; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.user.User; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; - -import java.util.List; - - -/** - * Created by Tom on 27/08/2014. - */ -public class ShotBowKit extends PremiumKit implements Listener { - - public ShotBowKit() { - setName(new MessageBuilder("KIT_CONTENT_SHOT_BOW_NAME").asKey().build()); - setKey("ShotBow"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_SHOT_BOW_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.shotbow"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(WeaponHelper.getEnchantedBow(new Enchantment[]{Enchantment.DURABILITY, Enchantment.ARROW_KNOCKBACK}, new int[]{10, 1})); - player.getInventory().addItem(new ItemStack(getMaterial(), 64)); - player.getInventory().addItem(new ItemStack(getMaterial(), 64)); - ArmorHelper.setColouredArmor(Color.YELLOW, player); - player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 8)); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - } - - @Override - public Material getMaterial() { - return Material.ARROW; - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(new ItemStack(getMaterial(), 64)); - } - - @EventHandler - public void onBowInteract(PlugilyPlayerInteractEvent e) { - if(!(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.PHYSICAL)) { - return; - } - - ItemStack stack = VersionUtils.getItemInHand(e.getPlayer()); - if(stack == null || stack.getType() != Material.BOW) - return; - - if(!e.getPlayer().getInventory().contains(getMaterial())) - return; - - User user = getPlugin().getUserManager().getUser(e.getPlayer()); - if(user.isSpectator() || !(user.getKit() instanceof ShotBowKit)) { - return; - } - if(!user.checkCanCastCooldownAndMessage("shotbow")) { - return; - } - for(int i = 0; i < 4; i++) { - Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { - Arrow pr = e.getPlayer().launchProjectile(Arrow.class); - pr.setVelocity(e.getPlayer().getLocation().getDirection().multiply(3)); - pr.setBounce(false); - pr.setShooter(e.getPlayer()); - pr.setCritical(true); - - org.bukkit.inventory.PlayerInventory inv = e.getPlayer().getInventory(); - - if(inv.contains(getMaterial())) { - inv.removeItem(new ItemStack(getMaterial(), 1)); - } - }, 2L * (2 * i)); - } - e.setCancelled(true); - user.setCooldown("shotbow", getKitsConfig().getInt("Kit-Cooldown.Shot-Bow", 5)); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/TeleporterKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/TeleporterKit.java deleted file mode 100644 index 4da48fe44..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/TeleporterKit.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.minigamesbox.inventory.normal.NormalFastInv; -import plugily.projects.villagedefense.arena.Arena; - -import java.util.Collections; -import java.util.List; - -/** - * Created by Tom on 18/08/2014. - */ -public class TeleporterKit extends PremiumKit implements Listener { - - public TeleporterKit() { - setName(new MessageBuilder("KIT_CONTENT_TELEPORTER_NAME").asKey().build()); - setKey("Teleporter"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_TELEPORTER_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.teleporter"); - } - - @Override - public void giveKitItems(Player player) { - ArmorHelper.setArmor(player, ArmorHelper.ArmorType.GOLD); - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - - player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 10)); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - player.getInventory().addItem(new ItemBuilder(Material.GHAST_TEAR) - .name(new MessageBuilder("KIT_CONTENT_TELEPORTER_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_TELEPORTER_GAME_ITEM_DESCRIPTION")) - .build()); - } - - @Override - public Material getMaterial() { - return Material.ENDER_PEARL; - } - - @Override - public void reStock(Player player) { - //no restock items for this kit - } - - @EventHandler - public void onRightClick(PlugilyPlayerInteractEvent e) { - if(!(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)) { - return; - } - Player player = e.getPlayer(); - Arena arena = (Arena) getPlugin().getArenaRegistry().getArena(player); - if(arena == null) { - return; - } - - ItemStack stack = VersionUtils.getItemInHand(player); - if(!ItemUtils.isItemStackNamed(stack)) - return; - - if(!ChatColor.stripColor(ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta())).equalsIgnoreCase(ChatColor.stripColor(new MessageBuilder("KIT_CONTENT_TELEPORTER_GAME_ITEM_NAME").asKey().build()))) { - return; - } - if(!(getPlugin().getUserManager().getUser(player).getKit() instanceof TeleporterKit)) { - return; - } - int slots = arena.getVillagers().size(); - for(Player arenaPlayer : arena.getPlayers()) { - if(getPlugin().getUserManager().getUser(arenaPlayer).isSpectator()) { - continue; - } - slots++; - } - slots = getPlugin().getBukkitHelper().serializeInt(slots); - prepareTeleporterGui(player, arena, slots); - } - - private void prepareTeleporterGui(Player player, Arena arena, int slots) { - NormalFastInv gui = new NormalFastInv(slots, new MessageBuilder("KIT_CONTENT_TELEPORTER_GAME_ITEM_GUI").asKey().build()); - gui.addClickHandler(inventoryClickEvent -> inventoryClickEvent.setCancelled(true)); - for(Player arenaPlayer : arena.getPlayers()) { - if(getPlugin().getUserManager().getUser(arenaPlayer).isSpectator()) { - continue; - } - ItemStack skull = XMaterial.PLAYER_HEAD.parseItem(); - SkullMeta meta = (SkullMeta) skull.getItemMeta(); - meta = VersionUtils.setPlayerHead(player, meta); - ComplementAccessor.getComplement().setDisplayName(meta, arenaPlayer.getName()); - ComplementAccessor.getComplement().setLore(meta, Collections.singletonList("")); - skull.setItemMeta(meta); - gui.addItem(skull, onClick -> { - new MessageBuilder("KIT_CONTENT_TELEPORTER_TELEPORT_PLAYER").asKey().arena(arena).player(arenaPlayer).sendPlayer(); - VersionUtils.teleport(player, arenaPlayer.getLocation()); - VersionUtils.playSound(player.getLocation(), "ENTITY_ENDERMAN_TELEPORT"); - VersionUtils.sendParticles("PORTAL", arena.getPlayers(), player.getLocation(), 30); - player.closeInventory(); - }); - } - for(Villager villager : arena.getVillagers()) { - gui.addItem(new ItemBuilder(new ItemStack(Material.EMERALD)) - .name(villager.getCustomName()) - .lore(villager.getUniqueId().toString()) - .build(), onClick -> { - VersionUtils.teleport(player, villager.getLocation()); - VersionUtils.playSound(player.getLocation(), "ENTITY_ENDERMAN_TELEPORT"); - VersionUtils.sendParticles("PORTAL", arena.getPlayers(), player.getLocation(), 30); - new MessageBuilder("KIT_CONTENT_TELEPORTER_TELEPORT_VILLAGER").asKey().player(player).sendPlayer(); - }); - } - gui.open(player); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/TornadoKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/TornadoKit.java deleted file mode 100644 index 2cd6341da..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/TornadoKit.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; -import plugily.projects.minigamesbox.classic.utils.helper.WeaponHelper; -import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -import java.util.List; - -/** - * Created by Tom on 30/12/2015. - */ -public class TornadoKit extends PremiumKit implements Listener { - - private final int maxHeight = 5; - private final double maxRadius = 4; - private final double radiusIncrement = maxRadius / maxHeight; - private int active = 0; - - public TornadoKit() { - setName(new MessageBuilder("KIT_CONTENT_TORNADO_NAME").asKey().build()); - setKey("Tornado"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_TORNADO_DESCRIPTION"); - setDescription(description); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - getPlugin().getKitRegistry().registerKit(this); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return player.hasPermission("villagedefense.kit.tornado") || getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player); - } - - @Override - public void giveKitItems(Player player) { - ArmorHelper.setArmor(player, ArmorHelper.ArmorType.GOLD); - player.getInventory().addItem(WeaponHelper.getUnBreakingSword(WeaponHelper.ResourceType.STONE, 10)); - - player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 10)); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - player.getInventory().addItem(new ItemBuilder(new ItemStack(getMaterial(), 5)) - .name(new MessageBuilder("KIT_CONTENT_TORNADO_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_TORNADO_GAME_ITEM_DESCRIPTION")) - .build()); - } - - @Override - public Material getMaterial() { - return XMaterial.COBWEB.parseMaterial(); - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(new ItemBuilder(new ItemStack(getMaterial(), 5)) - .name(new MessageBuilder("KIT_CONTENT_TORNADO_GAME_ITEM_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_TORNADO_GAME_ITEM_DESCRIPTION")) - .build()); - } - - @EventHandler - public void onTornadoSpawn(PlugilyPlayerInteractEvent e) { - if(e.getAction() != Action.RIGHT_CLICK_AIR && e.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - - Player player = e.getPlayer(); - if(!getPlugin().getArenaRegistry().isInArena(player)) - return; - - ItemStack stack = VersionUtils.getItemInHand(player); - if(!ItemUtils.isItemStackNamed(stack) - || !ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()).equalsIgnoreCase(new MessageBuilder("KIT_CONTENT_TORNADO_GAME_ITEM_NAME").asKey().build())) { - return; - } - if(!(getPlugin().getUserManager().getUser(player).getKit() instanceof TornadoKit)) { - return; - } - if(active >= 2) { - return; - } - getPlugin().getBukkitHelper().takeOneItem(player, stack); - e.setCancelled(true); - prepareTornado(player.getLocation()); - } - - private void prepareTornado(Location location) { - Tornado tornado = new Tornado(location); - active++; - new BukkitRunnable() { - @Override - public void run() { - tornado.update(); - if(tornado.entities >= 7 || tornado.times > 55) { - cancel(); - active--; - } - } - }.runTaskTimer(getPlugin(), 1, 1); - } - - private class Tornado { - private Location location; - private final Vector vector; - private int angle; - private int times = 0; - private int entities = 0; - - Tornado(Location location) { - this.location = location; - vector = location.getDirection(); - } - - void setLocation(Location location) { - this.location = location; - } - - void update() { - times++; - int lines = 3; - for(int l = 0; l < lines; l++) { - for(double y = 0; y < maxHeight; y += 0.5) { - double radius = y * radiusIncrement, - radians = Math.toRadians(360.0 / lines * l + y * 25 - angle), - x = Math.cos(radians) * radius, - z = Math.sin(radians) * radius; - VersionUtils.sendParticles("CLOUD", null, location.clone().add(x, y, z), 1, 0, 0, 0); - } - } - pushNearbyEnemies(); - setLocation(location.add(vector.getX() / (3 + Math.random() / 2), 0, vector.getZ() / (3 + Math.random() / 2))); - - angle += 50; - } - - private void pushNearbyEnemies() { - for(Entity entity : location.getWorld().getNearbyEntities(location, 2, 2, 2)) { - if(CreatureUtils.isEnemy(entity)) { - entities++; - - Vector velocityVec = vector.multiply(2).setY(0).add(new Vector(0, 1, 0)); - if(VersionUtils.isPaper() && (vector.getX() > 4.0 || vector.getZ() > 4.0)) { - velocityVec = vector.setX(2.0).setZ(1.0); // Paper's sh*t - } - - entity.setVelocity(velocityVec); - } - } - } - } -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/premium/WizardKit.java b/src/main/java/plugily/projects/villagedefense/kits/premium/WizardKit.java deleted file mode 100644 index 55fb0cc30..000000000 --- a/src/main/java/plugily/projects/villagedefense/kits/premium/WizardKit.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package plugily.projects.villagedefense.kits.premium; - -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Creature; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; -import plugily.projects.minigamesbox.classic.handlers.language.MessageBuilder; -import plugily.projects.minigamesbox.classic.kits.basekits.PremiumKit; -import plugily.projects.minigamesbox.classic.user.User; -import plugily.projects.minigamesbox.classic.utils.helper.ArmorHelper; -import plugily.projects.minigamesbox.classic.utils.helper.ItemBuilder; -import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; -import plugily.projects.minigamesbox.classic.utils.misc.complement.ComplementAccessor; -import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; -import plugily.projects.minigamesbox.classic.utils.version.events.api.PlugilyPlayerInteractEvent; -import plugily.projects.minigamesbox.classic.utils.version.xseries.XMaterial; -import plugily.projects.villagedefense.creatures.CreatureUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Plajer - *

- * Created at 01.03.2018 - */ -public class WizardKit extends PremiumKit implements Listener { - - private final List wizardsOnDuty = new ArrayList<>(); - - public WizardKit() { - setName(new MessageBuilder("KIT_CONTENT_WIZARD_NAME").asKey().build()); - setKey("Wizard"); - List description = getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_WIZARD_DESCRIPTION"); - setDescription(description); - getPlugin().getKitRegistry().registerKit(this); - getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); - } - - @Override - public boolean isUnlockedByPlayer(Player player) { - return getPlugin().getPermissionsManager().hasPermissionString("KIT_PREMIUM_UNLOCK", player) || player.hasPermission("villagedefense.kit.wizard"); - } - - @Override - public void giveKitItems(Player player) { - player.getInventory().addItem(new ItemBuilder(getMaterial()) - .name(new MessageBuilder("KIT_CONTENT_WIZARD_GAME_ITEM_WAND_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_WIZARD_GAME_ITEM_WAND_DESCRIPTION")) - .build()); - player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.INK_SAC.parseMaterial(), 4)) - .name(new MessageBuilder("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_DESCRIPTION")) - .build()); - - ArmorHelper.setColouredArmor(Color.GRAY, player); - player.getInventory().addItem(new ItemStack(Material.SADDLE)); - - } - - @Override - public Material getMaterial() { - return Material.BLAZE_ROD; - } - - @Override - public void reStock(Player player) { - player.getInventory().addItem(new ItemBuilder(new ItemStack(XMaterial.INK_SAC.parseMaterial())) - .name(new MessageBuilder("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_NAME").asKey().build()) - .lore(getPlugin().getLanguageManager().getLanguageListFromKey("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_DESCRIPTION")) - .build()); - } - - @EventHandler - public void onQuit(PlayerQuitEvent e) { - wizardsOnDuty.remove(e.getPlayer()); - } - - @EventHandler - public void onWizardDamage(EntityDamageByEntityEvent event) { - if(!(event.getDamager() instanceof Creature && event.getEntity() instanceof Player)) { - return; - } - if(!wizardsOnDuty.contains(event.getEntity()) || getPlugin().getArenaRegistry().getArena((Player) event.getEntity()) == null) { - return; - } - ((Creature) event.getDamager()).damage(2.0, event.getEntity()); - } - - @EventHandler - public void onStaffUse(PlugilyPlayerInteractEvent event) { - if(getPlugin().getArenaRegistry().getArena(event.getPlayer()) == null) { - return; - } - - User user = getPlugin().getUserManager().getUser(event.getPlayer()); - if(user.isSpectator() || !(user.getKit() instanceof WizardKit)) { - return; - } - - ItemStack stack = VersionUtils.getItemInHand(event.getPlayer()); - if(!ItemUtils.isItemStackNamed(stack)) { - return; - } - Player player = event.getPlayer(); - if(ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()).equals(new MessageBuilder("KIT_CONTENT_WIZARD_GAME_ITEM_ESSENCE_NAME").asKey().build())) { - if(!user.checkCanCastCooldownAndMessage("essence")) { - return; - } - wizardsOnDuty.add(player); - if(VersionUtils.getMaxHealth(player) > (player.getHealth() + 3)) { - player.setHealth(player.getHealth() + 3); - } else { - player.setHealth(VersionUtils.getMaxHealth(player)); - } - getPlugin().getBukkitHelper().takeOneItem(player, stack); - VersionUtils.setGlowing(player, true); - applyRageParticles(player); - for(Entity entity : player.getNearbyEntities(2, 2, 2)) { - if(CreatureUtils.isEnemy(entity)) { - ((Creature) entity).damage(9.0, player); - } - } - Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { - VersionUtils.setGlowing(player, false); - wizardsOnDuty.remove(player); - }, 20L * 15); - user.setCooldown("essence", getKitsConfig().getInt("Kit-Cooldown.Wizard.Essence", 15)); - } else if(ComplementAccessor.getComplement().getDisplayName(stack.getItemMeta()).equals(new MessageBuilder("KIT_CONTENT_WIZARD_GAME_ITEM_WAND_NAME").asKey().build())) { - if(!user.checkCanCastCooldownAndMessage("wizard_staff")) { - return; - } - applyMagicAttack(player); - user.setCooldown("wizard_staff", getKitsConfig().getInt("Kit-Cooldown.Wizard.Staff", 1)); - } - } - - private void applyRageParticles(Player player) { - new BukkitRunnable() { - @Override - public void run() { - Location loc = player.getLocation(); - loc.add(0, 0.8, 0); - VersionUtils.sendParticles("VILLAGER_ANGRY", null, loc, 5, 0, 0, 0); - if(!wizardsOnDuty.contains(player) || !getPlugin().getArenaRegistry().isInArena(player)) { - cancel(); - } - } - }.runTaskTimer(getPlugin(), 0, 2); - } - - private void applyMagicAttack(Player player) { - new BukkitRunnable() { - double positionModifier = 0; - final Location loc = player.getLocation(); - final Vector direction = loc.getDirection().normalize(); - - @Override - public void run() { - positionModifier += 0.5; - double x = direction.getX() * positionModifier, - y = direction.getY() * positionModifier + 1.5, - z = direction.getZ() * positionModifier; - loc.add(x, y, z); - VersionUtils.sendParticles("TOWN_AURA", null, loc, 5, 0, 0, 0); - for(Entity en : loc.getChunk().getEntities()) { - if(!(CreatureUtils.isEnemy(en)) || en.getLocation().distance(loc) >= 1.5 || en.equals(player)) { - continue; - } - ((LivingEntity) en).damage(6.0, player); - VersionUtils.sendParticles("FIREWORKS_SPARK", null, en.getLocation(), 2, 0.5, 0.5, 0.5); - } - loc.subtract(x, y, z); - if(positionModifier > 40) { - cancel(); - } - } - }.runTaskTimer(getPlugin(), 0, 1); - } - -} diff --git a/src/main/java/plugily/projects/villagedefense/kits/utils/ActionBarPriority.java b/src/main/java/plugily/projects/villagedefense/kits/utils/ActionBarPriority.java new file mode 100644 index 000000000..b6033b6a8 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/utils/ActionBarPriority.java @@ -0,0 +1,38 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.utils; + +/** + * @author Plajer + *

+ * Created at 29.09.2023 + */ +public class ActionBarPriority { + + public static final int DAMAGE_EFFECT = 0; + public static final int BUFFS = 1; + public static final int HEALING = 2; + public static final int HEALING_AND_BUFFS = 3; + public static final int PASSIVE = 4; + public static final int ULTIMATE = 5; + public static final int LOW_PRIORITY = 1; + public static final int MEDIUM_PRIORITY = 4; + public static final int HIGH_PRIORITY = 6; + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/utils/KitHelper.java b/src/main/java/plugily/projects/villagedefense/kits/utils/KitHelper.java new file mode 100644 index 000000000..bf2ccccad --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/utils/KitHelper.java @@ -0,0 +1,108 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.utils; + +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import plugily.projects.minigamesbox.classic.kits.basekits.Kit; +import plugily.projects.minigamesbox.classic.user.User; +import plugily.projects.minigamesbox.classic.utils.helper.ItemUtils; +import plugily.projects.minigamesbox.classic.utils.version.VersionUtils; +import plugily.projects.villagedefense.Main; +import plugily.projects.villagedefense.arena.Arena; + +/** + * @author Plajer + *

+ * Created at 01.08.2023 + */ +public class KitHelper { + + private static Main plugin; + + private KitHelper() { + } + + public static void init(Main plugin) { + KitHelper.plugin = plugin; + } + + public static boolean isInGameWithKitAndItemInHand(Player player, Class instance) { + if(plugin.getArenaRegistry().getArena(player) == null) { + return false; + } + + User user = plugin.getUserManager().getUser(player); + if(user.isSpectator() || !instance.isInstance(user.getKit())) { + return false; + } + ItemStack stack = VersionUtils.getItemInHand(player); + return ItemUtils.isItemStackNamed(stack); + } + + public static void scheduleAbilityCooldown(ItemStack item, Player player, int castTime, int cooldown) { + ItemMeta meta = item.getItemMeta(); + meta.addEnchant(Enchantment.DURABILITY, 1, true); + item.setItemMeta(meta); + Bukkit.getScheduler().runTaskLater(KitHelper.plugin, () -> { + ItemMeta newMeta = item.getItemMeta(); + newMeta.removeEnchant(Enchantment.DURABILITY); + item.setItemMeta(newMeta); + + VersionUtils.setMaterialCooldown(player, item.getType(), (cooldown - castTime) * 20); + }, castTime * 20L); + } + + public static void healPlayer(Player target, double healAmount) { + healPlayer(target, target, healAmount); + } + + public static void healPlayer(Player source, Player target, double healAmount) { + target.setHealth(Math.min(target.getHealth() + healAmount, VersionUtils.getMaxHealth(target))); + VersionUtils.sendParticles("HEART", target, target.getLocation(), 3); + if(!source.equals(target)) { + Arena arena = plugin.getArenaRegistry().getArena(target); + arena.getAssistHandler().doRegisterBuffOnAlly(source, target); + } + } + + public static boolean canExecuteEnemy(LivingEntity entity, LivingEntity damager) { + //todo implement execution immunity here (for bosses) + return true; + } + + public static boolean executeEnemy(LivingEntity entity, LivingEntity damager) { + //todo implement execution immunity here (for bosses) + entity.damage(KitSpecifications.LETHAL_DAMAGE, damager); + return true; + } + + public static double maxHealthPercentDamage(LivingEntity entity, Player damager, double percent) { + double damageDone = (VersionUtils.getMaxHealth(entity) / 100.0) * percent; + entity.setHealth(Math.max(0, entity.getHealth() - damageDone)); + //todo implement max health percentage immunity here (for bosses) + entity.damage(0, damager); + return damageDone; + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/kits/utils/KitSpecifications.java b/src/main/java/plugily/projects/villagedefense/kits/utils/KitSpecifications.java new file mode 100644 index 000000000..1e2ea54e0 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/kits/utils/KitSpecifications.java @@ -0,0 +1,56 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.kits.utils; + +import plugily.projects.villagedefense.arena.Arena; + +/** + * @author Plajer + *

+ * Created at 01.09.2022 + */ +public class KitSpecifications { + + public static final double LETHAL_DAMAGE = 10000000.0; + + public static GameTimeState getTimeState(Arena arena) { + if(arena.getWave() <= 15) { + return GameTimeState.EARLY; + } else if(arena.getWave() <= 30) { + return GameTimeState.MID; + } else { + return GameTimeState.LATE; + } + } + + public enum GameTimeState { + LATE(31), MID(16), EARLY(0); + + private int startWave; + + GameTimeState(int startWave) { + this.startWave = startWave; + } + + public int getStartWave() { + return startWave; + } + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/user/VDUser.java b/src/main/java/plugily/projects/villagedefense/user/VDUser.java new file mode 100644 index 000000000..0389b6db2 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/user/VDUser.java @@ -0,0 +1,46 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.user; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Data +@AllArgsConstructor +public class VDUser { + + private UUID uuid; + private Map> gameplayRecords = new HashMap<>(); + + @Data + @AllArgsConstructor + public static class GameplayRecord { + + private String mapId; + private String kitName; + private int wave; + + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/user/VDUserManager.java b/src/main/java/plugily/projects/villagedefense/user/VDUserManager.java new file mode 100644 index 000000000..496ed8e80 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/user/VDUserManager.java @@ -0,0 +1,109 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2024 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.user; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import plugily.projects.minigamesbox.classic.utils.configuration.ConfigUtils; +import plugily.projects.villagedefense.Main; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +public class VDUserManager implements Listener { + + private final Main plugin; + private final List users = new ArrayList<>(); + private final FileConfiguration usersFile; + + public VDUserManager(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + this.usersFile = ConfigUtils.getConfig(plugin, "vd_user_data"); + for (Player player : Bukkit.getOnlinePlayers()) { + users.add(load(player)); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + users.add(load(event.getPlayer())); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) { + VDUser target = users.stream() + .filter(user -> user.getUuid().equals(event.getPlayer().getUniqueId())) + .findFirst() + .orElse(null); + persist(target); + users.remove(target); + } + + public VDUser getUser(Player player) { + return users.stream() + .filter(user -> user.getUuid().equals(player.getUniqueId())) + .findFirst() + .orElse(null); + } + + public List getRegisteredUsers() { + return users; + } + + public VDUser load(OfflinePlayer player) { + UUID uuid = player.getUniqueId(); + if (!usersFile.isSet(uuid.toString())) { + return new VDUser(uuid, new HashMap<>()); + } + Map> records = new HashMap<>(); + ConfigurationSection section = usersFile.getConfigurationSection(uuid + ".records"); + for (String key : section.getKeys(false)) { + List localRecords = new ArrayList<>(); + for (String value : usersFile.getStringList(uuid + ".records." + key)) { + String[] data = value.split(";"); + localRecords.add(new VDUser.GameplayRecord(key, data[0], Integer.parseInt(data[1]))); + } + records.put(key, localRecords); + } + return new VDUser(uuid, records); + } + + public void persist(VDUser user) { + for (Map.Entry> entry : user.getGameplayRecords().entrySet()) { + List flatData = entry.getValue().stream() + .map(record -> record.getKitName() + ";" + record.getWave()) + .collect(Collectors.toList()); + usersFile.set(user.getUuid() + ".records." + entry.getKey(), flatData); + } + ConfigUtils.saveConfig(plugin, usersFile, "vd_user_data"); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/utils/NumberUtils.java b/src/main/java/plugily/projects/villagedefense/utils/NumberUtils.java new file mode 100644 index 000000000..d20d32dd3 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/utils/NumberUtils.java @@ -0,0 +1,43 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.utils; + +/** + * @author Plajer + *

+ * Created at 04.08.2023 + */ +public class NumberUtils { + + private NumberUtils() { + } + + /** + * Fit the requested value between minimum and maximum + * + * @param value the value to clamp + * @param min absolute minimum to return + * @param max absolute maximum to return + * @return value clamped between min and max + */ + public static double clamp(double value, double min, double max) { + return Math.max(min, Math.min(max, value)); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/utils/ProtocolUtils.java b/src/main/java/plugily/projects/villagedefense/utils/ProtocolUtils.java new file mode 100644 index 000000000..0baa9d030 --- /dev/null +++ b/src/main/java/plugily/projects/villagedefense/utils/ProtocolUtils.java @@ -0,0 +1,62 @@ +/* + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package plugily.projects.villagedefense.utils; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import org.bukkit.block.Block; +import plugily.projects.villagedefense.Main; + +/** + * @author Plajer + *

+ * Created at 28.08.2023 + */ +public class ProtocolUtils { + + private static boolean enabled = false; + + private ProtocolUtils() { + } + + public static void init(Main plugin) { + ProtocolUtils.enabled = plugin.getServer().getPluginManager().getPlugin("ProtocolLib") != null; + } + + public static void removeBlockBreakAnimation(Block block) { + sendBlockBreakAnimation(block, 10); + } + + //https://wiki.vg/Protocol#Set_Block_Destroy_Stage + public static void sendBlockBreakAnimation(Block block, int stage) { + if(!enabled) { + return; + } + ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + PacketContainer packet = manager.createPacket(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); + packet.getBlockPositionModifier().write(0, new BlockPosition(block.getX(), block.getY(), block.getZ())); + packet.getIntegers().write(0, block.hashCode()); + packet.getIntegers().write(1, stage); + manager.broadcastServerPacket(packet); + } + +} diff --git a/src/main/java/plugily/projects/villagedefense/utils/Utils.java b/src/main/java/plugily/projects/villagedefense/utils/Utils.java index f237886d9..889e1f369 100644 --- a/src/main/java/plugily/projects/villagedefense/utils/Utils.java +++ b/src/main/java/plugily/projects/villagedefense/utils/Utils.java @@ -1,19 +1,19 @@ /* - * Village Defense - Protect villagers from hordes of zombies - * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors + * Village Defense - Protect villagers from hordes of zombies + * Copyright (c) 2023 Plugily Projects - maintained by Tigerpanzer_02 and contributors * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package plugily.projects.villagedefense.utils; @@ -31,6 +31,7 @@ public class Utils { private Utils() { } + @Deprecated public static Material getCachedDoor(Block block) { //material can not be cached as we allow other door types if(block == null) { @@ -38,4 +39,5 @@ public static Material getCachedDoor(Block block) { } return (MaterialUtils.isDoor(block.getType()) ? block.getType() : Material.AIR); } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f7500ec97..0d89d851d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -170,11 +170,6 @@ Time-Manager: Restarting: 5 -# Should we add support for upgradeable Wolves and Golems in game? -# Configure upgrades pricing in entity_upgrades.yml after enabling it. -Entity-Upgrades: false - - Respawn: # Respawn players when wave ends/starts? After-Wave: true @@ -185,9 +180,9 @@ Respawn: Limit: Wave: # Should game have finite amount of waves - Unlimited: true + Unlimited: false # Limit of waves, if this wave ends game will end - Game-End: 200 + Game-End: 50 Spawn: # Limit of mobs can be spawned globally in-game # Will affect only buying them in in-game shop @@ -197,7 +192,7 @@ Limit: Villagers: 10 # After how many Creatures should we limit them? # Once limit is reached Creatures get more health so it's still harder each wave - Creatures: 75 + Creatures: 85 # Can the players buy again iron golems or wolves if these # entities died? The config limit and permission will be ignored. Entity-Buy-After-Death: false @@ -207,10 +202,6 @@ Creatures: # Active after Creatures limit is reached # Higher value means weaker Creatures Multiplier-Divider: 18 - # Enable very simple health bar for Creatures? - # They will have health instead of their names - # It will show percentage of health left. - Health-Bar: true Orbs: @@ -225,21 +216,13 @@ Orbs: Type: PERCENTAGE Value: 50 - -# Should the name tag of these mobs always visible? -Name-Visibility: - Golem: true - Wolf: true - Villager: true - - # Zombie glow to make it visible to players. Glowing-Status: # From which wave should the glowing be activated? - Starting-Wave: 6 + Starting-Wave: 1 # How many creatures should the glow be activated from? # Set to 0 to disable - Creatures-Left: 0 + Creatures-Left: 2 Update-Notifier: diff --git a/src/main/resources/creatures.yml b/src/main/resources/creatures.yml index d5ae223ba..286608ad5 100644 --- a/src/main/resources/creatures.yml +++ b/src/main/resources/creatures.yml @@ -23,6 +23,7 @@ Creatures: drop_item: null Content: BABY_ZOMBIE: + name: "Baby Zombie" enabled: true wave: min: 3 @@ -69,7 +70,7 @@ Creatures: spawn_lower: 0 # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/attribute/Attribute.html attributes: - GENERIC_MOVEMENT_SPEED: 0.3 + GENERIC_MOVEMENT_SPEED: 0.2 GENERIC_MAX_HEALTH: 2.0 GENERIC_KNOCKBACK_RESISTANCE: 2.0 GENERIC_ATTACK_DAMAGE: 5.0 @@ -92,6 +93,7 @@ Creatures: drop_chance: 0 drop_item: null FAST_ZOMBIE: + name: "Fast Zombie" enabled: true wave: min: 0 @@ -171,6 +173,7 @@ Creatures: drop_chance: 0 drop_item: null GOLEM_BUSTER: + name: "Golem Buster" enabled: true wave: min: 8 @@ -250,6 +253,7 @@ Creatures: drop_chance: 0 drop_item: null HARD_ZOMBIE: + name: "Hard Zombie" enabled: true wave: min: 4 @@ -329,6 +333,7 @@ Creatures: drop_chance: 0 drop_item: null PLAYER_BUSTER: + name: "Player Buster" enabled: true wave: min: 4 @@ -409,6 +414,7 @@ Creatures: drop_chance: 0 drop_item: null TANKER_ZOMBIE: + name: "Tank Zombie" enabled: true wave: min: 20 @@ -416,6 +422,7 @@ Creatures: priority_type: ANY explosive_hit: false entity_type: ZOMBIE + door_bulldozing: true baby: false breed: false age: 0 @@ -469,6 +476,7 @@ Creatures: drop_chance: 0 drop_item: null SOFT_HARD_ZOMBIE: + name: "Medium Zombie" enabled: true wave: min: 4 @@ -549,6 +557,7 @@ Creatures: drop_chance: 0 drop_item: null VILLAGER_BUSTER: + name: "Villager Buster" enabled: true wave: min: 10 @@ -629,6 +638,7 @@ Creatures: drop_chance: 0 drop_item: null VILLAGER_SLAYER: + name: "Villager Slayer" enabled: true wave: min: 23 @@ -636,6 +646,7 @@ Creatures: priority_type: VILLAGER explosive_hit: true entity_type: ZOMBIE + door_bulldozing: true baby: false breed: false age: 0 diff --git a/src/main/resources/entity_upgrades.yml b/src/main/resources/entity_upgrades.yml index 89a15f72b..05775b342 100644 --- a/src/main/resources/entity_upgrades.yml +++ b/src/main/resources/entity_upgrades.yml @@ -2,10 +2,10 @@ Entity-Upgrades: # Cost of x tier (in orbs), ex 1: 100 means 1st tier cost 100 orbs to upgrade Health-Tiers: - '1': 100 - '2': 200 - '3': 350 - '4': 500 + '1': 200 + '2': 300 + '3': 500 + '4': 650 Damage-Tiers: '1': 150 '2': 300 diff --git a/src/main/resources/kit_settings.yml b/src/main/resources/kit_settings.yml new file mode 100644 index 000000000..8cc2f53bb --- /dev/null +++ b/src/main/resources/kit_settings.yml @@ -0,0 +1,52 @@ +# Settings file for existing kits implemented in Village Defense 5 +# You can translate and configure the kits here + +Knight: + Language: + Name: "&2Knight" + Description: + - "This is the one and only knight kit!" + - "Many people think this is the worst kit!" + - "I must admit they are totally wrong!" + +Cleaner: + Language: + Name: "&bCleaner" + Description: + - "&6&lGAME POWER: &7poor/&7strong/&7mediocre" + - "&6&lCLASS: &7mixed, support/&7damage dealer" + - "" + - "&6&lABILITIES:" + - "&a&l• POP AWE (PASSIVE):" + - " &7Every 5 seconds pop random" + - " &71/2/3 alive zombies" + - "&a&l• CLEANSING STICK:" + - " &7On use pop random 10/20/25" + - " &7alive zombies with a delay" + - " &7of 0.5s every 5 pops" + - " &7(&c&lCOOLDOWN 45/&c&l35/&c&l30s&7)" + - "&e&l• POPLUST (ULTIMATE)" + - " &7On use every enemy can be" + - " &7oneshot and popped by anyone" + - " &7(&c&lCAST TIME -/&c&l5&7/&c&l7s&7, &c&lCOOLDOWN 70s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + Game-Item: + Cleansing-Stick: + Name: "&6&lCLEANSING STICK" + Description: + - "On use pop random 10/20/25" + - "alive zombies with a delay" + - "of 0.5s every 5 pops" + - "&c&lCOOLDOWN: &745/&735/&730s" + Activate: "&7Lets wipe them up!" + Poplust: + Name: "&e&lPOPLUST &7(Ultimate)" + Description: + - "On use every enemy can be" + - "oneshot and popped by anyone" + - "&c&lCAST TIME: &7-/&75/&77s, &c&lCOOLDOWN &760s" + Activate: "&7Poplust incoming!" + Active-Title: "0,20,0;;&e&lONESHOT ENEMIES NOW!" + Active-Action-Bar: + - "&e&lPOPLUST ACTIVE &7(%number%s)" + - "&c&lPOPLUST ACTIVE &7(%number%s)" diff --git a/src/main/resources/kits.yml b/src/main/resources/kits.yml index 11c06e355..4cd9e3193 100644 --- a/src/main/resources/kits.yml +++ b/src/main/resources/kits.yml @@ -4,73 +4,58 @@ # https://www.spigotmc.org/resources/55010/ # -# Only kits that inherits level kit feature will be available to modify here. -# Filling here other kits won't change anything as they inherits premium or free kit. -Required-Level: - ZombieFinder: 1 - Archer: 2 - Puncher: 4 - Healer: 6 - Looter: 8 - Runner: 10 - MediumTank: 12 - Worker: 15 - GolemFriend: 18 - Terminator: 20 - Hardcore: 100 +# When integration with Vault is available players can purchase kits for one game via economy plugin +Kit-One-Time-Prices: + Knight: 0 #free because default + Builder: 60 + Tornado: 60 + Shot-Bow: 80 + Medic: 80 + Cleaner: 100 + Pets-Friend: 100 + Terminator: 120 + Crusader: 140 + Wizard: 160 # Here you can disable plugily projects preconfigured kits. # Set 'false' to disable. Enabled-Game-Kits: # Knight is default kit, it cannot be disabled #Knight: true - LightTank: true - Archer: true - GolemFriend: true - Hardcore: true - Healer: true - Looter: true - MediumTank: true - Puncher: true - Runner: true Terminator: true - Worker: true - ZombieFinder: true - Blocker: true Cleaner: true - DogFriend: true - HeavyTank: true Medic: true - Naked: true - PremiumHardcore: true ShotBow: true - Teleporter: true Tornado: true Wizard: true + PetsFriend: true + Builder: true + Crusader: true # The cooldown in seconds for some kit items Kit-Cooldown: - Cleaner: 60 + Cleaner: + Cleansing-Wand: + I: 45 + II: 35 + III: 30 + Poplust: 75 Shot-Bow: 5 Wizard: - Essence: 15 - Staff: 1 + Flower: 15 + Bloodlust: 70 Zombie-Finder: 30 - -# The settings for some kits -Kit-Settings: - Cleaner: - # The maximum health for the enemies to be removed - Max-Health: 2048 - # The maximum amount of enemies that this kit can remove - Max-Amount: 50 - # From the start, how many enemies can this kit remove? - Base-Amount: 10 - # The amount of the removed enemies will be increased after how many waves? - Increase-After-Wave: 5 - # How many amount will be added to the base amount? - # Set to 0 to disable - Increase-Amount: 5 + Medic: + Aura: + I: 30 + II: 15 + Homecoming: 60 + Tornado: + Monsoon: 20 + Final-Flight: 45 + Terminator: + Neverdeath: 20 + Motors-Overcharge: 60 # Don't edit it. But who's stopping you? It's your server! diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index 2cec32762..1d2b90901 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -9,6 +9,10 @@ # Some messages support their own placeholders # like %player%, %kit% etc. +# Applied in Village Defense Gold update +Gold-Messages: + New-Record-Reached: "%plugin_prefix% You've reached new record on this map with kit %value%!" + # # Color scheme # @@ -237,6 +241,7 @@ In-Game: Villagers: "%color_chat_issue%All villagers died!" Survived: "&aYou survived all the waves" Admin: + Nothing-To-Clean: "%color_chat_issue%%plugin_prefix% No entities to clean!" Set-Starting-In-To-0: "%plugin_prefix% An admin set waiting time to 0. The game starts now!" Removed: Villagers: "%plugin_prefix% %player% has removed all the villagers!" @@ -247,11 +252,15 @@ In-Game: Wave: "%color_chat_issue%%plugin_prefix% Admin changed the wave to %number%" Village: Rotten-Flesh-Level-Up: "%plugin_prefix% The gods were happy with the rotten flesh! Therefor they gave you an &aextra heart!" - You-Feel-Refreshed: "%plugin_prefix% You feel refreshed!" # Do not use spaces between villager names. No limit in names size and amount :) Villager: Died: "%color_chat_issue%%plugin_prefix% A villager has died!" Names: "Jagger,Kelsey,Kelton,Haylie,Harlow,Howard,Wulffric,Winfred,Ashley,Bailey,Beckett,Alfredo,Alfred,Adair,Edgar,ED,Eadwig,Edgaras,Buckley,Stanley,Nuffley,Mary,Jeffry,Rosaly,Elliot,Harry,Sam,Rosaline,Tom,Ivan,Kevin,Adam" + Special-Offer: "&e&l-10% SHOP OFFER" + Offering-Sale: "%plugin_prefix% Before wave starts, villager %value% offers &e&l-10% SHOP DEAL" + Rotten-Offer: "&c&lSELL ME ROTTEN FLESH" + Rotten-Sale: "%plugin_prefix% A wandering traded has arrived, trade your %value% for bonus hearts and orbs before wave starts!" + Pinata-Event: "%plugin_prefix% A wild Pinata has appeared! Punch it to earn some loot!" Wave: Stuck-Zombies: "%color_chat_issue%%plugin_prefix% It seems like the last zombie got stuck somewhere. No worries! The gods killed him for you!" Spectator-Warning: "%color_chat_issue%%plugin_prefix% You are a spectator! You can't do anything until you'd respawned at the start of the next wave!" @@ -262,17 +271,23 @@ In-Game: Title: Start: "20,30,20;Wave %number%;" End: "20,30,20;Wave %number% ended;" - Orbs: - Pickup: "+ %number% orbs" + Start-3: "10,20,10;;&a&l3" + Start-2: "10,20,10;;&e&l2" + Start-1: "10,20,10;;&c&l1" Entities: + Cant-Ride-Other: "%color_chat_issue%%plugin_prefix% You can't ride pet you don't own!" + Cant-Upgrade-This: "%color_chat_issue%%plugin_prefix% You can't upgrade this pet!" + Cant-Upgrade-Other: "%color_chat_issue%%plugin_prefix% You can't upgrade pet you don't own!" Wolf: Spawn: "%plugin_prefix% Wolf spawned in the village!" - Name: "%player%'s Wolf" - Death: "%color_chat_issue%%plugin_prefix% One of your wolves were killed!" + Name: "%player%'s Wolf &8(&7LVL %number%&8)" + Death: "%color_chat_issue%%plugin_prefix% Your Wolf (LVL %number%, Kills %value%) was killed!" Golem: Spawn: "%plugin_prefix% Golem spawned in the village!" - Name: "%player%'s Golem" - Cant-Ride-Other: "%color_chat_issue%%plugin_prefix% You can't ride the golem of somebody else!" + Name: "%player%'s Golem &8(&7LVL %number%&8)" + Death: "%color_chat_issue%%plugin_prefix% Your Iron Golem (LVL %number%, Kills %value%) was killed!" + Zombie: + Stunned-Name: "&c&lSTUNNED" Shop: GUI: "&lShop" Golem-Item-Name: "Spawn Golem" @@ -280,7 +295,13 @@ In-Game: Mob-Limit-Reached: "%color_chat_issue%%plugin_prefix% You can't buy mobs! You've reached the limit of %number% mobs!" Not-Enough-Currency: "%color_chat_issue%%plugin_prefix% You need more orbs to buy this item!" Currency: "orbs" + Wave-Lock: "&6Locked till wave %number%" + Item-Locked-Name: "&c&lITEM LOCKED" + Wave-Still-Locked: "%color_chat_issue%%plugin_prefix% This item will be unlocked at wave %number%!" Not-Defined: "%color_chat_issue%%plugin_prefix% Shop wasn't set up! Contact staff!" + Special-Offer: "&e&l-10% SPECIAL OFFER" + New-Shop-Offers: "%plugin_prefix% New offers are now available in Villager Shop!" + Auto-Armor-Equipped: "%plugin_prefix% Armor piece was equipped automatically!" # # Sign messages @@ -350,6 +371,10 @@ Kit: Not-Unlocked: "%color_chat_issue%%plugin_prefix% You haven't unlocked %value% yet!" Choose: "%plugin_prefix% You have chosen: %value%!" Cooldown: "%color_chat_issue%%plugin_prefix% Kit ability still on cooldown (%number%)!" + Locked-Till: "%color_chat_issue%%plugin_prefix% This ability is locked until wave %number%!" + Ability-Unlocked: "%color_chat_issue%%plugin_prefix% &7Ability %value% &7is now unlocked!" + Ability-Power-Increased: "%color_chat_issue%%plugin_prefix% %value% &7ability power has increased!" + Passive-Power-Increased: "%color_chat_issue%%plugin_prefix% &7Your passive power has increased!" Menu: Title: "Kit Menu" Lore: @@ -358,229 +383,452 @@ Kit: Unlock-At-Level: "Unlocks at level %number%" Unlock-In-Store: "&bUnlock this in the store!" Content: - Cleaner: - Name: "&bCleaner" - Description: - - "The cleaner has a special ability." - - "With this ability, he can make all the" - - "zombies disappear. However, it takes" - - "a lot of effort to do this!" - Game-Item: - Name: "&6Cleaner Wand!" - Description: - - "Right click to kill all zombies!" - - "Cooldown: 60 seconds" - Cleaned: - Map: "&b%player% has cleaned the map!" - Nothing: "&aThe map is already empty!" #WARNING: used for admin clean commands too!!! - Zombie-Teleporter: - Name: "&2Zombie Teleporter" - Description: - - "Teleport those zombies to you!" - - "Many people think this is the worst kit!" - - "I must admit they are totally wrong!" - Game-Item: - GUI: "Zombie Teleporter" - Name: "Zombie Teleporter" - Description: - - "Teleport zombies to you!" - Teleport: - Zombie: "&aTeleported weakened zombie to you!" - Not-Found: "&cThere are no zombies to teleport!" Knight: Name: "&2Knight" Description: - "This is the one and only knight kit!" - "Many people think this is the worst kit!" - "I must admit they are totally wrong!" - Light-Tank: - Name: "&2Light Tank" - Description: - - "You are Junior tank!" - Archer: - Name: "&6Archer" - Description: - - "Start with a bow, leather armor and a wooden sword." - - "Archers are loved by the villagers, know that!" - Puncher: - Name: "&6Puncher" - Description: - - "Punch those zombies back with your epic shovel!" - - "Knockback V is not unknown to you!" - Healer: - Name: "&6Healer" - Description: - - "Being a healer is the same as being loved." - - "You are able to heal your teammates and villagers!" - - "Gets a restock every wave!" - Looter: - Name: "&6Looter" - Description: - - "Get one additional rotten flesh" - - "on every zombie kill!" - Runner: - Name: "&6Runner" - Description: - - "Parkour is your passion!" - - "You are able to run faster than everybody else." - - "You have also the ability to jump higher." - Medium-Tank: - Name: "&6Medium Tank" - Description: - - "Start off with 6 more hearts!" - - "Don't be afraid!" - - "You have plenty hearts left to lose!" - Worker: - Name: "&6Worker" + Cleaner: + Name: "&bCleaner" Description: - - "Get each round a door and start off" - - "with 2 additional doors. This way you" - - "can replace the doors!" + - "&6&lGAME POWER: &7poor/&7strong/&7mediocre" + - "&6&lCLASS: &7mixed, support/&7damage dealer" + - "" + - "&6&lABILITIES:" + - "&a&l• POP AWE (PASSIVE):" + - " &7Every 5 seconds pop random" + - " &71/2/3 alive zombies" + - "&a&l• CLEANSING STICK:" + - " &7On use pop random 10/15/20" + - " &7alive zombies with a delay" + - " &7of 0.5s every 5 pops" + - " &7(&c&lCOOLDOWN 45/&c&l35/&c&l30s&7)" + - "&e&l• POPLUST (ULTIMATE)" + - " &7On use every enemy can be" + - " &7oneshot and popped by yourself" + - " &7(&c&lCAST TIME -/&c&l7&7/&c&l11s&7, &c&lCOOLDOWN 75s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" Game-Item: - Chat: "&aDoor placed!" - Dog-Friend: - Name: "&bDog Friend" - Description: - - "Start off with three dogs and" - - "get one extra dog every wave!" - Hardcore: - Name: "&6Hardcore" - Description: - - "You'll see yourself" - - "why this is hardcore" - Golem-Friend: - Name: "&6Golem Friend" - Description: - - "Start with a golem and" - - "get new every 5 waves!" + Cleansing-Stick: + Name: "&6&lCLEANSING STICK" + Description: + - "On use pop random 10/20/25" + - "alive zombies with a delay" + - "of 0.5s every 5 pops" + - "&c&lCOOLDOWN: &745/&735/&730s" + Activate: "&7Lets wipe them up!" + Poplust: + Name: "&e&lPOPLUST &7(Ultimate)" + Description: + - "On use every enemy can be" + - "oneshot and popped by yourself" + - "&c&lCAST TIME: &7-/&77/&711s, &c&lCOOLDOWN &775s" + Activate: "&7Poplust incoming!" + Active-Title: "0,20,0;;&e&lONESHOT ENEMIES NOW!" + Active-Action-Bar: + - "&e&lPOPLUST ACTIVE &7(%number%s)" + - "&c&lPOPLUST ACTIVE &7(%number%s)" Tornado: Name: "&bTornado" Description: - - "Spawn in an awesome tornado!" + - "&6&lGAME POWER: &7?/&7?/&7?" + - "&6&lCLASS: &7mixed, support" + - "" + - "&6&lABILITIES:" + - "&a&l• CALL OF THE WIND (PASSIVE):" + - " &7Each turn you receive 2/3/5 tornadoes," + - " &7which push back and damage enemies" + - "&a&l• MONSOON:" + - " &7Creates wind sphere that knocks back" + - " &7and permanently slows all enemies" + - " &7(&c&lCAST TIME 6/&c&l9/&c&l12s&7, &c&lCOOLDOWN 20s&7)" + - "&e&l• FINAL FLIGHT (ULTIMATE):" + - " &7On cast your attacks cause enemies" + - " &7to levitate and receive 25% max health" + - " &7damage per second that lasts for 4s" + - " &7(&c&lCAST TIME 10s&7, &c&lCOOLDOWN 45s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + Game-Item: + Tornado: + Name: "&6&lTORNADO TIME" + Description: + - "Right click to spawn a" + - "tornado at your location!" + Monsoon: + Name: "&6&lMONSOON" + Description: + - "On cast creates wind sphere that knocks back" + - "and permanently slows enemies" + - "&c&lCOOLDOWN: &720s" + Active-Action-Bar: + - "&e&lMONSOON ACTIVE &7(%number%s)" + - "&c&lMONSOON ACTIVE &7(%number%s)" + Final-Flight: + Name: "&e&lFINAL FLIGHT &7(Ultimate)" + Description: + - "On cast your attacks cause enemies" + - "to levitate and receive 25% max health" + - "damage per second that lasts for 4s" + - "&c&lCAST TIME: &710s, &c&lCOOLDOWN &740s" + Active-Action-Bar: + - "&e&lFINAL FLIGHT ACTIVE &7(%number%s)" + - "&c&lFINAL FLIGHT ACTIVE &7(%number%s)" + Builder: + Name: "&6Builder" + Description: + - "&6&lGAME POWER: &7poor/&7mediocre/&7mediocre" + - "&6&lCLASS: &7mixed, support" + - "" + - "&6&lABILITIES:" + - "&a&l• RESTOCK (PASSIVE):" + - " &7Receive 1 door every 5/&73/&72 waves" + - " &7to replace broken ones and receive" + - " &71/&72/&73 fences every wave to block" + - " &7enemies that last 10/&712/&714s" + - "&a&l• EARTHED:" + - " &7On use every ally cannot be knocked" + - " &7back by any non explosion damage" + - " &7(&c&lCAST TIME 10s&7, &c&lCOOLDOWN 20s&7)" + - "&e&l• BLOCKAGE (ULTIMATE)" + - " &7On use enemies cannot damage nor" + - " &7destroy any door on the map" + - " &7(&c&lCAST TIME 15s&7, &c&lCOOLDOWN -/&c&l40/&c&l30s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" Game-Item: - Name: "Tornado Time" - Description: - - "Right click to spawn a" - - "tornado at your location!" + Fence: + Name: "&6&lBLOCKING FENCE" + Description: + - "On use block path for enemies" + - "that last 10/&712/&714s" + Door: + Name: "&6&lREPLACEABLE DOOR" + Description: + - "Replace a broken door with this one!" + Earthed: + Name: "&6&lEARTHED" + Description: + - "On use every ally cannot be knocked" + - "back by any non explosion damage" + - "&7(&c&lCAST TIME 10s&7, &c&lCOOLDOWN 20s&7)" + Activate: "&7Everyone is now unshaken!" + Active-Action-Bar: + - "&e&lEARTHED ACTIVE &7(%number%s)" + - "&c&lEARTHED ACTIVE &7(%number%s)" + Knock-Protected-By-Action-Bar: + - "&e&lYOU'RE KNOCKBACK PROTECTED BY &7%player%" + - "&c&lYOU'RE KNOCKBACK PROTECTED BY &7%player%" + Blockage: + Name: "&e&lBLOCKAGE &7(Ultimate)" + Description: + - "On use enemies cannot damage nor" + - "destroy any door on the map" + - "&c&lCAST TIME 15s&7, &c&lCOOLDOWN -/&c&l40/&c&l30s&7)" + Activate: "&7Hardened every door on the map!" Terminator: Name: "&6Terminator" Description: - - "Easily kill those zombies" - - "with your strength powers!" - Teleporter: - Name: "&bTeleporter" - Description: - - "Everybody is astonished about your teleportation." - - "Nobody knows how to do it except you! Due to this," - - "you are able to teleport to villagers" - - "that need help in no time!" + - "&6&lGAME POWER: &7mediocre/&7strong/&7strong" + - "&6&lCLASS: &7melee, damage dealer" + - "" + - "&6&lABILITIES:" + - "&a&l• BLADE OF TERMINUS (PASSIVE):" + - " &7Receive sword that scales with waves:" + - " &e&lWAVE 5: &720% on-hit burn chance" + - " &e&lWAVE 10: &75% instakill chance" + - " &e&lWAVE 15: &76% lifesteal, 40% on-hit burn" + - " &e&lWAVE 20: &720% shared combust chance" + - " &e&lWAVE 25: &735% large knockback chance" + - " &e&lWAVE 30+: &7+1% dmg each wave (40% cap)" + - "&7(&c&lBELOW ARE UNLOCKED IN MID GAME&7)" + - "&a&l• NEVERDEATH &7(&c&lCOOLDOWN 20s&7):" + - " &7On use receive absorption for 15s" + - "&e&l• MOTORS OVERCHARGE (ULTIMATE)" + - " &7On use pull enemies to you, damage" + - " &7them for 35% of max health per sec, on" + - " &7end knock them away and instakill them" + - " &7(&c&lCAST TIME 10s&7, &c&lCOOLDOWN 50s&7)" Game-Item: - Name: "&rTeleportation Menu" - Description: - - "Right click to open teleportation menu!" - GUI: "Teleporter Menu" - Teleport: - Villager: "&aTeleported to the villager!" - Warning: "&4Village defense didn't found that villager! That villager is probably already dead!" - Player: "&aTeleported to %player%" - Not-Found: "&cPlayer not found! Try again!" - Heavy-Tank: - Name: "&bHeavy Tank" - Description: - - "Start off with iron armor and a double" - - "amount of hearts! Yup, that's right," - - "you'll be the last man standing!" + Terminus: + Name: "&6&lBLADE OF TERMINUS" + Description: + - "&7Terminus blade scales as game progresses:" + - " &e&lWAVE 5: &720% on-hit burn chance" + - " &e&lWAVE 10: &75% instakill chance" + - " &e&lWAVE 15: &76% lifesteal, 40% on-hit burn" + - " &e&lWAVE 20: &720% shared combust chance" + - " &e&lWAVE 25: &735% large knockback chance" + - " &e&lWAVE 30+: &7+1% dmg each wave (40% cap)" + Neverdeath: + Name: "&6&lNEVERDEATH" + Description: + - "On use receive absorption for 15s," + - "the lower your health the higher" + - "the absorption effect" + - "&c&lCOOLDOWN &720s" + Activate: "&7Protocol &6&lNEVERDEATH &7active!" + Motors-Overcharge: + Name: "&e&lMOTORS OVERCHARGE &7(Ultimate)" + Description: + - "On use pull enemies to you, damage" + - "them for 35% of max health per sec, on" + - "end knock them away and instakill them" + - "&c&lCAST TIME &710s, &c&lCOOLDOWN &760s" + Activate: "&7Engaging kinematic motors, full power reached!" + Active-Action-Bar: + - "&e&lMOTORS OVERCHARGE ACTIVE &7(%number%s)" + - "&c&lMOTORS OVERCHARGE ACTIVE &7(%number%s)" Shot-Bow: - Name: "&bShotbow Master" - Description: - - "You invented a crazy shotbow!" - Blocker: - Name: "&bBlocker" + Name: "&6Shotbow Master" Description: - - "Hold the zombies back with" - - "your special barriers. These" - - "barriers last for 10 seconds" + - "&6&lGAME POWER: &7poor/strong/mediocre" + - "&6&lCLASS: &7ranged, damage dealer" + - "" + - "&6&lABILITIES:" + - "&a&l• ONESHOT (PASSIVE):" + - " &7Have 10/&720/&730% chance to oneshot" + - " &7enemy with your arrows" + - "&a&l• EFFECTIVE ARROWS (PASSIVE):" + - " &7Each arrow applies random effect:" + - " &e&lLIGHTNING: &710% AOE damage" + - " &e&lSLOWNESS: &710s slowness" + - " &e&lWEAKNESS: &710s weakness" + - " &e&lCOMBUST: &710s AOE combust" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + - "&e&l• ARROW RAIN (ULTIMATE)" + - " &7On use launch -/&78/&712 arrows that" + - " &7knock enemies and oneshot them" + - " &7(&c&lCOOLDOWN 20s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" Game-Item: - Name: "Fence" - Description: - - "Place this barrier to hold back" - - "zombies! These barriers last for 10 seconds" - Place: - Success: "&aBarrier placed!" - Fail: "&cUnable to place barrier here" - Premium-Hardcore: - Name: "&bPremium Hardcore Master" - Description: - - "One hit most zombies with your OP sword!" - - "However be careful. this kit is only for" - - "the pros! Do not use it if you aren't a pro!" + Arrow-Rain: + Name: "&6&lARROW RAIN" + Description: + - "&7On use launch -/&78/&712 arrows that" + - "&7knock enemies and oneshot them" + - "&c&lCOOLDOWN &720s" Medic: Name: "&6Medic" Description: - - "This kit activates your passive powers." - - "Every time you hit a zombie, you have" - - "a 1/10 chance to heal the players" - - "in a 5 block radius around you." - Wild-Naked: - Name: "&bWild Naked" + - "&6&lGAME POWER: &7poor/mediocre/strong" + - "&6&lCLASS: &7mixed, support" + - "" + - "&6&lABILITIES:" + - "&a&l• FIRST AID (PASSIVE):" + - " &7Each zombie hit you have 10% chance to" + - " &7heal nearby allies by 0.5 heart and" + - " &7you heal allies and villagers on wave" + - " &7start for 1/2/3 hearts" + - "&a&l• HEALER AURA:" + - " &7Creates healing aura that heals" + - " &7allies and pets by -/2/4 hearts per sec" + - " &7(&c&lCAST TIME 10s&7, &c&lCOOLDOWN -/&c&l30/&c&l15s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + - "&e&l• HOMECOMING (ULTIMATE):" + - " &7On cast all spectators are respawned" + - " &7and are given Speed Boost -/I/II and" + - " &7Damage Boost -/I/II for 30 seconds" + - " &7(&c&lCOOLDOWN 60s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + Game-Item: + Aura: + Name: "&6&lHEALING AURA" + Description: + - "On cast creates healing aura" + - "that heals allies, wolves and golems" + - "2/4 hearts per second" + - "&c&lCAST TIME &710s, &c&lCOOLDOWN &7-/&730/&715s" + Active-Action-Bar: + - "&e&lHEALING AURA ACTIVE &7(%number%s)" + - "&c&lHEALING AURA ACTIVE &7(%number%s)" + Healed-By-Action-Bar: + - "&e&lYOU'RE BEING HEALED BY &7%player%" + - "&c&lYOU'RE BEING HEALED BY &7%player%" + Homecoming: + Name: "&e&lHOMECOMING &7(Ultimate)" + Description: + - "On cast all spectators are" + - "respawned and given Speed Boost -/I/II" + - "and Damage Boost -/I/II for 30s" + - "&c&lCOOLDOWN &760s" + Activate: "&7Come back my allies! We will not fall!" + Respawned-By-Title: "&eIt's not your time yet" + Respawned-By-Subtitle: "&7Respawned by %player%" + Crusader: + Name: "&bCrusader" + Description: + - "&6&lGAME POWER: &7mediocre/strong/strong" + - "&6&lCLASS: &7melee, tank" + - "" + - "&6&lABILITIES:" + - "&a&l• IRON WILL (PASSIVE):" + - " &7Every 3 hits you stun the enemy for" + - " &72/&74/&75s and receive 1/&72/&74 &b&lCOURAGE" + - " &7stacks, capped at 50. Receive blast" + - " &7resistance in mid game" + - "&a&l• COURAGEOUS &7(&c&lCOOLDOWN 5s&7):" + - " &7Use &b&lCOURAGE &7stacks that apply:" + - " &e&l0 STACKS: &7absorption 1 for 5s" + - " &e&l5 STACKS: &7speed boost 1 for 5s" + - " &e&l15 STACKS: &715% instant heal" + - " &e&l25 STACKS: &730% instant heal" + - " &e&l35 STACKS: &760% instant heal" + - " &e&l50 STACKS: &7burn aura for 8s" + - "&e&l• GLORY TO THE KING (ULTIMATE):" + - " &7On cast use all &b&lCOURAGE" + - " &7stacks to receive immortality" + - " &7for 10s and be healed after" + - " &7(&c&lCOOLDOWN -/&c&l40/&c&l25s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + Game-Item: + Courageous: + Name: "&6&lCOURAGEOUS" + Description: + - "Use &b&lCOURAGE &7stacks that apply:" + - " &e&l0 STACKS: &7absorption 1 for 5s" + - " &e&l5 STACKS: &7speed boost 1 for 5s" + - " &e&l15 STACKS: &715% instant heal" + - " &e&l25 STACKS: &730% instant heal" + - " &e&l35 STACKS: &760% instant heal" + - " &e&l50 STACKS: &7burn aura for 8s" + - "&c&lCOOLDOWN 5s" + Stacks: + Base: "&7%number%/&750 &b&lCOURAGE" + Max: "&7&lMAX &b&lCOURAGE" + Activate: "&7To the end, and then beyond, I fight on!" + Aura-Action-Bar: + - "&e&lBURN AURA ACTIVE &7(%number%s)" + - "&c&lBURN AURA ACTIVE &7(%number%s)" + Glory-To-The-King: + Name: "&e&lGLORY TO THE KING &7(Ultimate)" + Description: + - "On cast receive heal -/4/5 and" + - "absorption 3 for 20s and use all" + - "&b&lCOURAGE &7stacks, you cannot" + - "be killed for 10s" + - "&c&lCOOLDOWN -/&c&l40/&c&l25s" + Activate: "&7Death's scythe hesitates before my might!" + Active-Action-Bar: + - "&e&lGLORY TO THE KING ACTIVE &7(%number%s)" + - "&c&lGLORY TO THE KING ACTIVE &7(%number%s)" + Pets-Friend: + Name: "&bPets Friend" Description: - - "You are the ultimate master!" - - "You start off with a iron Sharpness" - - "VI and Smite II sword!" - Cannot-Wear-Armor: "&cYou can't wear armor with the Wild Naked kit!" + - "&6&lGAME POWER: &7strong/mediocre/mediocre" + - "&6&lCLASS: &7mixed, support" + - "" + - "&6&lABILITIES:" + - "&a&l• TRUE FRIEND (PASSIVE):" + - " &7Spawn 1 wolf every 3/&72/&71 waves and 1" + - " &7golem every 4/&73/&72 waves, all pets" + - " &7receive -/&71/&72 random tier I" + - " &7upgrades on spawn" + - "&a&l• FIGHT OR FLIGHT:" + - " &7On use every spawned pet will have" + - " &7increased damage I/&7II/&7III and" + - " &7regeneration I for 10s" + - " &7(&c&lSPELL TIME 10s&7, &c&lCOOLDOWN 30s&7)" + - "&e&l• UNSTOPPABLE BEASTS (ULTIMATE):" + - " &7On use spawn a wolf and golem" + - " &7will all maxed upgrades" + - " &7(&c&lCOOLDOWN 140s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" + Game-Item: + Fight-Or-Flight: + Name: "&6&lFIGHT OR FLIGHT" + Description: + - "On use every spawned pet will have" + - "increased damage by 10/15/20% and" + - "regeneration I for 10s" + - "&c&lSPELL TIME 10s&7, &c&lCOOLDOWN 25s" + Activate: "&7Who let the dogs out?!" + Unstoppable-Beasts: + Name: "&e&lUNSTOPPABLE BEASTS &7(Ultimate)" + Description: + - "On use spawn a wolf and golem" + - "with all maxed upgrades" + - "&c&lCOOLDOWN 70s" + Activate: "&7Rise and fight my brave pets!" Wizard: Name: "&bWizard" Description: - - "You're half blood." - - "You've come to the village to protect" - - "villagers from hordes of undead." - - "Use your dark powers to kill them all!" + - "&6&lGAME POWER: &7mediocre/strong/strong" + - "&6&lCLASS: &7ranged, damage dealer" + - "" + - "&6&lABILITIES:" + - "&a&l• WIZARD WAND:" + - " &7Flat 20/25/30% max health damage and" + - " &7projectile pierce 4/5/6 per shot" + - "&a&l• CORRUPTING FLOWER:" + - " &7Every 3/3/2 waves receive item, on use" + - " &7attacks slows and burns enemies for 3s" + - " &7(&c&lCAST TIME 15s&7, &c&lCOOLDOWN 15s&7)" + - "&e&l• BLOODLUST (ULTIMATE):" + - " &7Creates deadly aura that deals 10%" + - " &7max health to nearby enemies and" + - " &7heals you for 8% of damage dealt" + - " &7from aura each second" + - " &7(&c&lCAST TIME 15s&7, &c&lCOOLDOWN 70s&7)" + - " &7(&c&lUNLOCKED IN MID GAME&7)" Game-Item: - Essence: - Name: "Dark essence" + Wand: + Name: "&6&lWIZARD WAND" Description: - - "Click to absorb surrounded matter" + - "Right click to shoot projectile" + - "flat 20/25/30% max health damage" + - "and 4/5/6 pierce per shot" + Flower: + Name: "&c&lCORRUPTING FLOWER" + Description: + - "Click to make your attacks deal" + - "slow and burn for 3 seconds!" + - "&c&lCAST TIME &715s, &c&lCOOLDOWN &715s" + Activate: "&7Let &0&lCORRUPTION &7arise!" + Bloodlust: + Name: "&e&lBLOODLUST &7(Ultimate)" + Description: + - "Click to create death aura" - "and use it as your personal thorn shield!" - - "Lasts for 5 seconds" - Wand: - Name: "Magic wand" - Description: "Right click to cast dark matter" + - "&c&lCAST TIME &715s, &c&lCOOLDOWN &770s" + Activate: "&7Sacrifice your souls to me!" + Active-Action-Bar: + - "&e&lBLOODLUST ACTIVE &7(%number%s)" + - "&c&lBLOODLUST ACTIVE &7(%number%s)" # # Upgrade-Menu messages # # Upgrade-Menu function need to be enabled on config.yml Upgrade-Menu: - Title: "&3&lUpgrade entity" + Title: "&6&lUPGRADE ENTITY" Upgraded-Entity: "%plugin_prefix% &3Upgraded entity to tier &8%tier%&3!" Cannot-Afford: "%plugin_prefix% &3You don't have enough orbs to apply that upgrade!" Max-Tier: "%plugin_prefix% &3Entity is at max tier of this upgrade!" Stats-Item: - Name: "&3&lCurrent Stats" - Description: "&3Movement speed: &8%speed%; &3Attack Damage: &8%damage%; &3Health: - &8%current_hp%/%max_hp%" + Name: "&6&lCURRENT STATS" + Description: " &a&lSPEED: &7%speed%; &7&lDAMAGE: &7%damage%; &a&lHEALTH: &7%current_hp%/%max_hp%" Upgrades: Health: - Name: "&3&lUpgrade Health" - Description: "&3Upgrade max health to tier &8%tier%&3!;&3From &8%from% &3to + Name: "&c&lUPGRADE: &aHealth" + Description: "&3Upgrade max health to tier &8%tier% ▲&3!;&3From &8%from% &3to &8%to%;&3Cost of upgrade: &8%cost%;;&3Click to purchase" Damage: - Name: "&3&lUpgrade Damage" - Description: "&3Upgrade entity damage to tier &8%tier%&3!;&3From &8%from% &3to + Name: "&c&lUPGRADE: &7Damage" + Description: "&3Upgrade entity damage to tier &8%tier% ▲&3!;&3From &8%from% &3to &8%to%;&3Cost of upgrade: &8%cost%;;&8Click to purchase" Speed: - Name: "&3&lUpgrade Speed" - Description: "&3Upgrade movement speed to tier &8%tier%&3!;&3From &8%from% &3to + Name: "&c&lUPGRADE: &6Speed" + Description: "&3Upgrade movement speed to tier &8%tier% ▲&3!;&3From &8%from% &3to &8%to%;&3Cost of upgrade: &8%cost%;;&8Click to purchase" Swarm-Awareness: - Name: "&3&lSwarm Awareness" - Description: "&3Upgrade swarm awareness to tier &8%tier%&3!;&3From &8%from% + Name: "&3&lSWARM AWARENESS" + Description: "&3Upgrade swarm awareness to tier &8%tier% ▲&3!;&3From &8%from% &8damage multiplier per wolf in radius;&8of 3 blocks &3to %to%;&3The more wolves near attacking wolf;&3the more damage wolf deal;&3Cost of upgrade: &8%cost%;;&8Click to purchase" Final-Defense: - Name: "&3&lFinal Defense" - Description: "&3Upgrade final defense to tier &8%tier%&3!;&3From &8%from% explosion + Name: "&3&lFINAL DEFENSE" + Description: "&3Upgrade final defense to tier &8%tier% ▲&3!;&3From &8%from% explosion radius &3to &8%to%;&3Golem will explode after death killing nearby;&3zombies and stun all alive ones;&3Cost of upgrade: &8%cost%;;&8Click to purchase" # diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c6fd6b679..9ff73a973 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,17 +2,17 @@ name: ${description} main: plugily.projects.villagedefense.Main authors: [ PlugilyProjects, Tigerpanzer_02, TomTheDeveloper, Plajer, montlikadani ] version: ${version} -softdepend: [ PlaceholderAPI, Parties, Spigot-Party-API-PAF, PartyAndFriends, ViaVersion, ProtocolSupport ] +softdepend: [ PlaceholderAPI, Parties, Spigot-Party-API-PAF, PartyAndFriends, ViaVersion, ProtocolSupport, ProtocolLib ] api-version: 1.13 commands: villagedefense: description: VillageDefense Commands - usage: "\u00A76Correct usage: /vd [option]" + usage: "Correct usage: /vd [option]" aliases: [ vd, villaged ] villagedefenseadmin: description: VillageDefense Admin Commands - usage: "\u00A76Correct usage: /vda [option]" + usage: "Correct usage: /vda [option]" aliases: [ vda, villageadmin ] permissions: diff --git a/src/main/resources/powerups.yml b/src/main/resources/powerups.yml index 46ee3e203..4b667299c 100644 --- a/src/main/resources/powerups.yml +++ b/src/main/resources/powerups.yml @@ -16,8 +16,7 @@ Powerups: material: BLAZE_POWDER # Add as many potion effects as you want # Format: PotionName, Duration, Amplifier - potion-effect: - - "" + potion-effect: [ ] # PLAYER for pickup player | ALL for all arena players potion-type: PLAYER # like rewards @@ -56,8 +55,7 @@ Powerups: material: IRON_INGOT # Add as many potion effects as you want # Format: PotionName, Duration, Amplifier - potion-effect: - - "REGENERATION, 3, 1" + potion-effect: [ ] # PLAYER for pickup player | ALL for all arena players potion-type: PLAYER # like rewards diff --git a/src/main/resources/vd_user_data.yml b/src/main/resources/vd_user_data.yml new file mode 100644 index 000000000..d52756f99 --- /dev/null +++ b/src/main/resources/vd_user_data.yml @@ -0,0 +1,4 @@ +# uuid: +# records: +# mapname: +# - kit_id;wave \ No newline at end of file