49 Commits
Author SHA1 Message Date
Luka de Vrij 7e6144fcea versioning draft 2024-06-04 23:00:35 +02:00
Luka de Vrij 440d43ed09 Dev branch with ProtocolSidebar 1.20.6 2024-05-28 23:58:19 +02:00
Luka de Vrij adf60eb533 Update README.md 2024-04-13 21:55:26 +02:00
Luka de Vrij 1ddfe08162 1.3.1 release 2024-04-13 21:48:38 +02:00
Luka de Vrij 19338dcdcd fixed #3 i hope 2024-04-12 22:58:11 +02:00
Luka de Vrij 4c9bb79652 1.3 README.md 2024-02-17 16:34:04 +01:00
Luka de Vrij 2f6b9032ca Merge branch 'main' of https://github.com/LukaDeVrij/PureKitPvP 2024-02-17 16:18:20 +01:00
Luka de Vrij 65a9046230 1.3 it seems 2024-02-17 16:18:12 +01:00
Luka de Vrij f80b7f0e16 Delete PureKitPvP.iml 2024-02-16 22:37:19 +01:00
Luka de Vrij 5db29e30fe Create LICENSE 2024-02-16 22:36:36 +01:00
Luka de Vrij 7321263e38 Delete .idea directory 2024-02-16 22:34:32 +01:00
Luka de Vrij fb76bc5eab Delete .gitattributes 2024-02-16 22:34:23 +01:00
Luka de Vrij 7c89f1e708 final fixes 2024-02-16 22:32:38 +01:00
Luka de Vrij 1ce06a5028 Component cleanup and bugsfixings
suicide, voidkiller, getstats rework
2024-01-26 22:50:38 +01:00
Luka de Vrij 23d2d378ea loottable inventory + tabexecutor on pkpvp kit 2024-01-07 23:43:43 +01:00
Luka de Vrij e725189fb5 fixed issue thanks Eisi05 2024-01-06 00:09:41 +01:00
Luka de Vrij 80d65bc2f4 i am going insane 2024-01-05 22:12:31 +01:00
Luka de Vrij e87e9eebca refactor rollback + language enum + edit kit 2024-01-04 23:30:14 +01:00
Luka de Vrij 9bfb7e0992 bunch of refactoring 2024-01-04 20:17:10 +01:00
Luka de Vrij 4456aa61ba console sender fix + kit supercommand draft
Console can now send most commands that are not player specific; every class has a getter for consoleExecutable bool
WIP Rework of admin kit commands; now under supercommand /pkpvp kit
2023-12-17 23:27:30 +01:00
Luka de Vrij da3fdf06cd 1.20.4 error in depend ProtocolSidebar
cleaned up pom.xml because of this
2023-12-12 16:25:21 +01:00
Luka de Vrij c67697e5f9 1.20.4 struggles 2023-12-11 23:42:12 +01:00
Luka de Vrij 78ca4f0df1 Scoreboard functional - new event
Not perfect - see Trello
Event double health added
2023-12-05 23:51:26 +01:00
Luka de Vrij cd7fbae8a6 Update SidebarScoreboard.java 2023-12-05 14:58:34 +01:00
Luka de Vrij a460007521 Global scoreboard testing
Possible implementation -> needs testing
Hashmap implementation for leaderboards is garbage
Remake this structure and just sort the hashmap into a linkedhashmap on values
https://www.digitalocean.com/community/tutorials/sort-hashmap-by-value-java
2023-12-04 23:25:54 +01:00
Luka de Vrij df962e2f49 3rd time's the charm
Personal stats operational
All in constructor tho -> needs refactoring to support onJoin listener
2023-12-03 23:57:34 +01:00
Luka de Vrij 6b5bcd227a PreviewKit fix 2023-12-02 21:02:03 +01:00
Luka de Vrij 5840cad9ab Bug fixes
double head eat fixed
Suicide way nicer now
Projectiles that are in air on kill are removed: removes tridents staying behind
/Kit delay induced bug fixed
2023-12-02 20:44:40 +01:00
Luka de Vrij 1438e34a4e QUICK FIX
theije bug fix adventures
2023-11-30 23:18:19 +01:00
Luka de Vrij a8b360e4c8 Preview Kit feature 2023-11-30 21:50:39 +01:00
Luka de Vrij 507c16ebc9 previewKit stub 2023-11-27 23:29:16 +01:00
Luka de Vrij 9d2aa536e9 Componentization + scoreboars stub 2023-11-26 22:19:07 +01:00
Luka de Vrij e0305a7533 Kit + Perks lang.yml support + Componentization 2023-11-25 22:38:13 +01:00
Luka de Vrij 3d860fda39 AAAH LORE AND PERK WORKS THANK NOTCH 2023-11-25 17:02:02 +01:00
Luka de Vrij 6f9d4657ea Lang support perks + Component-ization
LAng supports multiline (ie with lore)
2023-11-25 00:03:28 +01:00
Luka de Vrij d1c931cff0 further Componentization + language supp stub
+ fixes to tab complete and lang support stub
2023-11-23 23:17:49 +01:00
Luka de Vrij 8f471a25d4 bug fix thursday
perks &cosmetics config values failsafe
componentization of CreateKit
proj trails on everything
2023-11-23 20:45:28 +01:00
Luka de Vrij 638ece8382 deathhandler refactors !!!! 2023-11-22 23:12:40 +01:00
Luka de Vrij d7acab42d6 TabManager NMS stub 2023-11-20 23:20:47 +01:00
Luka de Vrij ed5315c22e Merge branch 'main' of https://github.com/LukaDeVrij/PureKitPvP 2023-11-17 16:47:47 +01:00
Luka de Vrij bd62e89b98 Juggernaut stub + NMS support 2023-11-17 16:47:45 +01:00
Luka de Vrij 8883a5e5b8 Update README.md 2023-10-17 19:52:38 +02:00
Luka de Vrij 66b5695844 full framework for events + pause/resume 2023-09-12 23:06:00 +02:00
Luka de Vrij 556e9b4b57 events framework bijna done 2023-09-11 23:09:25 +02:00
Luka de Vrij 2141aafb1e Start/stop event commands
Lack already ran checks
2023-09-10 14:56:34 +02:00
Luka de Vrij 6e6af1ca99 bug fix saturday 2023-09-09 23:15:29 +02:00
Luka de Vrij 89b8f63cd2 small fixes + events framework
Custom items reworked - PSD instead of lore
Custom items hotbar dancing fix
Config values added
Framework for events
2 working events - Pickup Frenzy & TeleMadness
2023-09-08 23:35:10 +02:00
Luka de Vrij dba8be3d9c Update README.md 2023-07-22 16:50:22 +02:00
Luka de Vrij b8f996afa9 Update README.md 2023-07-22 16:49:32 +02:00
98 changed files with 4052 additions and 1558 deletions

No files matched your search

-2
View File
@@ -1,2 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
File renamed without changes.
-3
View File
@@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" />
</component>
</module>
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="PureKitPvP" />
</profile>
</annotationProcessing>
</component>
</project>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/PureKitsFork/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/PureKitsFork/src/main/resources" charset="UTF-8" />
</component>
</project>
-30
View File
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="sonatype" />
<option name="name" value="sonatype" />
<option name="url" value="https://oss.sonatype.org/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="papermc-repo" />
<option name="name" value="papermc-repo" />
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/PureKitsFork/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/PureKitPvP.iml" filepath="$PROJECT_DIR$/.idea/PureKitPvP.iml" />
</modules>
</component>
</project>
Generated
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-2023 LukaDeVrij and Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software!
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>PAPER</platformType>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>
+36 -3
View File
@@ -6,12 +6,12 @@
<groupId>me.lifelessnerd.purekitpvp</groupId>
<artifactId>PureKitPvP</artifactId>
<version>1.2</version>
<version>1.3.1</version>
<packaging>jar</packaging>
<name>PureKitPvP</name>
<description>Full KitPvP experience, customizable kits and items</description>
<description>Full KitPvP experience, with customizable kits and items</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -44,6 +44,14 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<outputDirectory>F:\Minecraft\Servers\MC 1.20.6 Server\plugins</outputDirectory>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
@@ -62,14 +70,39 @@
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.20.1-R0.1-SNAPSHOT</version>
<version>1.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- https://github.com/CatCoderr/ProtocolSidebar -->
<dependency>
<groupId>me.catcoder</groupId>
<artifactId>bukkit-sidebar</artifactId>
<version>6.2.7-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.j256.ormlite/ormlite-jdbc -->
<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-jdbc</artifactId>
<version>6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.steveice10/opennbt -->
<dependency>
<groupId>com.github.steveice10</groupId>
<artifactId>opennbt</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,61 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.kitCommand.GetKit;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.plugin.Plugin;
public abstract class AbstractInventory implements Listener {
protected Inventory inv;
protected Plugin plugin;
public AbstractInventory(int size, Component title, Plugin plugin) {
this.plugin = plugin;
// Create a new inventory, with no owner (as this isn't a real inventory)
inv = Bukkit.createInventory(null, size, title);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
// You can call this whenever you want to put the items in
public abstract void initializeItems();
// You can open the inventory with this
public void openInventory(final HumanEntity ent) {
ent.openInventory(inv);
}
public void unregisterEvents(){
HandlerList.unregisterAll(this);
}
// Check for clicks on items
@EventHandler
public void onInventoryClick(final InventoryClickEvent e) {
if (!e.getInventory().equals(inv)) return;
Player player = (Player) e.getWhoClicked();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) return;
// verify current item is not null
if (e.getCurrentItem() == null) return;
onInventoryClickLogic(e);
}
public abstract void onInventoryClickLogic(final InventoryClickEvent e);
@EventHandler
public void onInventoryClose(InventoryCloseEvent e){
if (!e.getInventory().equals(inv)) return;
HandlerList.unregisterAll(this);
}
}
@@ -1,15 +1,22 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.custommobs.CustomMobCommand;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import me.lifelessnerd.purekitpvp.createKit.*;
import me.lifelessnerd.purekitpvp.customitems.GetCustomItem;
import me.lifelessnerd.purekitpvp.customitems.loottablelogic.CreateLootTable;
import me.lifelessnerd.purekitpvp.kitadmin.*;
import me.lifelessnerd.purekitpvp.customItems.GetCustomItem;
import me.lifelessnerd.purekitpvp.customItems.loottable.CreateLootTable;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import me.lifelessnerd.purekitpvp.kitCommand.ResetKit;
import me.lifelessnerd.purekitpvp.globalevents.EventCommand;
import me.lifelessnerd.purekitpvp.globalevents.GlobalEventManager;
import me.lifelessnerd.purekitpvp.globalevents.events.AbstractEvent;
import me.lifelessnerd.purekitpvp.kitadmin.ResetKit;
import me.lifelessnerd.purekitpvp.kitadmin.KitSupercommand;
import me.lifelessnerd.purekitpvp.noncombatstats.commands.GetKitStats;
import org.bukkit.ChatColor;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -29,16 +36,17 @@ public class AdminCommandManager implements TabExecutor {
ArrayList<Subcommand> subcommands = new ArrayList<>();
Plugin plugin;
GlobalEventManager globalEventManager;
public AdminCommandManager(Plugin plugin) {
subcommands.add(new CreateKit(plugin));
subcommands.add(new DeleteKit(plugin));
subcommands.add(new KitSupercommand((PureKitPvP) plugin));
subcommands.add(new ResetKit());
subcommands.add(new SetKillItem(plugin));
//subcommands.add(new SetPerk(plugin));
subcommands.add(new GetKitStats(plugin));
this.globalEventManager = new GlobalEventManager(plugin);
subcommands.add(new EventCommand(plugin, this.globalEventManager));
subcommands.add(new CreateLootTable(plugin));
subcommands.add(new GetCustomItem());
subcommands.add(new CustomMobCommand());
subcommands.add(new GetKitStats(plugin));
subcommands.add(new AdminHelpCommand(subcommands, plugin));
subcommands.add(new InfoCommand());
subcommands.add(new ReloadPlugin(plugin));
@@ -48,32 +56,35 @@ public class AdminCommandManager implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage("The console cannot perform these commands.");
return false;
}
Player player = (Player) sender;
if (!(player.hasPermission("purekitpvp.admin.*"))) {
player.sendMessage(ChatColor.RED + "You do not have permission!");
if (!(sender.hasPermission("purekitpvp.admin.*"))) {
sender.sendMessage(LanguageConfig.lang.get("GENERIC_NO_PERMISSION"));
return true;
}
if (args.length < 1) {
player.sendMessage("Please specify what function to use.");
sender.sendMessage(LanguageConfig.lang.get("GENERIC_LACK_OF_ARGS"));
return false;
}
//Check for names of subcommands in arg
for (int i = 0; i < getSubcommands().size(); i++) {
if (args[0].equalsIgnoreCase(getSubcommands().get(i).getName())) {
boolean result = getSubcommands().get(i).perform(player, args);
if (sender instanceof Player) {
getSubcommands().get(i).perform(sender, args);
} else {
if (!getSubcommands().get(i).getConsoleExecutable()){
sender.sendMessage(Component.text("The console cannot perform this command!"));
} else {
getSubcommands().get(i).perform(sender, args);
}
}
return true; // All help dialogs are done in-class with player.sendMessage
}
}
player.sendMessage(args[0] + " is not a valid sub-command.");
TextReplacementConfig config = ComponentUtils.replaceConfig("%ARG%", args[0]);
sender.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_ARGS").replaceText(config));
return false;
}
@@ -133,67 +144,97 @@ public class AdminCommandManager implements TabExecutor {
return arguments;
}
}
if (args[0].equalsIgnoreCase("setkillitem")) {
if (args[0].equalsIgnoreCase("kit")){
if (args.length == 2) {
List<String> autoComplete = new ArrayList<>();
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
if (args.length == 2){
List<String> arguments = new ArrayList<>();
arguments.add("setkillitem");
arguments.add("delete");
arguments.add("create");
arguments.add("edit");
return arguments;
}
if (args[1].equalsIgnoreCase("setkillitem")) {
if (args.length == 3) {
List<String> autoComplete = new ArrayList<>();
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
}
;
return autoComplete;
}
;
return autoComplete;
}
}
if (args[0].equalsIgnoreCase("deletekit")) {
if (args[1].equalsIgnoreCase("delete")) {
if (args.length == 2) {
List<String> autoComplete = new ArrayList<>();
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
if (args.length == 3) {
List<String> autoComplete = new ArrayList<>();
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
}
return autoComplete;
}
;
return autoComplete;
}
}
if (args[0].equalsIgnoreCase("createkit")) {
if (args[1].equalsIgnoreCase("create")) {
if (args.length == 2) {
List<String> arguments = new ArrayList<>();
arguments.add("<kitName>");
return arguments;
}
if (args.length == 3) {
List<String> arguments = new ArrayList<>();
arguments.add("&1");
arguments.add("&2");
arguments.add("&3");
arguments.add("&4");
arguments.add("&5");
arguments.add("&6");
arguments.add("&7");
arguments.add("&8");
arguments.add("&9");
arguments.add("&0");
if (args.length == 3) {
List<String> arguments = new ArrayList<>();
arguments.add("<kitName>");
return arguments;
}
if (args.length == 4) {
List<String> arguments = new ArrayList<>();
arguments.add("black");
arguments.add("dark_blue");
arguments.add("dark_green");
arguments.add("dark_aqua");
arguments.add("dark_red");
arguments.add("dark_purple");
arguments.add("gold");
arguments.add("gray");
arguments.add("dark_gray");
arguments.add("blue");
arguments.add("green");
arguments.add("aqua");
arguments.add("red");
arguments.add("light_purple");
arguments.add("yellow");
arguments.add("white");
return arguments;
}
if (args.length == 4) {
KitIcon kitIconLib = new KitIcon();
return arguments;
}
if (args.length == 5) {
KitIcon kitIconLib = new KitIcon();
return Arrays.asList(kitIconLib.materialList);
}
if (args.length == 5) {
List<String> arguments = new ArrayList<>();
arguments.add("kit.other");
return Arrays.asList(kitIconLib.materialList);
}
if (args.length == 6) {
List<String> arguments = new ArrayList<>();
arguments.add("kit.other");
return arguments;
return arguments;
}
if (args.length == 7) {
KitIcon kitIconLib = new KitIcon();
return Arrays.asList(kitIconLib.materialList);
}
}
if (args.length == 6) {
KitIcon kitIconLib = new KitIcon();
return Arrays.asList(kitIconLib.materialList);
if (args[1].equalsIgnoreCase("edit")){
if (args.length == 3) {
List<String> autoComplete = new ArrayList<>();
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
}
return autoComplete;
}
}
}
if (args[0].equalsIgnoreCase("custommob")) {
if (args.length == 2) {
@@ -250,6 +291,24 @@ public class AdminCommandManager implements TabExecutor {
return new ArrayList<>(MobSpawnConfig.get().getKeys(false));
}
}
if (args[0].equalsIgnoreCase("event")){
if (args.length == 2) {
List<String> autoComplete = new ArrayList<>();
autoComplete.add("start");
autoComplete.add("stop");
autoComplete.add("pause");
return autoComplete;
}
if (args[1].equalsIgnoreCase("start") || args[1].equalsIgnoreCase("stop") ){
if (args.length == 3) {
List<String> autoComplete = new ArrayList<>();
for (AbstractEvent event : globalEventManager.enabledByConfig) {
autoComplete.add(event.getEventName().replace(' ', '_').toLowerCase());
}
return autoComplete;
}
}
}
return new ArrayList<>();
}
}
@@ -1,8 +1,14 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
@@ -36,8 +42,13 @@ public class AdminHelpCommand extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return true;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand();
if (args.length == 1){
String message = """
&bPureKitPvP - Help Menu
@@ -45,10 +56,12 @@ public class AdminHelpCommand extends Subcommand {
&a/getkit <kit> &r- &eGet a kit directly
&a/suicide &r- &eCommit suicide (if enabled)
&a/stats <player> &r- &eGet PVP stats of a player
&a/perks &r- &eSelect perks
&a/purekitpvphelp &r- &eShow this menu for non-admins
&bFor admin commands, see &a/pkpvp help 2&b!
""";
player.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
sender.sendMessage(serializer.deserialize(message));
}
@@ -56,13 +69,15 @@ public class AdminHelpCommand extends Subcommand {
if (args[1].equalsIgnoreCase("2")){
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&bPureKitPvP - Admin Commands"));
sender.sendMessage(Component.text("PureKitPvP - Admin Commands").color(NamedTextColor.BLUE));
for (Subcommand subcommand : subcommands){
String message =
"&a" + subcommand.getSyntax() + " &r- &e" + subcommand.getDescription();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
String message = "&a" + subcommand.getSyntax() + " &r- &e" + subcommand.getDescription();
sender.sendMessage(serializer.deserialize(message));
}
} else {
TextReplacementConfig config = ComponentUtils.replaceConfig("%ARG%", args[1]);
sender.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_WRONG_ARGS.toString()).replaceText(config));
}
}
@@ -1,6 +1,7 @@
package me.lifelessnerd.purekitpvp;
import org.bukkit.ChatColor;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -15,16 +16,8 @@ public class HelpCommand implements CommandExecutor {
return false;
}
String message = """
&bPureKitPvP - Help Menu
&a/kit &r- &eOpen up the kit menu
&a/getkit <kit> &r- &eGet a kit directly
&a/suicide &r- &eCommit suicide (if enabled)
&a/stats <player> &r- &eGet PVP stats of a player
&a/perks &r- &eSelect perks
&bFor admin commands, see &a/pkpvp help 2&b!
""";
player.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
Component message = LanguageConfig.lang.get("GENERIC_PLAYER_HELP");
player.sendMessage(message);
return true;
}
}
@@ -1,6 +1,8 @@
package me.lifelessnerd.purekitpvp;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class InfoCommand extends Subcommand{
@@ -27,17 +29,24 @@ public class InfoCommand extends Subcommand{
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return true;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
String message =
"""
&bPureKitPvP - version 1.2
&bPureKitPvP - version 1.3.1
&6Discord Support: &ohttps://discord.com/invite/8n65jSEkVf
&6SpigotMC: &ohttps://bit.ly/PureKitPvPSpigotMC
&6Github: &ohttps://github.com/LifelessNerd/PureKitPvP
&6Developer: &ohttps://twitter.com/NerdLifeless
&6Developer: &ohttps://twitter.com/LukaDeVrij
&rIf you have any problems, bugs or glitches, please do reach out to me via any of the links above.
""";
player.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand();
sender.sendMessage(serializer.deserialize(message));
return true;
}
@@ -1,22 +1,25 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.combathandlers.*;
import me.lifelessnerd.purekitpvp.combathandlers.leveling.PlayerLevelChat;
import me.lifelessnerd.purekitpvp.combathandlers.libs.commands.Suicide;
import me.lifelessnerd.purekitpvp.combathandlers.killhandler.Suicide;
import me.lifelessnerd.purekitpvp.combathandlers.mobhandler.OnPlayerSpawnMob;
import me.lifelessnerd.purekitpvp.combathandlers.killhandler.DeathHandler;
import me.lifelessnerd.purekitpvp.database.KitDatabase;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.globalevents.events.DoubleHealthListeners;
import me.lifelessnerd.purekitpvp.scoreboards.SidebarScoreboard;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsCommand;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsGUIListener;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.inventories.KillEffectInventory;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.inventories.KillMessageInventory;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.inventories.ProjectileTrailInventory;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners.KillEffect;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners.KillMessage;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners.ProjectileTrail;
import me.lifelessnerd.purekitpvp.perks.perkCommand.PerkCommand;
import me.lifelessnerd.purekitpvp.perks.perkCommand.PerkGUIListener;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkFireHandler;
import me.lifelessnerd.purekitpvp.customitems.GoldenHeadEat;
import me.lifelessnerd.purekitpvp.customitems.OpenRandomChest;
import me.lifelessnerd.purekitpvp.customItems.GoldenHeadEat;
import me.lifelessnerd.purekitpvp.customItems.OpenRandomChest;
import me.lifelessnerd.purekitpvp.files.*;
import me.lifelessnerd.purekitpvp.kitCommand.GUIListener;
import me.lifelessnerd.purekitpvp.kitCommand.GetKit;
@@ -24,24 +27,40 @@ import me.lifelessnerd.purekitpvp.kitCommand.KitsGUI;
import me.lifelessnerd.purekitpvp.noncombatstats.commands.GetStats;
import me.lifelessnerd.purekitpvp.noncombatstats.listeners.ArrowsShotStat;
import me.lifelessnerd.purekitpvp.noncombatstats.listeners.ProjectilesThrownStat;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.SQLException;
public final class PureKitPvP extends JavaPlugin {
private KitDatabase kitDatabase;
@Override
public void onEnable() {
PerkFireHandler.plugin = this; //idk? fixes npe?
PluginGetter.plugin = this; //this is dumb but used in >= 2 instances
// Has to be at the start because other class constructors use it
getConfig().options().copyDefaults();
saveDefaultConfig();
saveConfig();
//Database
try {
// Ensure the plugin's data folder exists
if (!getDataFolder().exists()) {
getDataFolder().mkdirs();
}
kitDatabase = new KitDatabase(getDataFolder().getAbsolutePath() + "/kitdatabase.db");
} catch (SQLException e) {
e.printStackTrace();
System.out.println("Failed to connect to database! " + e.getMessage());
Bukkit.getPluginManager().disablePlugin(this);
}
//Kits config
KitConfig.setup();
KitConfig.get().addDefault("kits", "");
//Might create problems, I tried to just keep value null but then the entire value didn't show up until I created a kit
//Which is not too bad either so whatever, if there are any problems ever change this and hope for the best
//Otherwise find a way to make a path without a value, like: kits: , instead of kits: ''
//: fix this with createConfiguration if I feel like it, tbf it works fine (IT DOES)
KitConfig.get().options().copyDefaults(true);
KitConfig.save();
@@ -70,6 +89,14 @@ public final class PureKitPvP extends JavaPlugin {
CosmeticsConfig.get().options().copyDefaults(true);
CosmeticsConfig.save();
LanguageConfig.setup();
LanguageConfig.get().options().copyDefaults(true);
LanguageConfig.save();
LanguageConfig.loadLanguage();
SidebarScoreboard scoreboard = new SidebarScoreboard(this);
getCommand("getkit").setExecutor(new GetKit(this));
getCommand("kit").setExecutor(new KitsGUI(this));
getCommand("perk").setExecutor(new PerkCommand(this));
@@ -93,6 +120,10 @@ public final class PureKitPvP extends JavaPlugin {
getServer().getPluginManager().registerEvents(new PlayerLevelChat(this), this);
getServer().getPluginManager().registerEvents(new ChickenPrevention(this), this);
getServer().getPluginManager().registerEvents(new PickupListener(this), this);
getServer().getPluginManager().registerEvents(new BlockRemover(this), this);
// getServer().getPluginManager().registerEvents(new KitPreviewListener(this), this);
getServer().getPluginManager().registerEvents(new ProjectileRemover(this), this);
getServer().getPluginManager().registerEvents(new DoubleHealthListeners(this), this);
getServer().getPluginManager().registerEvents(new CosmeticsGUIListener(this), this);
getServer().getPluginManager().registerEvents(new KillEffect(this), this);
@@ -100,8 +131,7 @@ public final class PureKitPvP extends JavaPlugin {
getServer().getPluginManager().registerEvents(new ProjectileTrail(this), this);
getServer().getPluginManager().registerEvents(new ProjectileTrailInventory(this), this);
getServer().getPluginManager().registerEvents(new KillMessageInventory(this), this);
PerkFireHandler.plugin = this; //idk? fixes npe?
PluginGetter.plugin = this; //this is dumb but used in 2 instances
getLogger().info("Enabled PureKitPvP");
getLogger().warning("Plugin active in world " + getConfig().getString("world") + ". To change this, see the config.");
@@ -112,5 +142,8 @@ public final class PureKitPvP extends JavaPlugin {
getLogger().info("Goodbye!");
}
public KitDatabase getKitDatabase() {
return kitDatabase;
}
}
@@ -1,12 +1,13 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.files.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.scoreboards.SidebarScoreboard;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import java.io.File;
public class ReloadPlugin extends Subcommand {
Plugin plugin;
@@ -35,7 +36,12 @@ public class ReloadPlugin extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return true;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
KitConfig.reload();
KitConfig.save();
@@ -58,12 +64,21 @@ public class ReloadPlugin extends Subcommand {
CosmeticsConfig.reload();
CosmeticsConfig.save();
LanguageConfig.reload();
LanguageConfig.loadLanguage();
LanguageConfig.save();
plugin.reloadConfig();
plugin.getConfig();
plugin.saveConfig();
plugin.saveDefaultConfig();
player.sendMessage("Plugin configs were reloaded!");
SidebarScoreboard scoreboard = new SidebarScoreboard(plugin); // Make new Scoreboard instance
sender.sendMessage(Component.text("Plugin configs were reloaded!"));
sender.sendMessage(Component.text("Please note that settings relating to events are not reloaded." +
"\nIf you have made such changes, a server reload/restart is required.").color(NamedTextColor.GRAY));
return true;
}
@@ -2,6 +2,7 @@ package me.lifelessnerd.purekitpvp;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -15,6 +16,8 @@ public abstract class Subcommand {
public abstract String getSyntax();
public abstract boolean perform(Player player, String[] args);
public abstract boolean getConsoleExecutable();
public abstract boolean perform(CommandSender player, String[] args);
}
@@ -0,0 +1,42 @@
package me.lifelessnerd.purekitpvp.combathandlers;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.plugin.Plugin;
public class BlockRemover implements Listener {
Plugin plugin;
public BlockRemover(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlaceBlock(BlockPlaceEvent event) {
Player player = event.getPlayer();
Block placedBlock = event.getBlockPlaced();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (!(plugin.getConfig().getBoolean("remove-blocks"))){
return;
}
// If player is in survival // adventure -> remove block
if (player.getGameMode() == GameMode.CREATIVE){
return;
}
long secDelay = plugin.getConfig().getInt("remove-blocks-delay");
Bukkit.getScheduler().runTaskLater(this.plugin, () ->
{
placedBlock.getLocation().getBlock().setType(Material.AIR);
}, secDelay * 20);
}
}
@@ -2,12 +2,8 @@ package me.lifelessnerd.purekitpvp.combathandlers;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkFireHandler;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
@@ -1,6 +1,5 @@
package me.lifelessnerd.purekitpvp.combathandlers;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
@@ -0,0 +1,75 @@
package me.lifelessnerd.purekitpvp.combathandlers;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashMap;
public class ProjectileRemover implements Listener {
Plugin plugin;
static HashMap<Projectile, Player> projectiles;
public ProjectileRemover(Plugin plugin) {
this.plugin = plugin;
projectiles = new HashMap<>();
}
@EventHandler
public void onProjectileLaunch(PlayerLaunchProjectileEvent e){
Player player = e.getPlayer();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
addToHashMap(e.getProjectile(), player);
}
@EventHandler
public void playerShootArrow(EntityShootBowEvent e){
if (!(e.getEntity() instanceof Player player)) {
return;
}
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
addToHashMap((Projectile) e.getProjectile(), player);
// Cast? What can be shot with a bow that isn't a projectile?!
}
private void addToHashMap(Projectile proj, Player player) {
projectiles.put(proj, player);
new BukkitRunnable() {
@Override
public void run() {
projectiles.remove(proj, player);
// System.out.println("removed something: now " + projectiles.size());
}
}.runTaskLater(plugin, 300L);
}
public static void removeExistingProjectiles(Player player){
try {
for (Projectile projectile : projectiles.keySet()){
if (projectiles.get(projectile).equals(player) && !(projectile.isDead())){
// System.out.println("removing things");
// System.out.println(projectiles.size());
projectile.remove();
}
}
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
@@ -7,7 +7,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.logging.Level;
@@ -35,9 +34,7 @@ public class VoidKiller implements Listener {
for (PotionEffect effect : p.getActivePotionEffects()) {
p.removePotionEffect(effect.getType());
}
p.setHealth(1);
Location tpLoc = new Location(loc.getWorld(), loc.getX(), loc.getY() - 150, loc.getZ());
p.teleport(tpLoc);
p.chat("/suicide");
}
} catch (Exception ex) {
plugin.getLogger().log(Level.SEVERE, "Please set voidY in the config!");
@@ -1,18 +1,25 @@
package me.lifelessnerd.purekitpvp.combathandlers.killhandler;
import me.lifelessnerd.purekitpvp.combathandlers.ProjectileRemover;
import me.lifelessnerd.purekitpvp.combathandlers.leveling.PlayerLeveling;
import me.lifelessnerd.purekitpvp.combathandlers.libs.DamageCauseLib;
import me.lifelessnerd.purekitpvp.combathandlers.mobhandler.MobRemover;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners.KillEffect;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners.KillMessage;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.globalevents.EventDataClass;
import me.lifelessnerd.purekitpvp.globalevents.events.JuggernautListeners;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkFireHandler;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.DoubleUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.title.Title;
import org.bukkit.*;
import org.bukkit.configuration.file.FileConfiguration;
@@ -28,8 +35,8 @@ import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
@@ -53,6 +60,7 @@ public class DeathHandler implements Listener {
public void onDeath(PlayerDeathEvent e){
Player player = e.getPlayer();
Location deathLocation = player.getLocation();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
@@ -63,10 +71,34 @@ public class DeathHandler implements Listener {
double y = plugin.getConfig().getDouble("respawnY");
double z = plugin.getConfig().getDouble("respawnZ");
Bukkit.getScheduler().runTaskLater((Plugin)this.plugin, () ->
Bukkit.getScheduler().runTaskLater(this.plugin, () ->
player.teleport(new Location(player.getWorld(), x, y, z, 0, 0)), 1L);
Bukkit.getScheduler().runTaskLater((Plugin)this.plugin, () -> {
player.getInventory().clear();
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {
if (EventDataClass.dropInventoryOnDeath){
// Global Combat Event is active -> drop items on ground
ItemStack[] inventoryItems = player.getInventory().getContents();
ItemStack[] armorItems = player.getInventory().getArmorContents();
ItemStack offhandItem = player.getInventory().getItemInOffHand();
for (ItemStack item : inventoryItems) {
if (item != null)
player.getWorld().dropItemNaturally(deathLocation, item);
}
for (ItemStack item : armorItems) {
if (item != null)
player.getWorld().dropItemNaturally(deathLocation, item);
}
player.getWorld().dropItemNaturally(deathLocation, offhandItem);
player.getInventory().clear();
}
if (plugin.getConfig().getBoolean("inventory-clear")){
player.getInventory().clear();
}
player.getActivePotionEffects().clear();
player.setExp(0f);
player.setLevel(0);
@@ -75,21 +107,34 @@ public class DeathHandler implements Listener {
player.setFireTicks(0);
player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 5, 1));
player.addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 10 , 1));
player.setHealth(20);
player.chat("/kit");
}, 2L);
if (EventDataClass.doubleHealth){
player.setHealth(40);
} else {
player.setHealth(20);
}
}, 2L);
long kitDelay = plugin.getConfig().getLong("auto-kit-delay");
if (kitDelay != -1L) {
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {
player.chat("/kit");
}, kitDelay);
}
// Delete alive projectiles of that player
ProjectileRemover.removeExistingProjectiles(player);
DamageCauseLib damageCauseLib = new DamageCauseLib();
//Get all damage info and print to killed player
// Get all damage info and print to killed player
NamespacedKey key = new NamespacedKey(plugin, "damageDistributionInfo");
PlayerDamageDistribution damageData = player.getPersistentDataContainer().get(key, new PlayerDamageDistributionDataType());
String message = "&c&lYou died!";
player.sendMessage(ChatColor.translateAlternateColorCodes('&',message));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&7Death Recap:"));
player.sendMessage(LanguageConfig.lang.get(LanguageKey.COMBAT_YOU_DIED.toString()));
player.sendMessage(LanguageConfig.lang.get(LanguageKey.COMBAT_DEATH_RECAP.toString()));
// Printing process and formatting
int totalDamageDone = 0;
for (String hashmapKey : damageData.damageDistributionMap.keySet()){
@@ -98,19 +143,11 @@ public class DeathHandler implements Listener {
for (String hashmapKey : damageData.damageDistributionMap.keySet()){
int damageValue = damageData.damageDistributionMap.get(hashmapKey);
double damagePercentage = (double) damageValue / (double) totalDamageDone * 100.0;
if (damageCauseLib.damageCauseTranslations.containsKey(hashmapKey)){
// hashMapKey is a damageCause object
String damageCauseTranslation = damageCauseLib.damageCauseTranslations.get(hashmapKey);
String format = "&7-&e" + damageCauseTranslation + "&7 did &a" + (int) damagePercentage + "%";
player.sendMessage(ChatColor.translateAlternateColorCodes('&', format));
}
else {
String format = "&7- &a" + hashmapKey + "&7 did &a" + (int) damagePercentage + "%";
player.sendMessage(ChatColor.translateAlternateColorCodes('&', format));
}
int damagePercentageInt = (int) damagePercentage;
String damageCause = damageCauseLib.damageCauseTranslations.getOrDefault(hashmapKey, hashmapKey);
player.sendMessage(LanguageConfig.lang.get(LanguageKey.COMBAT_DEATH_CAUSE.toString()).
replaceText(ComponentUtils.replaceConfig("%CAUSE%", damageCause)).
replaceText(ComponentUtils.replaceConfig("%VALUE%", String.valueOf(damagePercentageInt))));
}
//Broadcasting and stuff
@@ -119,7 +156,7 @@ public class DeathHandler implements Listener {
String credit = ""; // Needed for later
boolean playerInvolved = true;
//Check who should get credit
if (damageData.lastPlayerDamager == null && damageData.lastOtherDamager != null){
//This means the player was completely killed by environment, no player killer
// Except when the killer is a zombie of a player -> handled down below
@@ -130,14 +167,10 @@ public class DeathHandler implements Listener {
playerInvolved = false;
}
if (damageData.lastPlayerDamager != null && damageData.lastOtherDamager != null){
if (damageData.lastPlayerDamager != null && damageData.lastOtherDamager != null && (!(damageData.lastPlayerDamager.equalsIgnoreCase(player.getName())))){
//This means player got damage from both
credit = damageData.lastPlayerDamager;
// deathMessage += " was killed by ";
// System.out.println(damageData.lastOtherDamager);
// if (damageData.lastOtherDamager.equalsIgnoreCase("VOID")){
// System.out.println("thrown in void");
// }
if (e.getEntity().getLastDamageCause().getCause().equals(EntityDamageEvent.DamageCause.ENTITY_ATTACK)){
deathMessage = KillMessage.create.byPlayer(player.getName(), damageData.lastPlayerDamager);
@@ -147,12 +180,19 @@ public class DeathHandler implements Listener {
}
}
if (damageData.lastPlayerDamager != null && damageData.lastOtherDamager == null){
if (damageData.lastPlayerDamager != null && damageData.lastOtherDamager == null && (!(damageData.lastPlayerDamager.equals(player.getName())))){
//Means player has only been hit by other players
credit = damageData.lastPlayerDamager;
deathMessage = KillMessage.create.byPlayer(player.getName(), damageData.lastPlayerDamager);
}
if (damageData.lastPlayerDamager != null){
if (damageData.lastPlayerDamager.equalsIgnoreCase(player.getName())){ // own kill check
deathMessage = KillMessage.create.byPlayer(player.getName(), damageData.lastPlayerDamager);
playerInvolved = false;
}
}
// deathMessage = deathMessage + credit;
// Death message shows who got credit, broadcast to every player in pvp world
@@ -162,8 +202,7 @@ public class DeathHandler implements Listener {
}
}
Component mainTitle = Component.text("You died!").color(TextColor.color(230,60,60));
Component mainTitle = LanguageConfig.lang.get(LanguageKey.COMBAT_YOU_DIED.toString());
Title title = Title.title(mainTitle, Component.text(""));
player.showTitle(title);
@@ -181,7 +220,9 @@ public class DeathHandler implements Listener {
for (String key2 : damageData.damageDistributionMap.keySet()){
if (!(key2.equalsIgnoreCase(credit)) && pvpPlayers.contains(key2) && pvpPlayers.contains(player.getName())){
// Don't count the killer in the assist check
// Don't count the killed player himself in the assist check
if (key2.equals(player.getName())){
continue;// Don't count the killed player himself in the assist check
}
//Only check players for assist
if (highestAssistor == null){
highestAssistor = key2;
@@ -204,15 +245,15 @@ public class DeathHandler implements Listener {
// Player was killed, all damage info reset
player.getPersistentDataContainer().remove(key);
//Sound effects and such
player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_HURT, 1,0);
//Set stats of player
//Check if player has an entry in config
FileConfiguration playerStats = PlayerStatsConfig.get();
if (PlayerStatsConfig.get().isSet(player.getName())){
FileConfiguration playerStats = PlayerStatsConfig.get();
playerStats.set(player.getName() + ".deaths", playerStats.getInt(player.getName() + ".deaths") + 1);
//Ratio update
@@ -225,26 +266,6 @@ public class DeathHandler implements Listener {
PlayerStatsConfig.save();
TextComponent actionBarText = Component.text("Deaths: ", NamedTextColor.GREEN)
.append(Component.text(playerStats.getInt(player.getName() + ".deaths"), NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" K/D: ", NamedTextColor.GREEN));
try {
actionBarText = actionBarText.append(Component.text((DoubleUtils.round(playerStats.getDouble(player.getName() + ".kdratio"), 2)), NamedTextColor.LIGHT_PURPLE));
} catch (Exception exception){
actionBarText = actionBarText.append(Component.text("Infinity", NamedTextColor.LIGHT_PURPLE));
}
//update level
PlayerLeveling.createLevelXPPath(player.getName());
// PlayerLeveling.addExperience(player, 1, "Death"); // 1 for DEATH// Ah no: can be exploited
// PlayerLeveling.updateLevels();
//remove any mobs player spawned
MobRemover.removeMobs(player);
player.sendActionBar(actionBarText);
} else {
//Player does not have an entry; creating one with new data
PlayerStatsConfig.get().set(player.getName(), "");
@@ -257,13 +278,31 @@ public class DeathHandler implements Listener {
}
TextComponent actionBarText = Component.text("Deaths: ", NamedTextColor.GREEN)
.append(Component.text(playerStats.getInt(player.getName() + ".deaths"), NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" K/D: ", NamedTextColor.GREEN));
try {
actionBarText = actionBarText.append(Component.text((DoubleUtils.round(playerStats.getDouble(player.getName() + ".kdratio"), 2)), NamedTextColor.LIGHT_PURPLE));
} catch (Exception exception){
actionBarText = actionBarText.append(Component.text("Infinity", NamedTextColor.LIGHT_PURPLE));
}
//update level
PlayerLeveling.createLevelXPPath(player.getName());
//remove any mobs player spawned
MobRemover.removeMobs(player);
player.sendActionBar(actionBarText);
//Only give credit if there is a player involved,
if (playerInvolved){
Player creditPlayer = Bukkit.getPlayerExact(credit);
creditPlayer.playSound(creditPlayer.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_HIT,1, 1);
//Check if player has an entry in config
if (PlayerStatsConfig.get().isSet(creditPlayer.getName())){
FileConfiguration creditStats = PlayerStatsConfig.get();
FileConfiguration creditStats = PlayerStatsConfig.get();
if (creditStats.isSet(creditPlayer.getName())) {
creditStats.set(creditPlayer.getName() + ".kills", creditStats.getInt(creditPlayer.getName() + ".kills") + 1);
//Ratio update
@@ -274,10 +313,10 @@ public class DeathHandler implements Listener {
//Killstreak update
creditStats.set(creditPlayer.getName() + ".killstreak", creditStats.getInt(creditPlayer.getName() + ".killstreak") + 1);
//Killstreak checker
if (creditStats.getInt(creditPlayer.getName() + ".killstreak") % 5 == 0){
if (creditStats.getInt(creditPlayer.getName() + ".killstreak") % 5 == 0) {
creditPlayer.playSound(creditPlayer.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 0.3f, 1);
for (Player pvpPlayer : Bukkit.getOnlinePlayers()){
if (pvpPlayer.getWorld() == player.getWorld()){
for (Player pvpPlayer : Bukkit.getOnlinePlayers()) {
if (pvpPlayer.getWorld() == player.getWorld()) {
pvpPlayer.sendMessage(ChatColor.RED + credit + ChatColor.YELLOW + " is on a KILLING STREAK of " + ChatColor.RED + creditStats.getInt(creditPlayer.getName() + ".killstreak"));
@@ -286,7 +325,7 @@ public class DeathHandler implements Listener {
}
PlayerLeveling.addExperience(creditPlayer, creditStats.getInt(creditPlayer.getName() + ".killstreak"), "Killstreak Bonus");
}
if(plugin.getConfig().getBoolean("killstreak-glowing")) {
if (plugin.getConfig().getBoolean("killstreak-glowing")) {
if (creditStats.getInt(creditPlayer.getName() + ".killstreak") >= 5) {
int duration = plugin.getConfig().getInt("killstreak-glowing-duration");
@@ -295,52 +334,8 @@ public class DeathHandler implements Listener {
}
PlayerStatsConfig.save();
// Actionbar thingies
TextComponent actionBarText = Component.text("Kills: ", NamedTextColor.GREEN)
.append(Component.text(creditStats.getInt(creditPlayer.getName() + ".kills"), NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" K/D: ", NamedTextColor.GREEN));
try {
actionBarText = actionBarText.append(Component.text((DoubleUtils.round(creditStats.getDouble(creditPlayer.getName() + ".kdratio"), 2)), NamedTextColor.LIGHT_PURPLE));
} catch (Exception exception){
actionBarText = actionBarText.append(Component.text("Infinity", NamedTextColor.LIGHT_PURPLE));
}
//update level
PlayerLeveling.createLevelXPPath(creditPlayer.getName());
if (!(creditPlayer == player)){
PlayerLeveling.addExperience(creditPlayer, 5, "Kill"); // 5 for KILL
}
PlayerLeveling.updateLevels();
creditPlayer.sendActionBar(actionBarText);
//Give killItem based on kit
try {
ItemStack killItem = new ItemStack(Material.AIR);
String kitName = PlayerStatsConfig.get().getString(credit + ".current_kit");
if (!(KitConfig.get().getString("kits." + kitName + ".killitem") == null)) {
ItemStack fromFile = (ItemStack) KitConfig.get().get("kits." + kitName + ".killitem");
killItem.setType(fromFile.getType());
killItem.setAmount(fromFile.getAmount());
killItem.setItemMeta(fromFile.getItemMeta());
creditPlayer.getInventory().addItem(killItem);
}
} catch (Exception exception){
plugin.getLogger().log(Level.SEVERE, exception.toString()); //TODO throws here. think i fixed it but not sure
}
//PerkHandler
PerkFireHandler.fireKillPerks(creditPlayer);
//The killcosmetic that the creditPlayer has fires
KillEffect.fireKillCosmetic(player, creditPlayer);
} else {
//Player does not have an entry; creating one with new data
//Player does not have an entry; creating one with new data
PlayerStatsConfig.get().set(creditPlayer.getName(), "");
PlayerStatsConfig.get().set(creditPlayer.getName() + ".kills", 1);
PlayerStatsConfig.get().set(creditPlayer.getName() + ".deaths", 0);
@@ -351,30 +346,62 @@ public class DeathHandler implements Listener {
}
// Actionbar thingies
actionBarText = Component.text("Kills: ", NamedTextColor.GREEN)
.append(Component.text(creditStats.getInt(creditPlayer.getName() + ".kills"), NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" K/D: ", NamedTextColor.GREEN));
try {
actionBarText = actionBarText.append(Component.text((DoubleUtils.round(creditStats.getDouble(creditPlayer.getName() + ".kdratio"), 2)), NamedTextColor.LIGHT_PURPLE));
} catch (Exception exception){
actionBarText = actionBarText.append(Component.text("Infinity", NamedTextColor.LIGHT_PURPLE));
}
//update level
PlayerLeveling.createLevelXPPath(creditPlayer.getName());
if (!(creditPlayer == player)){
PlayerLeveling.addExperience(creditPlayer, 5, "Kill"); // 5 for KILL
}
PlayerLeveling.updateLevels();
creditPlayer.sendActionBar(actionBarText);
//Give killItem based on kit
try {
ItemStack killItem = new ItemStack(Material.AIR);
String kitName = PlayerStatsConfig.get().getString(credit + ".current_kit");
if (!(KitConfig.get().getString("kits." + kitName + ".killitem") == null)) {
ItemStack fromFile = (ItemStack) KitConfig.get().get("kits." + kitName + ".killitem");
killItem.setType(fromFile.getType());
killItem.setAmount(fromFile.getAmount());
killItem.setItemMeta(fromFile.getItemMeta());
creditPlayer.getInventory().addItem(killItem);
}
} catch (Exception exception){
plugin.getLogger().log(Level.SEVERE, exception.toString()); // throws here. think i fixed it but not sure - i dont see anything
}
//PerkHandler
PerkFireHandler.fireKillPerks(creditPlayer);
//Juggernaut Event check
JuggernautListeners.onDeath(player, creditPlayer);
//The killcosmetic that the creditPlayer has fires
KillEffect.fireKillCosmetic(player, creditPlayer);
}
// If there is an assistor, we need to do some stuff for that player
if (assistor != null){
if (PlayerStatsConfig.get().isSet(assistor.getName())){
FileConfiguration assistorStats = PlayerStatsConfig.get();
FileConfiguration assistorStats = PlayerStatsConfig.get();
if (assistorStats.isSet(assistor.getName())){
assistorStats.set(assistor.getName() + ".assists", assistorStats.getInt(assistor.getName() + ".assists") + 1);
PlayerStatsConfig.save();
TextComponent actionBarText = Component.text("Assists: ", NamedTextColor.GREEN)
.append(Component.text(assistorStats.getInt(assistor.getName() + ".assists"), NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" K/D: ", NamedTextColor.GREEN))
.append(Component.text((assistorStats.getDouble(assistor.getName() + ".kdratio")), NamedTextColor.LIGHT_PURPLE));
assistor.sendActionBar(actionBarText);
//update level TODO: check this: I think this is in the wrong spot since it doesn't seem to work?
// Need a 3rd player or alt to test
PlayerLeveling.createLevelXPPath(assistor.getName());
PlayerLeveling.addExperience(assistor, 3, "Assist"); // 3 for assists
PlayerLeveling.updateLevels();
} else {
//Player does not have an entry; creating one with new data
PlayerStatsConfig.get().set(assistor.getName(), "");
@@ -386,14 +413,27 @@ public class DeathHandler implements Listener {
PlayerStatsConfig.save();
}
actionBarText = Component.text("Assists: ", NamedTextColor.GREEN)
.append(Component.text(assistorStats.getInt(assistor.getName() + ".assists"), NamedTextColor.LIGHT_PURPLE))
.append(Component.text(" K/D: ", NamedTextColor.GREEN))
.append(Component.text((assistorStats.getDouble(assistor.getName() + ".kdratio")), NamedTextColor.LIGHT_PURPLE));
assistor.sendActionBar(actionBarText);
//update level TODO: check this: I think this is in the wrong spot since it doesn't seem to work?
// Need a 3rd player or alt to test
PlayerLeveling.createLevelXPPath(assistor.getName());
PlayerLeveling.addExperience(assistor, 3, "Assist"); // 3 for assists
PlayerLeveling.updateLevels();
}
}
@EventHandler
public void onPlayerCombatHit(EntityDamageByEntityEvent event){
Player player = null;
Player damager = null;
boolean rangedCombat = true; // whether a chat message should be sent; if ranged; yes
// HAND-TO-HAND COMBAT
if (!(event.getEntity().getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
// If the entity that is damaged is in this world, the entire event should be in this world
@@ -409,12 +449,12 @@ public class DeathHandler implements Listener {
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
rangedCombat = false;
PerkFireHandler.fireCombatPerks(player, damager);
PerkFireHandler.fireVampirePerk(event);
} else if ((event.getDamager() instanceof Arrow || event.getDamager() instanceof SpectralArrow) && event.getEntity() instanceof Player) {
//This branch is a fuckin nightmare: too many hacked in exceptions because fucking spectral arrows and fucking skeletons
//This branch is a fuckin nightmare: too many hacked in exceptions because spectral arrows and skeletons
//Projectile combat
if(((AbstractArrow) event.getDamager()).getShooter() instanceof Player){
@@ -429,13 +469,7 @@ public class DeathHandler implements Listener {
PerkFireHandler.fireRangedPerks(event, damager);
double damage = event.getDamage();
double playerHP = player.getHealth() - damage;
if (playerHP < 0) {
playerHP = 0;
}
damager.sendMessage(ChatColor.translateAlternateColorCodes(
'&', "&a" + player.getName() + " &cis on &a" + (int) playerHP + " &cHP."));
} else if(((AbstractArrow) event.getDamager()).getShooter() instanceof Monster){
// Shooter is a skeleton probably
player = (Player) event.getEntity();
@@ -452,13 +486,7 @@ public class DeathHandler implements Listener {
ThrownPotion potion = (ThrownPotion) event.getDamager();
damager = (Player) potion.getShooter(); //works
double damage = event.getDamage();
double playerHP = player.getHealth() - damage;
if (playerHP < 0){
playerHP = 0;
}
damager.sendMessage(ChatColor.translateAlternateColorCodes(
'&', "&a" + player.getName() + " &cis on &a" + (int) playerHP + " &cHP."));
} else if (event.getDamager() instanceof Trident && event.getEntity() instanceof Player){
@@ -467,13 +495,7 @@ public class DeathHandler implements Listener {
Trident trident = (Trident) event.getDamager();
damager = (Player) trident.getShooter(); //works
double damage = event.getDamage();
double playerHP = player.getHealth() - damage;
if (playerHP < 0){
playerHP = 0;
}
damager.sendMessage(ChatColor.translateAlternateColorCodes(
'&', "&a" + player.getName() + " &cis on &a" + (int) playerHP + " &cHP."));
} else if (event.getDamager() instanceof Monster && event.getEntity() instanceof Player) {
@@ -482,22 +504,47 @@ public class DeathHandler implements Listener {
player = ((Player) event.getEntity()).getPlayer();
} else if (event.getDamager() instanceof EnderPearl && event.getEntity() instanceof Player) {
player = ((Player) event.getEntity()).getPlayer();
rangedCombat = false;
PerkFireHandler.fireEnderpearlDamagePerks((Player) event.getEntity(), event);
return;
}
else if (event.getDamager() instanceof Firework && event.getEntity() instanceof Player){
return; // Prevents NPE's
} else if (event.getDamager() instanceof Firework && event.getEntity() instanceof Player){
Firework fw = (Firework) event.getDamager();
if (fw.hasMetadata("nodamage")) {
event.setCancelled(true);
return;
}
if (fw.getShooter() instanceof Player){
player = (Player) event.getEntity();
damager = (Player) fw.getShooter();
} else {return;}
}
}
else {
//If we end up here idk what happened but nothing relevant (probably a zombie hitting a pig or something)
return;
}
// HP Message
if (rangedCombat){
double damage = event.getDamage();
double playerHP = player.getHealth() - damage;
if (playerHP < 0){
playerHP = 0;
}
DecimalFormat decimalFormat = new DecimalFormat("#.#");
String formattedDamage = decimalFormat.format(damage);
String formattedHP = decimalFormat.format(playerHP);
damager.sendMessage(
Component.text(player.getName(), NamedTextColor.GREEN).append(
Component.text(" is on ", NamedTextColor.RED).append(
Component.text(formattedHP, NamedTextColor.GREEN).append(
Component.text(" HP!", NamedTextColor.RED)
))));
damager.sendMessage(
Component.text(" You dealt ", NamedTextColor.GRAY).append(
Component.text(formattedDamage, NamedTextColor.GREEN).append(
Component.text(" damage!", NamedTextColor.GRAY))));
}
int damageAmount = (int) event.getDamage();
@@ -547,7 +594,6 @@ public class DeathHandler implements Listener {
@EventHandler
public void onPlayerTakeDamage(EntityDamageEvent event){
//EVERYTHING WHERE A PLAYER IS NOT INVOLVED
if (!(event.getEntity() instanceof Player)){
return;
@@ -575,7 +621,7 @@ public class DeathHandler implements Listener {
EntityDamageEvent.DamageCause cause = event.getCause();
// This branch prevents fall damage from happening in the spawn area; it also returns so that it does not get added to damageDistribution
if (event.getCause() == EntityDamageEvent.DamageCause.FALL){
if (cause == EntityDamageEvent.DamageCause.FALL){
Location fallLocation = player.getLocation();
// - 0.5 because block and player location are off by 0.5 because Minecraft
@@ -593,7 +639,8 @@ public class DeathHandler implements Listener {
}
}
}
// This branch negates any firework damage if it is of killeffect origin -> fireworks from a crossbow still count
// This branch negates any firework damage if
// it is of killeffect origin -> fireworks from a crossbow still count
if (event.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) {
EntityDamageByEntityEvent newEvent = (EntityDamageByEntityEvent) event;
if (newEvent.getDamager() instanceof Firework fw) {
@@ -0,0 +1,70 @@
package me.lifelessnerd.purekitpvp.combathandlers.killhandler;
import com.google.common.collect.ImmutableMap;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import org.bukkit.NamespacedKey;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;
import java.util.EnumMap;
public class Suicide implements CommandExecutor {
Plugin plugin;
public Suicide(Plugin plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player player)){
return true;
}
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return true;
}
if (!(plugin.getConfig().getBoolean("suicide-command"))){
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_FEATURE_DISABLED.toString()));
return true;
}
for(PotionEffect effect:player.getActivePotionEffects()){
//Now use the method Player#removePotionEffect to remove the potion effect. This method accepts a PotionEffectType, so we need to get the type of the effect variable, and then remove it:
player.removePotionEffect(effect.getType());
}
try {
NamespacedKey key = new NamespacedKey(plugin, "damageDistributionInfo");
if (!(player.getPersistentDataContainer().has(key,new PlayerDamageDistributionDataType()))){
//Player does not have dataContainer, creating one with data from this hit
//Make new object with that player, is mostly empty
PlayerDamageDistribution damageDistrib = new PlayerDamageDistribution(player);
player.getPersistentDataContainer().set(key, new PlayerDamageDistributionDataType(), damageDistrib);
}
PlayerDamageDistribution damageData = player.getPersistentDataContainer().get(key, new PlayerDamageDistributionDataType());
damageData.lastOtherDamager = "SUICIDE"; // NPE lies
damageData.damageDistributionMap.put("SUICIDE", 100000);
player.getPersistentDataContainer().set(key, new PlayerDamageDistributionDataType(), damageData);
} catch (Exception e){
System.out.println(e.getMessage());
}
player.setHealth(0);
return true;
}
}
@@ -1,9 +1,6 @@
package me.lifelessnerd.purekitpvp.combathandlers.leveling;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -1,6 +1,9 @@
package me.lifelessnerd.purekitpvp.combathandlers.leveling;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
@@ -52,7 +55,8 @@ public class PlayerLeveling {
int level = xpValue / 100;
if (!(level == playerStats.getInt(key + ".level"))){
Player player = Bukkit.getPlayerExact(key);
player.sendMessage(ChatColor.GOLD + "You leveled up to LEVEL " + level);
player.sendMessage(LanguageConfig.lang.get(LanguageKey.STATS_LEVEL_UP.toString()).
replaceText(ComponentUtils.replaceConfig("%VALUE%", String.valueOf(level))));
}
playerStats.set(key + ".level", level);
@@ -38,34 +38,34 @@ public class DamageCauseLib {
deathMessages.put("SONIC_BOOM"," got pummeled by a Warden");
deathMessages.put("MONSTER", " was killed by a mob, what a noob.");
damageCauseTranslations.put("CONTACT"," Cactus");
damageCauseTranslations.put("SUFFOCATION"," Suffocation");
damageCauseTranslations.put("FALL"," Fall Damage");
damageCauseTranslations.put("FIRE"," Fire");
damageCauseTranslations.put("FIRE_TICK"," Fire");
damageCauseTranslations.put("MELTING"," Lava");
damageCauseTranslations.put("LAVA"," Lava");
damageCauseTranslations.put("DROWNING"," Drowning");
damageCauseTranslations.put("BLOCK_EXPLOSION"," Explosion");
damageCauseTranslations.put("ENTITY_EXPLOSION"," Explosion");
damageCauseTranslations.put("VOID"," Void");
damageCauseTranslations.put("LIGHTNING"," Lightning");
damageCauseTranslations.put("SUICIDE"," Yourself");
damageCauseTranslations.put("STARVATION"," Hunger");
damageCauseTranslations.put("POISON"," Poison");
damageCauseTranslations.put("MAGIC"," Harming Effect");
damageCauseTranslations.put("WITHER"," Wither Effect");
damageCauseTranslations.put("FALLING_BLOCK"," Falling Blocks");
damageCauseTranslations.put("THORNS"," Thorns");
damageCauseTranslations.put("DRAGON_BREATH"," Dragon's Breath");
damageCauseTranslations.put("CUSTOM"," ???");
damageCauseTranslations.put("FLY_INTO_WALL"," Kinetic Energy");
damageCauseTranslations.put("HOT_FLOOR"," Magma");
damageCauseTranslations.put("CRAMMING"," Crowding");
damageCauseTranslations.put("DRYOUT"," Dryout");
damageCauseTranslations.put("FREEZE"," Freezing");
damageCauseTranslations.put("SONIC_BOOM"," Warden");
damageCauseTranslations.put("MONSTER"," Custom Mob");
damageCauseTranslations.put("CONTACT","Cactus");
damageCauseTranslations.put("SUFFOCATION","Suffocation");
damageCauseTranslations.put("FALL","Fall Damage");
damageCauseTranslations.put("FIRE","Fire");
damageCauseTranslations.put("FIRE_TICK","Fire");
damageCauseTranslations.put("MELTING","Lava");
damageCauseTranslations.put("LAVA","Lava");
damageCauseTranslations.put("DROWNING","Drowning");
damageCauseTranslations.put("BLOCK_EXPLOSION","Explosion");
damageCauseTranslations.put("ENTITY_EXPLOSION","Explosion");
damageCauseTranslations.put("VOID","Void");
damageCauseTranslations.put("LIGHTNING","Lightning");
damageCauseTranslations.put("SUICIDE","You");
damageCauseTranslations.put("STARVATION","Hunger");
damageCauseTranslations.put("POISON","Poison");
damageCauseTranslations.put("MAGIC","Harming Effect");
damageCauseTranslations.put("WITHER","Wither Effect");
damageCauseTranslations.put("FALLING_BLOCK","Falling Blocks");
damageCauseTranslations.put("THORNS","Thorns");
damageCauseTranslations.put("DRAGON_BREATH","Dragon's Breath");
damageCauseTranslations.put("CUSTOM","???");
damageCauseTranslations.put("FLY_INTO_WALL","Kinetic Energy");
damageCauseTranslations.put("HOT_FLOOR","Magma");
damageCauseTranslations.put("CRAMMING","Crowding");
damageCauseTranslations.put("DRYOUT","Dryout");
damageCauseTranslations.put("FREEZE","Freezing");
damageCauseTranslations.put("SONIC_BOOM","Warden");
damageCauseTranslations.put("MONSTER","Custom Mob");
}
}
@@ -1,50 +0,0 @@
package me.lifelessnerd.purekitpvp.combathandlers.libs.commands;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;
public class Suicide implements CommandExecutor {
Plugin plugin;
public Suicide(Plugin plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player player)){
return true;
}
if (!(plugin.getConfig().getBoolean("suicide-command"))){
player.sendMessage("This is disabled.");
return true;
}
player.setHealth(1);
for(PotionEffect effect:player.getActivePotionEffects()){
//Now use the method Player#removePotionEffect to remove the potion effect. This method accepts a PotionEffectType, so we need to get the type of the effect variable, and then remove it:
player.removePotionEffect(effect.getType());
}
player.teleport(new Location(player.getWorld(),
player.getLocation().getX(),
plugin.getConfig().getDouble("voidY"),
player.getLocation().getY()
));
//Kind of jank way to do it, but without this damageData is null, this way the void gives final blow
// Other way may be to set damageData.lastDamager to SUICIDE, but then we would have to get the
// PersistentDataContainer and all of its checks once more, so this is actually more efficient
return true;
}
}
@@ -1,11 +1,8 @@
package me.lifelessnerd.purekitpvp.combathandlers.mobhandler;
import it.unimi.dsi.fastutil.Hash;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.HashMap;
public class MobRemover {
public static void removeMobs(Player player){
@@ -1,9 +1,7 @@
package me.lifelessnerd.purekitpvp.combathandlers.mobhandler;
import me.lifelessnerd.purekitpvp.PluginGetter;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.*;
import org.bukkit.entity.*;
@@ -14,21 +12,16 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.SpawnEgg;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
public class OnPlayerSpawnMob implements Listener {
Plugin plugin;
@@ -3,6 +3,7 @@ package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand;
import me.lifelessnerd.purekitpvp.kitCommand.GetKit;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
@@ -25,7 +26,7 @@ import java.util.List;
public class CosmeticsCommand implements CommandExecutor {
Plugin plugin;
public CosmeticsCommand(Plugin plugin) {
public CosmeticsCommand(Plugin plugin) {
this.plugin = plugin;
}
@@ -38,7 +39,9 @@ public class CosmeticsCommand implements CommandExecutor {
Player player = (Player) sender;
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
player.sendMessage(ChatColor.RED + "You can only use this menu in " + ChatColor.GRAY + plugin.getConfig().getString("world"));
player.sendMessage(
Component.text("You can only use this menu in ", NamedTextColor.RED).append(
Component.text(plugin.getConfig().getString("world"), NamedTextColor.GRAY)));
return true;
}
//Create inventory GUI
@@ -50,7 +50,7 @@ public class KillEffectInventory implements Listener {
String configValue = CosmeticsConfig.get().getString("kill_effect." + player.getName());
// if player is not present in file; add it to config and try again
if (configValue == null){
CosmeticsConfig.get().set(player.getName(), plugin.getConfig().getString("default-kill-effect"));
CosmeticsConfig.get().set("kill_effect." + player.getName(), plugin.getConfig().getString("default-kill-effect"));
CosmeticsConfig.save();
CosmeticsConfig.reload();
configValue = CosmeticsConfig.get().getString("kill_effect." + player.getName());
@@ -17,6 +17,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import javax.swing.text.html.HTMLDocument;
import java.util.Random;
import java.util.logging.Level;
public class KillEffect implements Listener {
@@ -99,14 +100,16 @@ public class KillEffect implements Listener {
}
public static void bloodExplosion(Location location) {
Random rnd = new Random();
for (float i = 0.5f; i < 1.8f; i += 0.1) {
float rndFloat = rnd.nextFloat() / 10;
location.getWorld().spawnParticle(
Particle.BLOCK_CRACK,
location.add(0,i,0),
location.add(rndFloat,i,rndFloat),
20,
Material.REDSTONE_BLOCK.createBlockData()
);
location.subtract(rndFloat, i, rndFloat);
}
}
@@ -3,11 +3,8 @@ package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners;
import me.lifelessnerd.purekitpvp.PluginGetter;
import me.lifelessnerd.purekitpvp.combathandlers.libs.DamageCauseLib;
import me.lifelessnerd.purekitpvp.combathandlers.libs.DeathCauseLib;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsCommand;
import me.lifelessnerd.purekitpvp.files.CosmeticsConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Set;
import java.util.logging.Level;
@@ -4,20 +4,17 @@ import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import me.lifelessnerd.purekitpvp.files.CosmeticsConfig;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
public class ProjectileTrail implements Listener {
/* TODO: THIS CLASS HAS DUPOLICATE CODE because of the difference in events -> can be circumvented by passing projectile and player
TODO: can it? since one is projectile and the other is abstractarrow?? CROSSBOWS are added but is a projectile*/
Plugin plugin;
public ProjectileTrail(Plugin plugin) {
@@ -31,69 +28,31 @@ public class ProjectileTrail implements Listener {
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
String trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
if(trail == null){
CosmeticsConfig.get().set("projectile_trail." + player, "none");
CosmeticsConfig.save();
CosmeticsConfig.reload();
trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
}
String trail = checkCosmeticsDefined(player);
// Inspiration from https://github.com/iInvisibilities/spiraltrails/blob/main/SpiralFactory.java
// Not used right now, maybe in the future: this would allow for spirals and such
// Could be extended with https://github.com/iInvisibilities/spiraltrails/blob/main/SpiralFactory.java
Projectile projectile = e.getProjectile();
// System.out.println(projectile.toString());
int rotationSpeed = 30;
final double INCREMENT = (2 * Math.PI) / rotationSpeed;
new BukkitRunnable() {
produceTrailOnProjectile(trail, projectile);
double circlePointOffset = 0;
Location lastLocation = player.getEyeLocation();
}
@Override
public void run() {
if(projectile.isDead() || projectile.isOnGround()) {
this.cancel();
return;
}
String trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
// Could be removed: pass trail into the runnable once at event (How?)
// How? with a class that implements Runnable - a lot of code -> this is fine
Location location = projectile.getLocation();
// System.out.println(trail);
switch(trail){
case "none":
return;
case "flame":
location.getWorld().spawnParticle(Particle.FLAME, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
case "sparkle":
location.getWorld().spawnParticle(Particle.END_ROD, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
case "water_drip":
location.getWorld().spawnParticle(Particle.DRIP_WATER, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
case "heart":
location.getWorld().spawnParticle(Particle.HEART, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
case "firework":
location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
case "totem":
location.getWorld().spawnParticle(Particle.TOTEM, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
case "smoke":
location.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
break;
default:
break;
}
}
}.runTaskTimer(plugin, 2, plugin.getConfig().getInt("projectile-trail-period"));
@EventHandler
public void onFishingThrow(PlayerFishEvent e){
if (!(e.getPlayer().getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (!(plugin.getConfig().getBoolean("fishing-rod-trail"))){
return;
}
if (!(e.getState().equals(PlayerFishEvent.State.FISHING))){
return;
}
Player player = e.getPlayer();
String trail = checkCosmeticsDefined(player);
Projectile projectile = e.getHook();
produceTrailOnProjectile(trail, projectile);
}
@EventHandler
@@ -106,6 +65,13 @@ public class ProjectileTrail implements Listener {
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
String trail = checkCosmeticsDefined(player);
Projectile projectile = (Projectile) e.getProjectile();
produceTrailOnProjectile(trail, projectile);
}
public String checkCosmeticsDefined(Player player){
String trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
if(trail == null){
@@ -114,53 +80,45 @@ public class ProjectileTrail implements Listener {
CosmeticsConfig.reload();
trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
}
return trail;
}
// Inspiration from https://github.com/iInvisibilities/spiraltrails/blob/main/SpiralFactory.java
// Not used right now, maybe in the future: this would allow for spirals and such
Projectile arrow = (Projectile) e.getProjectile();
// Not necessarily an arrow, could be a firework
public void produceTrailOnProjectile(String trail, Projectile projectile){
int rotationSpeed = 30;
final double INCREMENT = (2 * Math.PI) / rotationSpeed;
new BukkitRunnable() {
double circlePointOffset = 0;
Location lastLocation = player.getEyeLocation();
@Override
public void run() {
if(arrow.isDead() || arrow.isOnGround()) { // hopefully this is most of em
if(projectile.isDead() || projectile.isOnGround()) {
this.cancel();
return;
}
String trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
Location location = projectile.getLocation();
Location location = arrow.getLocation();
// System.out.println(trail);
switch(trail){
case "none":
return;
case "flame":
location.getWorld().spawnParticle(Particle.FLAME, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.FLAME, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
case "sparkle":
location.getWorld().spawnParticle(Particle.END_ROD, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.END_ROD, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
case "water_drip":
location.getWorld().spawnParticle(Particle.DRIP_WATER, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.DRIP_WATER, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
case "heart":
location.getWorld().spawnParticle(Particle.HEART, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.HEART, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
case "firework":
location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
case "totem":
location.getWorld().spawnParticle(Particle.TOTEM, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.TOTEM, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
case "smoke":
location.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001);
location.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE, location, plugin.getConfig().getInt("projectile-trail-count"), 0.1, 0.1, 0.1, 0.001, null, true);
break;
default:
break;
@@ -169,5 +127,4 @@ public class ProjectileTrail implements Listener {
}.runTaskTimer(plugin, 2, plugin.getConfig().getInt("projectile-trail-period"));
}
}
@@ -1,139 +0,0 @@
package me.lifelessnerd.purekitpvp.createKit;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CreateKit extends Subcommand {
Plugin plugin;
public CreateKit(Plugin plugin) {
this.plugin = plugin;
}
@Override
public String getName() {
return "createkit";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Create a kit from the contents of your inventory";
}
@Override
public String getSyntax() {
return "/purekitpvp createkit <kitName> <displayColor> <kitIcon> <kitPermission> <killItem>";
}
@Override
public boolean perform(Player player, String[] args) {
if (!player.hasPermission("purekitpvp.admin.createkit")){
player.sendMessage(ChatColor.RED + "No permission!");
return true;
}
if (!(args.length >= 4)){
player.sendMessage(ChatColor.RED + "Please provide arguments!");
return false;
}
//Store arguments
KitIcon kitIconLib = new KitIcon();
String kitIcon = "STONE";
String killItem = "AIR";
String kitPermission = "kit.other";
String kitName = args[1].toLowerCase();
kitName = kitName.substring(0, 1).toUpperCase() + kitName.substring(1);
String displayColor = args[2];
if (!(args.length >= 5)){
player.sendMessage("Provide arguments!");
return false;
}
if (Arrays.asList(kitIconLib.materialList).contains(args[3])){
kitIcon = args[3].toUpperCase();
}else {
player.sendMessage(args[3] + " is not a valid option.");
return true;
}
if (!(args[5] == null)){
if (Arrays.asList(kitIconLib.materialList).contains(args[5])){
killItem = args[5].toUpperCase();
}else {
player.sendMessage(args[5] + " is not a valid option.");
return true;
}
} else {
killItem = "AIR";
player.sendMessage("Defaulted to kill item AIR (none). You may change this with /pkpvp setkillitem");
}
if (!(args[4] == null)){
kitPermission = args[4];
} else {
kitPermission = "kit.other";
}
//Storing all contents
ItemStack helmet = player.getInventory().getHelmet();
ItemStack chestplate = player.getInventory().getChestplate();
ItemStack leggings = player.getInventory().getLeggings();
ItemStack boots = player.getInventory().getBoots();
ItemStack[] kitContents = player.getInventory().getContents();
//Create kit in config
KitConfig.get().createSection("kits." + kitName);
KitConfig.get().set("kits." + kitName + ".permission", kitPermission);
KitConfig.get().set("kits." + kitName + ".displayname", displayColor);
KitConfig.get().set("kits." + kitName + ".guiitem", kitIcon);
KitConfig.get().set("kits." + kitName + ".guilore", "");
KitConfig.get().set("kits." + kitName + ".helmet", helmet);
KitConfig.get().set("kits." + kitName + ".chestplate", chestplate);
KitConfig.get().set("kits." + kitName + ".leggings", leggings);
KitConfig.get().set("kits." + kitName + ".boots", boots);
KitConfig.get().set("kits." + kitName + ".contents", kitContents);
//Killitem
Material killItemMat = Material.getMaterial(killItem);
ItemStack killItemStack = new ItemStack(killItemMat);
KitConfig.get().addDefault("kits." + kitName + ".killitem", "GOLDEN_APPLE");
KitConfig.get().set("kits." + kitName + ".killitem", killItemStack);
KitConfig.get().options().copyDefaults(true);
KitConfig.save();
KitConfig.reload();
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
"Kit created with following properties: \nKitName: &a" + kitName +
"&r\n displayColor: &a" + displayColor + "■" + "&r\n kitIcon: &a"
+ kitIcon + "&r\n kitPermission: &a" + kitPermission + "&r\nkillItem: &a" + killItem));
player.sendMessage("You can change these in the kits.yml file, but remember to backup the file when manually editing.");
return true;
}
}
@@ -1,133 +0,0 @@
package me.lifelessnerd.purekitpvp.createKit;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkLib;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
public class SetPerk extends Subcommand {
Plugin plugin;
public SetPerk(Plugin plugin) {
this.plugin = plugin;
}
@Override
public String getName() {
return "setperk";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Set perk values for this kit";
}
@Override
public String getSyntax() {
return "/purekitpvp setperk <kit> <perk> <true/false>";
}
@Override
public boolean perform(Player player, String[] args) {
if (!player.hasPermission("purekitpvp.admin.createkit")){
player.sendMessage(ChatColor.RED + "No permission!");
return true;
}
if (!(args.length >= 2)){
player.sendMessage(ChatColor.RED + "Please provide arguments!");
return false;
}
String kitNameArg = MyStringUtils.camelCaseWord(args[1]);
ArrayList<String> kitNames = new ArrayList<>();
ConfigurationSection kitsSection = KitConfig.get().getConfigurationSection("kits");
// This nesting is painful but it works okay
if (kitNameArg.equalsIgnoreCase("all")){
kitNames.addAll(kitsSection.getKeys(false));
} else {
if (!(KitConfig.get().isSet("kits." + kitNameArg))){
player.sendMessage(ChatColor.GRAY + "That kit does not exist.");
return true;
} else {
kitNames.add(kitNameArg);
}
}
String perkNameArg = args[2].toUpperCase();
PerkLib perkLib = new PerkLib();
ArrayList<String> perkNames = new ArrayList<>();
// This nesting is painful but it works okay
if (perkNameArg.equalsIgnoreCase("all")){
perkNames.addAll(perkLib.perks.keySet());
} else {
if (!(perkLib.perks.containsKey(perkNameArg))){
player.sendMessage(ChatColor.GRAY + "That perk does not exist. Choose from the following:");
for (String key : perkLib.perks.keySet()){
player.sendMessage(ChatColor.GREEN + key);
player.sendMessage(ChatColor.GRAY + perkLib.perks.get(key));
}
return true;
} else {
perkNames.add(perkNameArg);
}
}
String booleanArg = args[3].toLowerCase();
if (!(booleanArg.equalsIgnoreCase("true") || booleanArg.equalsIgnoreCase("false"))){
player.sendMessage(ChatColor.GRAY + "Provide either true or false.");
return true;
}
if (booleanArg.equalsIgnoreCase("true")) {
for(String kitName : kitNames){
for(String perkName : perkNames) {
KitConfig.get().set("kits." + kitName + ".perks." + perkName, true);
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
"&7Perk &e" + perkName + " &7updated to &aTRUE&7 for kit &e" + kitName
));
}
}
} else { // i.e. false
for (String kitName : kitNames) {
for (String perkName : perkNames) {
KitConfig.get().set("kits." + kitName + ".perks." + perkName, null);
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
"&7Perk &e" + perkName + " &7updated to &cFALSE&7 for kit &e" + kitName
));
}
}
}
KitConfig.save();
KitConfig.reload();
return true;
}
}
@@ -1,22 +1,24 @@
package me.lifelessnerd.purekitpvp.customitems;
package me.lifelessnerd.purekitpvp.customItems;
import com.google.common.collect.Lists;
import me.lifelessnerd.purekitpvp.PluginGetter;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Arrays;
@@ -44,16 +46,28 @@ public class GetCustomItem extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
Plugin plugin = PluginGetter.Plugin();
if (args[1].equalsIgnoreCase("golden_head")){
ItemStack goldenHead = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) goldenHead.getItemMeta();
meta.displayName(Component.text("Golden Head").decoration(TextDecoration.ITALIC, false));
String[] loreList = {"Healing Item"};
meta.setLore(Arrays.asList(loreList));
PersistentDataContainer itemContainer = meta.getPersistentDataContainer();
itemContainer.set(new NamespacedKey(plugin, "golden_head"), PersistentDataType.BOOLEAN, true);
// TODO Deprecated lore system
String[] loreList = {"Healing Item"};
meta.setLore(Arrays.asList(loreList));
//
meta.setOwningPlayer(Bukkit.getOfflinePlayer("PhantomTupac"));
// meta.setPlaceableKeys(null); // Block can not be placed on anything no workie
goldenHead.setItemMeta(meta);
player.getInventory().addItem(goldenHead);
@@ -64,14 +78,16 @@ public class GetCustomItem extends Subcommand {
} else if (args[1].equalsIgnoreCase("random_chest")){
if (!(LootTablesConfig.get().isSet(args[2]))){
player.sendMessage("Such loot table does not exist!");
player.sendMessage(Component.text("Such loot table does not exist!"));
return false;
}
String lore = LootTablesConfig.get().getString(args[2] + ".desiredLore");
String displayName = LootTablesConfig.get().getString(args[2] + ".displayName");
ItemStack chestItem = new ItemStack(Material.CHEST);
ItemMeta itemMeta = chestItem.getItemMeta();
itemMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "loottable_id"), PersistentDataType.STRING, args[2]);
List<String> loreList = new ArrayList<>();
loreList.add(ChatColor.translateAlternateColorCodes('&', lore));
itemMeta.setLore(loreList);
@@ -97,7 +113,7 @@ public class GetCustomItem extends Subcommand {
eggMeta.lore(lore);
PersistentDataContainer data = eggMeta.getPersistentDataContainer();
data.set(new NamespacedKey(PluginGetter.Plugin(), "custom_mob_id"), PersistentDataType.STRING, args[2]);
data.set(new NamespacedKey(plugin, "custom_mob_id"), PersistentDataType.STRING, args[2]);
egg.setItemMeta(eggMeta);
player.getInventory().addItem(egg);
@@ -1,22 +1,18 @@
package me.lifelessnerd.purekitpvp.customitems;
package me.lifelessnerd.purekitpvp.customItems;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.awt.*;
import java.util.Objects;
public class GoldenHeadEat implements Listener {
Plugin plugin;
@@ -46,16 +42,15 @@ public class GoldenHeadEat implements Listener {
ItemStack heldItem = player.getInventory().getItemInMainHand();
String desiredLore = "Healing Item";
if (!(heldItem.getItemMeta().hasLore())) {
if (!(heldItem.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "golden_head"), PersistentDataType.BOOLEAN))){
return;
}
if (!(heldItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "golden_head"), PersistentDataType.BOOLEAN))){
return;
}
if (!(heldItem.getItemMeta().getLore().contains(desiredLore))) { //NPE lies? // Also fuck component with their serializers
return;
}
e.setCancelled(true);
heldItem.setAmount(heldItem.getAmount() - 1);
int slot = player.getInventory().getHeldItemSlot();
@@ -64,6 +59,7 @@ public class GoldenHeadEat implements Listener {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 1));
player.getInventory().remove(heldItem);
player.getInventory().setItem(slot, heldItem);
// FIXED
// This is suboptimal, but apparently removing itemstack with amount 1 does not work
// Side effect is change in inventory slot possibly
// FIXED using SLOT
@@ -1,20 +1,20 @@
package me.lifelessnerd.purekitpvp.customitems;
package me.lifelessnerd.purekitpvp.customItems;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
import net.kyori.adventure.text.Component;
import org.bukkit.*;
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.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.util.*;
@@ -51,27 +51,24 @@ public class OpenRandomChest implements Listener {
ItemStack heldItem = player.getInventory().getItemInMainHand();
if (!(heldItem.getItemMeta().hasLore())){
if (!(heldItem.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "loottable_id")))){
return;
}
String itemLore = heldItem.getLore().get(0);
List<String> lootTables = new ArrayList<>(LootTablesConfig.get().getKeys(false));
String currentLootTable = null;
for(String lootName : lootTables){
String lootLore = LootTablesConfig.get().getString(lootName + ".desiredLore");
lootLore = ChatColor.translateAlternateColorCodes('&', lootLore);
if (lootLore.equalsIgnoreCase(itemLore)){
currentLootTable = lootName;
}
}
String currentLootTable = heldItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "loottable_id"), PersistentDataType.STRING);
if (currentLootTable == null){
player.sendMessage("This loottable is not defined.");
plugin.getLogger().warning("Player " + player.getName() + " attempted to open a loottable with lore " + itemLore + ", but no loottable was found!");
player.sendMessage(Component.text("This loottable is not defined."));
plugin.getLogger().warning("Player " + player.getName() + " attempted to open a loottable with name " + currentLootTable + ", but no loottable was found!");
plugin.getLogger().warning("Player " + player.getName() + " current kit is " + PlayerStatsConfig.get().getString(player.getName() + ".current_kit"));
return;
}
// Remove 1 golden head
heldItem.setAmount(heldItem.getAmount() - 1);
int slot = player.getInventory().getHeldItemSlot();
player.getInventory().remove(heldItem);
player.getInventory().setItem(slot, heldItem);
// Giving algorithm
if (LootTablesConfig.get().getBoolean(currentLootTable + ".guaranteed.enabled")){
//Guaranteed items algo
@@ -88,11 +85,10 @@ public class OpenRandomChest implements Listener {
ItemStack itemToGive = (ItemStack) LootTablesConfig.get().get(currentLootTable + ".content." + contentKeys.get(0) + ".item");
player.getInventory().addItem(itemToGive);
itemsFilled++;
if (LootTablesConfig.get().getDouble(currentLootTable + ".content." + contentKeys.get(0) + ".chance") <= 0.01){
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
"&bLUCKY! &a" + MyStringUtils.itemCamelCase(itemToGive.getType().toString()) + "&bhad a chance of &a" +
LootTablesConfig.get().getDouble(currentLootTable + ".content." + contentKeys.get(0) + ".chance") * 100
+ "%!"));
if (LootTablesConfig.get().getDouble(currentLootTable + ".content." + contentKeys.get(0) + ".chance") <= (double) plugin.getConfig().getInt("loottable-message-percentage") / 100){
player.sendMessage(LanguageConfig.lang.get("LOOT_LUCKY").replaceText(
ComponentUtils.replaceConfig("%ITEM%",MyStringUtils.itemCamelCase(itemToGive.getType().toString()))).replaceText(
ComponentUtils.replaceConfig("%CHANCE%", String.valueOf(LootTablesConfig.get().getDouble(currentLootTable + ".content." + contentKeys.get(0) + ".chance") * 100))));
}
}
}
@@ -107,10 +103,10 @@ public class OpenRandomChest implements Listener {
//Succes, get the item
ItemStack itemToGive = (ItemStack) LootTablesConfig.get().get(currentLootTable + ".content." + key + ".item");
player.getInventory().addItem(itemToGive);
if (LootTablesConfig.get().getDouble(currentLootTable + ".content." + key + ".chance") <= 0.01){
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
"&bLUCKY! &a" + MyStringUtils.itemCamelCase(itemToGive.getType().toString()) + "&bhad a chance of&a " +
LootTablesConfig.get().getDouble(currentLootTable + ".content." + key + ".chance") * 100 + "%!"));
if (LootTablesConfig.get().getDouble(currentLootTable + ".content." + key + ".chance") <= (double) plugin.getConfig().getInt("loottable-message-percentage") / 100){
player.sendMessage(LanguageConfig.lang.get("LOOT_LUCKY").replaceText(
ComponentUtils.replaceConfig("%ITEM%",MyStringUtils.itemCamelCase(itemToGive.getType().toString()))).replaceText(
ComponentUtils.replaceConfig("%CHANCE%", String.valueOf(LootTablesConfig.get().getDouble(currentLootTable + ".content." + contentKeys.get(0) + ".chance") * 100))));
}
}
}
@@ -119,19 +115,6 @@ public class OpenRandomChest implements Listener {
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_BELL, 1, 1);
if (heldItem.getAmount() > 1){
int itemsAdded = 0;
int desiredAmount = heldItem.getAmount() - 1;
while(itemsAdded < desiredAmount){
ItemStack heldItemSingle = heldItem;
heldItemSingle.setAmount(1);
player.getInventory().addItem(heldItemSingle);
itemsAdded++;
}
}
LootTablesConfig.save();
LootTablesConfig.reload();
}
@@ -1,28 +1,20 @@
package me.lifelessnerd.purekitpvp.customitems.loottablelogic;
package me.lifelessnerd.purekitpvp.customItems.loottable;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.createKit.KitIcon;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CreateLootTable extends Subcommand {
Plugin plugin;
@@ -52,33 +44,37 @@ public class CreateLootTable extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
if (!(player.hasPermission("purekitpvp.admin.createloottable"))) {
player.sendMessage("No permission!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_NO_PERMISSION"));
return true;
}
if (!(args.length >= 4)){
player.sendMessage("Provide arguments!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_LACK_OF_ARGS"));
return false;
}
String name = args[1];
String desiredLore = args[2];
String displayName = args[3];
Block targetBlock = player.getTargetBlock(10);
if (targetBlock == null){
player.sendMessage("Please look at a chest!");
}
if(!(targetBlock.getType() == Material.CHEST)){
player.sendMessage("Please look at a chest!");
return true;
}
Block targetBlock = player.getTargetBlock(null, 10);
if (!(targetBlock.getState() instanceof Chest targetChest)){
player.sendMessage("Please look at a chest!");
return true;
Inventory chestInventory;
if (targetBlock.getState() instanceof Chest targetChest){
chestInventory = targetChest.getBlockInventory();
} else {
chestInventory = player.getInventory();
player.sendMessage(Component.text("Inventory contents used for loottable creation.", NamedTextColor.GRAY));
}
FileConfiguration lootTables = LootTablesConfig.get();
@@ -90,8 +86,6 @@ public class CreateLootTable extends Subcommand {
lootTables.set(name + ".guaranteed.items", 3);
ConfigurationSection itemContent = lootTables.createSection(name + ".content");
Inventory chestInventory = targetChest.getBlockInventory();
int index = 0;
for (ItemStack item : chestInventory.getContents()){
if (item == null){
@@ -103,10 +97,10 @@ public class CreateLootTable extends Subcommand {
}
}
player.sendMessage(
"Loot table created. \nTo specify chances per item, and add multi-word lore" +
" please use the loottables.yml config!");
player.sendMessage("When manually editing loottables.yml, remember to back it up if it contains a lot of information.");
player.sendMessage(Component.text("Loot table created. \nTo specify chances per item, and add multi-word lore" +
" please use the loottables.yml config!"));
player.sendMessage(Component.text("When manually editing loottables.yml, remember to back it up if it " +
"contains a lot of information."));
LootTablesConfig.save();
LootTablesConfig.reload();
@@ -1,89 +0,0 @@
//package me.lifelessnerd.purekitpvp.customitems.commands;
//
//import me.lifelessnerd.purekitpvp.Subcommand;
//import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
//import org.bukkit.ChatColor;
//import org.bukkit.command.Command;
//import org.bukkit.command.CommandSender;
//import org.bukkit.command.TabExecutor;
//import org.bukkit.entity.Player;
//import org.bukkit.plugin.Plugin;
//import org.jetbrains.annotations.NotNull;
//import org.jetbrains.annotations.Nullable;
//
//import java.util.ArrayList;
//import java.util.List;
//
//public class CommandManager implements TabExecutor {
// ArrayList<Subcommand> subcommands = new ArrayList<>();
// Plugin plugin;
// public CommandManager(Plugin plugin){
// subcommands.add(new GetGoldenHead());
// subcommands.add(new GetRandomChest());
// this.plugin = plugin;
// }
//
// @Override
// public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
//
// if (!(sender instanceof Player)){
// sender.sendMessage("The console cannot perform these commands.");
// return false;
// }
// Player player = (Player) sender;
//
// if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
// player.sendMessage("You may not do that in this world!");
// return true;
// }
// if(!(player.hasPermission("purekitpvp.admin.getitem"))){
// player.sendMessage(ChatColor.RED + "You do not have permission!");
// return true;
// }
//
// if (args.length < 1){
// player.sendMessage("Please specify what function to use.");
// return false;
// }
//
// //Check for names of subcommands in arg
// for (int i = 0; i < getSubcommands().size(); i++){
// if (args[0].equalsIgnoreCase(getSubcommands().get(i).getName())){
// boolean result = getSubcommands().get(i).perform(player, args);
// return true; // All help dialogs are done in-class with player.sendMessage
// }
// }
//
//
// player.sendMessage(args[0] + " is not a valid sub-command.");
// return false;
//
// }
//
// public ArrayList<Subcommand> getSubcommands(){
// return subcommands;
// }
//
// @Override
// public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
//
// if(args.length == 1) {
// List<String> arguments = new ArrayList<>();
// arguments.add("createkit");
// arguments.add("deletekit");
// arguments.add("kitstats");
// arguments.add("setkillitem");
// arguments.add("getcustomitem");
// arguments.add("createloottable");
// arguments.add("help");
// arguments.add("reload");
// return arguments;
// }
//
// if (args[0].equalsIgnoreCase("random_chest")){
// List<String> arguments = new ArrayList<>(LootTablesConfig.get().getKeys(false));
// return arguments;
// }
// return null;
// }
//}
@@ -1,49 +0,0 @@
package me.lifelessnerd.purekitpvp.customitems.commands;
import me.lifelessnerd.purekitpvp.Subcommand;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import java.util.Arrays;
public class GetGoldenHead extends Subcommand {
@Override
public String getName() {
return "golden_head";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Put the golden head special item in your inventory to use in kits.";
}
@Override
public String getSyntax() {
return "/getitem golden_head";
}
@Override
public boolean perform(Player player, String[] args) {
// System.out.println("dab");
// ItemStack goldenHead = new ItemStack(Material.PLAYER_HEAD);
// SkullMeta meta = (SkullMeta) goldenHead.getItemMeta();
// meta.displayName(Component.text("Golden Head"));
// String[] loreList = {"Healing Item"};
// meta.setLore(Arrays.asList(loreList));
// meta.setOwningPlayer(Bukkit.getOfflinePlayer("PhantomTupac"));
// goldenHead.setItemMeta(meta);
//
// player.getInventory().addItem(goldenHead);
return true;
}
}
@@ -1,58 +0,0 @@
package me.lifelessnerd.purekitpvp.customitems.commands;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
public class GetRandomChest extends Subcommand {
@Override
public String getName() {
return "random_chest";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Get the random chest with a user-input loot table";
}
@Override
public String getSyntax() {
return "/getitem random_chest <loottablename>";
}
@Override
public boolean perform(Player player, String[] args) {
if (!(LootTablesConfig.get().isSet(args[1]))){
player.sendMessage("Such loot table does not exist!");
return false;
}
String lore = LootTablesConfig.get().getString(args[1] + ".desiredLore");
String displayName = LootTablesConfig.get().getString(args[1] + ".displayName");
ItemStack chestItem = new ItemStack(Material.CHEST);
ItemMeta itemMeta = chestItem.getItemMeta();
List<String> loreList = new ArrayList<>();
loreList.add(ChatColor.translateAlternateColorCodes('&', lore));
itemMeta.setLore(loreList);
itemMeta.displayName(Component.text(ChatColor.translateAlternateColorCodes('&',displayName)));
// itemMeta.setCustomModelData(1);
chestItem.setItemMeta(itemMeta);
player.getInventory().addItem(chestItem);
return true;
}
}
@@ -1,11 +1,14 @@
package me.lifelessnerd.purekitpvp.custommobs;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -33,14 +36,20 @@ public class CustomMobCommand extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
if (args.length <= 1){
player.sendMessage("Please provide arguments!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_LACK_OF_ARGS"));
return true;
}
if (args[1].equalsIgnoreCase("create")){
if (args.length <= 3){
player.sendMessage("Please provide arguments!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_LACK_OF_ARGS"));
return true;
}
//String customMobName = args[2];
@@ -64,7 +73,7 @@ public class CustomMobCommand extends Subcommand {
}
if (args[1].equalsIgnoreCase("set")){
if (args.length <= 3){
player.sendMessage("Please provide arguments!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_LACK_OF_ARGS"));
player.sendMessage("Usage: /purekitpvp custommob set <helmet/chestplate/leggings/boots/mainhand/offhand>");
return true;
}
@@ -97,13 +106,14 @@ public class CustomMobCommand extends Subcommand {
if (args[1].equalsIgnoreCase("delete")){
MobSpawnConfig.get().set(args[2], null);
player.sendMessage("Custom mob " + args[2] + " deleted.");
player.sendMessage(Component.text("Custom mob " + args[2] + " deleted."));
MobSpawnConfig.save();
MobSpawnConfig.reload();
return true;
}
else {
player.sendMessage("Invalid argument!");
TextReplacementConfig config = ComponentUtils.replaceConfig("%ARG%",args[1]);
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_WRONG_ARGS.toString()).replaceText(config));
}
return true;
@@ -0,0 +1,73 @@
package me.lifelessnerd.purekitpvp.database;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import me.lifelessnerd.purekitpvp.database.entities.PlayerKitPreferences;
import org.bukkit.entity.Player;
import java.sql.SQLException;
import java.util.HashMap;
public class KitDatabase {
private final Dao<PlayerKitPreferences, String> playerKitPreferencesDao;
public KitDatabase(String path) throws SQLException {
ConnectionSource connectionSource = new JdbcConnectionSource("jdbc:sqlite:" + path);
TableUtils.createTableIfNotExists(connectionSource, PlayerKitPreferences.class);
playerKitPreferencesDao = DaoManager.createDao(connectionSource, PlayerKitPreferences.class);
}
public void addEntry(Player player, String kitName, HashMap<Integer, Integer> prefs) throws SQLException {
if (hasEntry(player, kitName)){
updateEntry(player, kitName, prefs);
return;
}
PlayerKitPreferences playerKitPreferences = new PlayerKitPreferences();
playerKitPreferences.setUuid(player.getUniqueId().toString());
playerKitPreferences.setUsername(player.getName());
playerKitPreferences.setKitName(kitName);
playerKitPreferences.setPreferences(prefs);
playerKitPreferencesDao.create(playerKitPreferences);
}
public boolean hasEntry(Player player, String kitName) throws SQLException {
// Query for a user with the specified uuid and kitName
QueryBuilder<PlayerKitPreferences, ?> queryBuilder = playerKitPreferencesDao.queryBuilder();
queryBuilder.where().eq("uuid", player.getUniqueId().toString()).and().eq("kitName", kitName);
// Check if any records match the criteria
return queryBuilder.queryForFirst() != null;
}
public void updateEntry(Player player, String kitName, HashMap<Integer, Integer> prefs) throws SQLException {
QueryBuilder<PlayerKitPreferences, ?> queryBuilder = playerKitPreferencesDao.queryBuilder();
queryBuilder.where().eq("uuid", player.getUniqueId().toString()).and().eq("kitName", kitName);
PlayerKitPreferences playerKitPreferences = queryBuilder.queryForFirst();
if (playerKitPreferences != null) {
playerKitPreferences.setPreferences(prefs);
playerKitPreferencesDao.update(playerKitPreferences);
} else {
addEntry(player, kitName, prefs);
}
}
public PlayerKitPreferences getEntry(Player player, String kitName) throws SQLException {
if (!hasEntry(player, kitName)){
HashMap<Integer, Integer> emptyMap = new HashMap<>();
addEntry(player, kitName, emptyMap);
}
// Query for a user with the specified uuid and kitName
QueryBuilder<PlayerKitPreferences, ?> queryBuilder = playerKitPreferencesDao.queryBuilder();
queryBuilder.where().eq("uuid", player.getUniqueId().toString()).and().eq("kitName", kitName);
// Check if any records match the criteria
return queryBuilder.queryForFirst();
}
}
@@ -0,0 +1,57 @@
package me.lifelessnerd.purekitpvp.database.entities;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import java.util.HashMap;
@DatabaseTable(tableName = "player_kit_preferences")
public class PlayerKitPreferences {
@DatabaseField(generatedId = true, canBeNull = false)
private int id;
@DatabaseField(canBeNull = false)
private String uuid;
@DatabaseField(canBeNull = false)
private String username;
@DatabaseField(canBeNull = false)
private String kitName;
@DatabaseField(dataType = DataType.SERIALIZABLE)
private HashMap<Integer, Integer> preferences;
public PlayerKitPreferences() {
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getKitName() {
return kitName;
}
public void setKitName(String kitName) {
this.kitName = kitName;
}
public HashMap<Integer, Integer> getPreferences() {
return preferences;
}
public void setPreferences(HashMap<Integer, Integer> preferences) {
this.preferences = preferences;
}
}
@@ -0,0 +1,230 @@
package me.lifelessnerd.purekitpvp.files.lang;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.SortedMap;
import java.util.TreeMap;
public class LanguageConfig {
private static File file;
private static FileConfiguration customFile;
public static HashMap<String, Component> lang;
public static SortedMap<LanguageKey, Object> defaults;
public static void setup(){
defaults = new TreeMap<>();
lang = new HashMap<>();
file = new File(Bukkit.getServer().getPluginManager().getPlugin("PureKitPvP").getDataFolder(), "lang.yml");
if (!(file.exists())){
try{
file.createNewFile();
} catch (IOException e){
//pain
}
}
customFile = YamlConfiguration.loadConfiguration(file);
// Language defaults
defaults.put(LanguageKey.GENERIC_NO_PERMISSION, "&cYou do not have permission!");
defaults.put(LanguageKey.GENERIC_LACK_OF_ARGS, "&cNot enough arguments!");
defaults.put(LanguageKey.GENERIC_WRONG_ARGS, "%ARG% &cis not a valid argument!");
defaults.put(LanguageKey.GENERIC_WRONG_WORLD, "&cYou can only use this menu in &7%WORLD%");
defaults.put(LanguageKey.GENERIC_PLAYER_HELP, """
&bPureKitPvP - Help Menu
&a/kit &r- &eOpen up the kit menu
&a/getkit <kit> &r- &eGet a kit directly
&a/suicide &r- &eCommit suicide (if enabled)
&a/stats <player> &r- &eGet PVP stats of a player
&a/perks &r- &eSelect perks
&bFor admin commands, see &a/pkpvp help 2&b!
""");
defaults.put(LanguageKey.GENERIC_FEATURE_DISABLED, "&cThis feature is disabled.");
defaults.put(LanguageKey.PERKS_ALREADY_SELECTED, "&cYou can only change perks when you have no kit selected!");
defaults.put(LanguageKey.PERKS_GUI_TITLE, "&6Perks Menu");
defaults.put(LanguageKey.PERKS_GUI_INFO_TITLE, "&cPerks Info");
defaults.put(LanguageKey.PERKS_GUI_INFO_LORE, """
&aYou can equip a total of &e5 &aperks total.
&7Click on a perk slot to choose a perk for that slot.
&7It will replace any perk currently in that slot.
&7Perks are abilities that are always active.
&7Duplicate perks do not stack.
""");
defaults.put(LanguageKey.PERKS_GUI_BACK_KITS, "&aBack to Kits");
defaults.put(LanguageKey.PERKS_GUI_SLOT_TITLE, "&cPerk Slot %SLOT%");
defaults.put(LanguageKey.PERKS_GUI_SLOT_LORE, "&aClick to select a perk for this slot!");
defaults.put(LanguageKey.PERKS_GUI_BACK, "&aGo Back");
defaults.put(LanguageKey.PERKS_PERK_JUGGERNAUT, """
&rGain regeneration 1 (5s) after every kill
""");
defaults.put(LanguageKey.PERKS_PERK_BULLDOZER, """
&rGain strength 2 (3s) after every kill
""");
defaults.put(LanguageKey.PERKS_PERK_KNOWLEDGE, """
&rGain 1 XP level on kill
""");
defaults.put(LanguageKey.PERKS_PERK_NOTORIETY, """
&rChance of gaining a sharpness level on each kill
&rChance is 100 - (25 * Sharpness Level) percent
""");
defaults.put(LanguageKey.PERKS_PERK_NOTORIETY_MAX, "&eYou have reached the maximum Notoriety!");
defaults.put(LanguageKey.PERKS_PERK_NOTORIETY_UPGRADE, "&eYour sharpness level has increased (chance of %CHANCE%%)!");
defaults.put(LanguageKey.PERKS_PERK_ENDERMAGIC, """
&r30% chance of gaining an ender pearl on kill
""");
defaults.put(LanguageKey.PERKS_PERK_ENDERMAGIC_OCCUR, "&eYou gained an ender pearl!");
defaults.put(LanguageKey.PERKS_PERK_SPEEDSTER, """
&rGain 10 seconds of speed 2 after every kill
""");
defaults.put(LanguageKey.PERKS_PERK_ROBBERY, """
&r30% chance of disarming someone if hit with your fist
&rThe weapon will be swapped with a slot in the inventory
""");
defaults.put(LanguageKey.PERKS_PERK_ROBBERY_DISARMED,"&eYou were disarmed by %PLAYER%'s Robbery perk!");
defaults.put(LanguageKey.PERKS_PERK_ROBBERY_DISARMER,"&eYou disarmed %PLAYER% with your Robbery perk!");
defaults.put(LanguageKey.PERKS_PERK_SNOWMAN, """
&rGive slowness 1 (3s) when you hit someone with a snowball
""");
defaults.put(LanguageKey.PERKS_PERK_DISRUPTOR, """
&rGive poison 1 (5s) when you hit someone with an egg
""");
defaults.put(LanguageKey.PERKS_PERK_ENDERMAN, """
&rYou can now ride ender pearls; they do no damage
""");
defaults.put(LanguageKey.PERKS_PERK_VAMPIRE, """
&rOn critical hits, gain 50% of the damage
&ryou dealt, as instant health
""");
defaults.put(LanguageKey.PERKS_PERK_MARKSMAN, """
&rChance of 100 - (25 * Power level) percent to
&radd power to the item held, if it's a bow
""");
defaults.put(LanguageKey.PERKS_PERK_MARKSMAN_UPGRADE,"&eYour power level has increased (chance of %CHANCE%%)!");
defaults.put(LanguageKey.PERKS_PERK_MARKSMAN_MAX,"&eYou have reached the maximum power level!");
defaults.put(LanguageKey.PERKS_PERK_APOLLO, """
&rYou get each arrow you hit on a player back
&rA kill nets one extra arrow of that type
""");
defaults.put(LanguageKey.PERKS_PERK_ADRENALINE, """
&rWhen below 6 HP (3 hearts), you get a speed boost
""");
defaults.put(LanguageKey.KITS_GUI_TITLE, "Kits");
defaults.put(LanguageKey.KITS_GUI_PREV, "Previous Page");
defaults.put(LanguageKey.KITS_GUI_NEXT, "Next Page");
defaults.put(LanguageKey.KITS_ALREADY_SELECTED, "&cYou already have a kit!");
defaults.put(LanguageKey.KITS_DOES_NOT_EXIST, "&cThat kit does not exist!");
defaults.put(LanguageKey.KITS_PERMISSION_NOT_DEFINED, "&cThat kit does not have a permission associated. Please report this to your administrator.");
defaults.put(LanguageKey.KITS_KIT_GIVEN, "&aKit &6%KIT% &agiven.");
defaults.put(LanguageKey.KITS_NO_KITS, "&cThere are no kits... yet. Create some with /pkpvp createkit");
defaults.put(LanguageKey.KITS_GUI_NO_PERMISSION, "&cYou don't have permission!");
defaults.put(LanguageKey.KITS_GUI_PREVIEW, "&bRIGHT CLICK to preview!");
defaults.put(LanguageKey.KITS_GUI_WEAPONS, "&3Weapons:");
defaults.put(LanguageKey.KITS_GUI_ITEMS, "&3Items:");
defaults.put(LanguageKey.KITS_GUI_ARMOR, "&3Armor:");
defaults.put(LanguageKey.KITS_GUI_NO_ARMOR, "&3No Armor");
defaults.put(LanguageKey.KITS_GUI_OFFHAND, "&3Offhand:");
defaults.put(LanguageKey.KITS_GUI_KILL_ITEM, "&fItem on Kill:");
defaults.put(LanguageKey.KITS_GUI_NO_KILL_ITEM, "&fNo Item on Kill");
defaults.put(LanguageKey.KITS_GUI_RESET, "&fReset Kit");
defaults.put(LanguageKey.KITS_GUI_RESET_LORE, """
&9If you do not have permission to reset your kit,
&9this will run /suicide on your behalf.
""");
defaults.put(LanguageKey.KITS_GUI_PERKS, "&rPerks menu");
defaults.put(LanguageKey.KITS_GUI_PERKS_LORE, """
&9Click here to change your perks!
""");
defaults.put(LanguageKey.KITS_RESET_KIT, "&aKit has been reset.");
defaults.put(LanguageKey.KITS_GUI_PREVIEW_TITLE, "&aKit Preview > &b%KIT%");
defaults.put(LanguageKey.KITS_GUI_PREVIEW_TEXT, "&aRight click to preview.");
defaults.put(LanguageKey.KITS_GUI_PREVIEW_STATS, "&6Global Stats");
defaults.put(LanguageKey.KITS_GUI_PREVIEW_PREFS, "&6Customize layout");
defaults.put(LanguageKey.KITS_GUI_PREFS_TITLE, "&6Customizing > &b%KIT%");
defaults.put(LanguageKey.KITS_GUI_PREFS_SAVE, "&6Save custom layout");
defaults.put(LanguageKey.KITS_GUI_PREFS_INFO, "&7The slot above resembles the off-hand.");
defaults.put(LanguageKey.KITS_GUI_PREFS_SAVED, "&6Custom layout saved!");
defaults.put(LanguageKey.KITS_GUI_PREFS_BACK, "&6Back to kit preview");
defaults.put(LanguageKey.KITS_GUI_PREFS_RESET, "&cReset your layout");
defaults.put(LanguageKey.KITS_GUI_PREVIEW_SELECT, "&aSelect Kit");
defaults.put(LanguageKey.KITS_GUI_PREVIEW_BACK, "&aBack to Kits");
defaults.put(LanguageKey.KITS_GUI_EDIT_SAVE, "&aSave Kit");
defaults.put(LanguageKey.KITS_GUI_EDIT_SAVED, "&aKit updated.");
defaults.put(LanguageKey.LOOT_LUCKY, "&bLUCKY! &a%ITEM%had a chance of &a%CHANCE%%!");
defaults.put(LanguageKey.EVENTS_END, "&7The event has ended.");
defaults.put(LanguageKey.EVENTS_START, "&bRANDOM EVENT! &d%EVENT% &bhas been selected!");
defaults.put(LanguageKey.EVENTS_TELEMADNESS_DESC, "Everyone gets Ender Pearls, all the time!");
defaults.put(LanguageKey.EVENTS_TELEMADNESS_ITEM_LORE, """
&7This is an event specific item, which
&7will be removed as soon as the event ends.
""");
defaults.put(LanguageKey.EVENTS_PICKUP_DESC, "Killed players drop their stuff!");
defaults.put(LanguageKey.EVENTS_JUGGERNAUT_DESC, "Team up to kill the Juggernaut!");
defaults.put(LanguageKey.EVENTS_DOUBLE_DESC, "All player health is doubled!");
defaults.put(LanguageKey.SCOREBOARD_MAIN_TITLE, "&6PureKitPvP");
defaults.put(LanguageKey.SCOREBOARD_PERSONAL_TITLE, "&6Personal Stats");
defaults.put(LanguageKey.SCOREBOARD_PERSONAL_KILLSTREAK, " &7Killstreak: &b%VALUE%");
defaults.put(LanguageKey.SCOREBOARD_PERSONAL_KILLS, " &7Kills: &b%VALUE%");
defaults.put(LanguageKey.SCOREBOARD_PERSONAL_DEATHS, " &7Deaths: &b%VALUE%");
defaults.put(LanguageKey.SCOREBOARD_PERSONAL_KD, " &7K/D Ratio: &b%VALUE%");
defaults.put(LanguageKey.SCOREBOARD_PERSONAL_LEVEL, " &7Level: &b%VALUE%");
defaults.put(LanguageKey.SCOREBOARD_GLOBAL_TITLE, "&6Global Stats");
defaults.put(LanguageKey.SCOREBOARD_GLOBAL_KILLSTREAK, " &dKillstreak");
defaults.put(LanguageKey.SCOREBOARD_GLOBAL_KILLS, " &dKills");
defaults.put(LanguageKey.SCOREBOARD_GLOBAL_KD, " &dK/D Ratio");
defaults.put(LanguageKey.SCOREBOARD_GLOBAL_LEVEL, "&dLevel");
defaults.put(LanguageKey.STATS_NO_STATS, "That player has no stats attached to them!");
defaults.put(LanguageKey.STATS_TITLE, "%PLAYER% &bStatistics");
defaults.put(LanguageKey.STATS_LEVEL_UP, "&6You leveled up to LEVEL %VALUE%!");
defaults.put(LanguageKey.COMBAT_YOU_DIED, "&c&lYou died!");
defaults.put(LanguageKey.COMBAT_DEATH_RECAP, "&7Death Recap");
defaults.put(LanguageKey.COMBAT_DEATH_CAUSE, "&7- &e%CAUSE% &7did &a%VALUE%%");
SortedMap<String, Object> defaultsString = new TreeMap<>();
for (LanguageKey key : defaults.keySet()){
defaultsString.put(key.toString(), defaults.get(key));
}
customFile.addDefaults(defaultsString);
}
public static FileConfiguration get(){
return customFile;
}
public static void save(){
try{
customFile.save(file);
} catch (IOException e){
System.out.println("Cannot save!");
}
}
public static void reload(){
customFile = YamlConfiguration.loadConfiguration(file);
}
public static void loadLanguage(){
// Take data out of file; store it in map
LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand();
for (String key : get().getKeys(false)) {
lang.put(key, serializer.deserialize(get().getString(key)).decoration(TextDecoration.ITALIC, false));
// System.out.println(key + ": " + get().getString(key));
}
}
}
@@ -0,0 +1,105 @@
package me.lifelessnerd.purekitpvp.files.lang;
public enum LanguageKey {
GENERIC_NO_PERMISSION,
GENERIC_LACK_OF_ARGS,
GENERIC_WRONG_ARGS,
GENERIC_WRONG_WORLD,
GENERIC_PLAYER_HELP,
GENERIC_FEATURE_DISABLED,
PERKS_ALREADY_SELECTED,
PERKS_GUI_TITLE,
PERKS_GUI_INFO_TITLE,
PERKS_GUI_INFO_LORE,
PERKS_GUI_BACK_KITS,
PERKS_GUI_SLOT_TITLE,
PERKS_GUI_SLOT_LORE,
PERKS_GUI_BACK,
PERKS_PERK_JUGGERNAUT,
PERKS_PERK_BULLDOZER,
PERKS_PERK_KNOWLEDGE,
PERKS_PERK_NOTORIETY,
PERKS_PERK_NOTORIETY_MAX,
PERKS_PERK_NOTORIETY_UPGRADE,
PERKS_PERK_ENDERMAGIC,
PERKS_PERK_ENDERMAGIC_OCCUR,
PERKS_PERK_SPEEDSTER,
PERKS_PERK_ROBBERY,
PERKS_PERK_ROBBERY_DISARMED,
PERKS_PERK_ROBBERY_DISARMER,
PERKS_PERK_SNOWMAN,
PERKS_PERK_DISRUPTOR,
PERKS_PERK_ENDERMAN,
PERKS_PERK_VAMPIRE,
PERKS_PERK_MARKSMAN,
PERKS_PERK_MARKSMAN_UPGRADE,
PERKS_PERK_MARKSMAN_MAX,
PERKS_PERK_APOLLO,
PERKS_PERK_ADRENALINE,
KITS_GUI_TITLE,
KITS_GUI_PREV,
KITS_GUI_NEXT,
KITS_ALREADY_SELECTED,
KITS_DOES_NOT_EXIST,
KITS_PERMISSION_NOT_DEFINED,
KITS_KIT_GIVEN,
KITS_NO_KITS,
KITS_GUI_NO_PERMISSION,
KITS_GUI_PREVIEW,
KITS_GUI_WEAPONS,
KITS_GUI_ITEMS,
KITS_GUI_ARMOR,
KITS_GUI_NO_ARMOR,
KITS_GUI_OFFHAND,
KITS_GUI_KILL_ITEM,
KITS_GUI_NO_KILL_ITEM,
KITS_GUI_RESET,
KITS_GUI_RESET_LORE,
KITS_GUI_PERKS,
KITS_GUI_PERKS_LORE,
KITS_RESET_KIT,
KITS_GUI_PREVIEW_TITLE,
KITS_GUI_PREVIEW_TEXT,
KITS_GUI_PREVIEW_STATS,
KITS_GUI_PREVIEW_PREFS,
KITS_GUI_PREFS_TITLE,
KITS_GUI_PREFS_SAVE,
KITS_GUI_PREFS_SAVED,
KITS_GUI_PREFS_BACK,
KITS_GUI_PREFS_INFO,
KITS_GUI_PREFS_RESET,
KITS_GUI_PREVIEW_SELECT,
KITS_GUI_PREVIEW_BACK,
KITS_GUI_EDIT_SAVE,
KITS_GUI_EDIT_SAVED,
LOOT_LUCKY,
EVENTS_END,
EVENTS_START,
EVENTS_TELEMADNESS_DESC,
EVENTS_TELEMADNESS_ITEM_LORE,
EVENTS_PICKUP_DESC,
EVENTS_JUGGERNAUT_DESC,
EVENTS_DOUBLE_DESC,
SCOREBOARD_MAIN_TITLE,
SCOREBOARD_PERSONAL_TITLE,
SCOREBOARD_PERSONAL_KILLSTREAK,
SCOREBOARD_PERSONAL_KILLS,
SCOREBOARD_PERSONAL_DEATHS,
SCOREBOARD_PERSONAL_KD,
SCOREBOARD_PERSONAL_LEVEL,
SCOREBOARD_GLOBAL_TITLE,
SCOREBOARD_GLOBAL_KILLSTREAK,
SCOREBOARD_GLOBAL_KILLS,
SCOREBOARD_GLOBAL_KD,
SCOREBOARD_GLOBAL_LEVEL,
STATS_NO_STATS,
STATS_TITLE,
COMBAT_YOU_DIED,
COMBAT_DEATH_RECAP,
COMBAT_DEATH_CAUSE,
STATS_LEVEL_UP,
;
}
@@ -0,0 +1,79 @@
package me.lifelessnerd.purekitpvp.globalevents;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
public class EventCommand extends Subcommand {
Plugin plugin;
GlobalEventManager gem;
public EventCommand(Plugin plugin, GlobalEventManager gem) {
this.plugin = plugin;
this.gem = gem;
}
@Override
public String getName() {
return "event";
}
@Override
public String[] getAliases() {
return new String[0];
}
@Override
public String getDescription() {
return "Start and stop events";
}
@Override
public String getSyntax() {
return "/purekitpvp event <start/stop/pause> <eventName>";
}
@Override
public boolean getConsoleExecutable() {
return true;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
if (!(args.length >= 2)) {
sender.sendMessage(Component.text("Please provide arguments!").color(NamedTextColor.RED));
return false;
}
if (!(plugin.getConfig().getBoolean("global-event-loop"))){
sender.sendMessage(Component.text("Global event loop is disabled in config.").color(NamedTextColor.RED));
return false;
}
if (args[1].equalsIgnoreCase("start")) {
if (!(args.length >= 3)) {
sender.sendMessage(Component.text("Please provide an event to start!").color(NamedTextColor.RED));
return false;
}
String eventName = args[2];
Component success = gem.startEvent(eventName);
sender.sendMessage(success);
} else if (args[1].equalsIgnoreCase("stop")) {
// Do stuff
Component success = gem.stopEvent();
sender.sendMessage(success);
} else if (args[1].equalsIgnoreCase("pause")) {
sender.sendMessage(gem.pauseResumeTimer());
} else {
sender.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_ARGS").replaceText(ComponentUtils.replaceConfig("%ARG%", args[0])));
}
return false;
}
}
@@ -0,0 +1,12 @@
package me.lifelessnerd.purekitpvp.globalevents;
public class EventDataClass {
public static boolean dropInventoryOnDeath = false;
public static boolean juggernautRunning = false;
public static String juggernaut = "";
public static boolean doubleHealth = false;
}
@@ -0,0 +1,179 @@
package me.lifelessnerd.purekitpvp.globalevents;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.globalevents.events.AbstractEvent;
import me.lifelessnerd.purekitpvp.globalevents.events.DoubleHealthEvent;
import me.lifelessnerd.purekitpvp.globalevents.events.PickupFrenzyEvent;
import me.lifelessnerd.purekitpvp.globalevents.events.TeleMadnessEvent;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.concurrent.ThreadLocalRandom;
import java.util.ArrayList;
import java.util.List;
public class GlobalEventManager {
AbstractEvent currentEvent = null;
int globalTimer = 0;
public BukkitTask timerRunnable;
int nextEventTime = 0;
int period = 0;
public List<AbstractEvent> enabledByConfig;
public List<AbstractEvent> allEvents;
public boolean paused;
public Plugin plugin;
public GlobalEventManager(Plugin plugin) {
this.plugin = plugin;
this.allEvents = new ArrayList<>();
allEvents.add(new PickupFrenzyEvent(plugin));
allEvents.add(new TeleMadnessEvent(plugin));
allEvents.add(new DoubleHealthEvent(plugin));
enabledByConfig = new ArrayList<>();
for (AbstractEvent event : this.allEvents) {
for (String inConfig : plugin.getConfig().getStringList("global-events-enabled")) {
if (event.getEventName().equalsIgnoreCase(inConfig)) {
enabledByConfig.add(event);
}
}
}
if (!(plugin.getConfig().getBoolean("global-event-loop"))) {
return;
}
// System.out.println("Global Combat Event loop enabled, starting!");
paused = false;
// Global timer (1 second increments)
timerRunnable = new BukkitRunnable() {
@Override
public void run() {
int amount = 0;
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world"))) {
amount++;
}
if (amount >= 1) {
globalTimer++;
// System.out.println(1 + " - " + globalTimer);
}
}
}
}.runTaskTimer(plugin, 0, 20);
period = plugin.getConfig().getInt("global-event-period");
// TODO somewhere in here is a bug: first event after reload is 1 sec too long
nextEventTime = globalTimer + period;
// Runnable that starts new events, if nextEventTime is passed
new BukkitRunnable() {
@Override
public void run() {
if (!(globalTimer >= nextEventTime)) {
// Still in cooldown period (or event is running)
return;
}
// No event running - cooldown period over!
AbstractEvent randomEvent = enabledByConfig.get(ThreadLocalRandom.current().nextInt(0, enabledByConfig.size()));
// System.out.println(randomEvent.getEventName());
startEvent(randomEvent.getEventName().replace(' ', '_'));
}
}.runTaskTimer(plugin, 0, 20);
}
public Component startEvent(String name) {
if (this.currentEvent != null) {
if (this.currentEvent.running) { // Event already running?
return Component.text("An event is already/still running!").color(NamedTextColor.RED);
}
}
for (AbstractEvent event : this.allEvents) {
String eventId = event.getEventName().replace(' ', '_');
if (eventId.equalsIgnoreCase(name)) {
event.onStart();
this.currentEvent = event;
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world"))) {
onlinePlayer.sendMessage(LanguageConfig.lang.get("EVENTS_START").
replaceText(ComponentUtils.replaceConfig("%EVENT%", this.currentEvent.getEventName())).
appendNewline().append(Component.text(this.currentEvent.getEventLength() + "s" + " - ").
append(this.currentEvent.getEventDescription())
));
}
}
this.nextEventTime = this.globalTimer + this.currentEvent.getEventLength() + this.period;
// System.out.println(this.nextEventTime + " Now: " + this.globalTimer);
// This means the nextEventTime is eventTime + cooldown period after current time
}
}
return Component.text("Started event.").color(NamedTextColor.GREEN);
}
public Component stopEvent() {
if (this.currentEvent == null) {
return Component.text("No event is running.").color(NamedTextColor.RED);
}
if (!this.currentEvent.running) {
return Component.text("No event is running.").color(NamedTextColor.RED);
}
AbstractEvent currentEvent = this.currentEvent;
// Fast forward globalTimer to time event would have stopped
this.globalTimer = this.globalTimer + (currentEvent.getEventLength() - currentEvent.timer);
// Force end event
currentEvent.timer = currentEvent.getEventLength();
this.currentEvent = null;
return Component.text("Stopping current event and continuing the global event loop...").color(NamedTextColor.GREEN);
}
public Component pauseResumeTimer() {
// if (currentEvent == null){
// return Component.text("There is no event running, you may not pause now!").color(NamedTextColor.RED);
// // TODO temp fix; this should be possible but for some reason NPES everywhere if we dont do this also double events?
// }
if (paused) {
if (currentEvent != null) currentEvent.pauseResumePasser(true);
paused = false;
// Global timer (1 second increments)
timerRunnable = new BukkitRunnable() {
@Override
public void run() {
int amount = 0;
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world"))) {
amount++;
}
if (amount >= 1) {
globalTimer++;
// System.out.println(2 + " - " + globalTimer);
}
}
}
}.runTaskTimer(plugin, 0, 20);
return Component.text("Global event loop resumed.").color(NamedTextColor.GREEN);
} else {
if (currentEvent != null) currentEvent.pauseResumePasser(false);
paused = true;
timerRunnable.cancel();
return Component.text("Global event loop paused.").color(NamedTextColor.GREEN);
}
}
}
@@ -0,0 +1,93 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
public abstract class AbstractEvent {
public Plugin plugin;
public int timer;
public int taskId;
public boolean running;
public int eventLength;
public BukkitTask runnable;
public AbstractEvent(Plugin plugin) {
this.plugin = plugin;
this.timer = 0;
this.taskId = 0;
this.running = false;
this.eventLength = 30; // default -> can be overwritten in class
}
public abstract String getEventName();
public abstract Component getEventDescription();
public int getEventLength() {
return this.eventLength;
}
public abstract void onStart();
/**
* Calling this method with a BukkitTask ensures the Task is cancelled after the event ends
*/
public void startEndListener(BukkitTask eventLoop) {
this.runnable = new BukkitRunnable() {
@Override
public void run() {
if (timer >= getEventLength()) {
this.cancel();
if (eventLoop != null) {
eventLoop.cancel();
}
timer = 0;
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world"))) {
onlinePlayer.sendMessage(LanguageConfig.lang.get("EVENTS_END"));
}
}
onEnd();
}
timer++;
}
}.runTaskTimer(plugin, 0, 20);
}
public abstract void pauseResumePasser(boolean paused);
public void pauseResumeAbstractEvent(boolean paused, BukkitTask eventLoop) {
if (paused) {
this.runnable = new BukkitRunnable() {
@Override
public void run() {
if (timer >= getEventLength()) {
this.cancel();
if (eventLoop != null) {
eventLoop.cancel();
}
timer = 0;
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world"))) {
onlinePlayer.sendMessage(LanguageConfig.lang.get("EVENTS_END"));
}
}
onEnd();
}
timer++;
}
}.runTaskTimer(plugin, 0, 20);
} else {
runnable.cancel();
}
}
public abstract void onEnd();
}
@@ -0,0 +1,64 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.globalevents.EventDataClass;
import me.lifelessnerd.purekitpvp.utils.PlayerUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
import java.util.Set;
public class DoubleHealthEvent extends AbstractEvent{
BukkitTask eventLoop;
public DoubleHealthEvent(Plugin plugin) {
super(plugin);
this.eventLength = plugin.getConfig().getInt("double-health-length");
}
@Override
public String getEventName() {
return "Double Health";
}
@Override
public Component getEventDescription() {
return LanguageConfig.lang.get(LanguageKey.EVENTS_DOUBLE_DESC.toString());
}
@Override
public void onStart() {
this.running = true;
EventDataClass.doubleHealth = true;
Set<Player> players = PlayerUtils.getPlayersInWorld(plugin.getConfig().getString("world"));
for (Player player : players){
AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH);
attribute.setBaseValue(40.0D);
player.setHealth(40.0D);
}
startEndListener(null);
}
@Override
public void pauseResumePasser(boolean paused) {
pauseResumeAbstractEvent(paused, eventLoop);
}
@Override
public void onEnd() {
EventDataClass.doubleHealth = false;
Set<Player> players = PlayerUtils.getPlayersInWorld(plugin.getConfig().getString("world"));
for (Player player : players){
AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH);
attribute.setBaseValue(20.0D);
player.setHealth(20.0D);
}
this.running = false;
}
}
@@ -0,0 +1,62 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.globalevents.EventDataClass;
import org.bukkit.World;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
public class DoubleHealthListeners implements Listener {
Plugin plugin;
public DoubleHealthListeners(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onJoin(PlayerJoinEvent e){
Player player = e.getPlayer();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
if (EventDataClass.doubleHealth){
AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH);
attribute.setBaseValue(40.0D);
player.setHealth(40.0D);
// xTODO and set HP to be max instantly DO THIS EVERYWHERE THINK I DID
}
}
@EventHandler
public void onQuit(PlayerQuitEvent e){
Player player = e.getPlayer();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
if (EventDataClass.doubleHealth){
AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH);
attribute.setBaseValue(20.0D);
}
}
@EventHandler
public void onWorldChange(PlayerChangedWorldEvent e){
Player player = e.getPlayer();
World fromWorld = e.getFrom();
if (fromWorld.getName().equals(plugin.getConfig().getString("world"))){
return;
}
if (EventDataClass.doubleHealth){
AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH);
attribute.setBaseValue(20.0D);
}
}
}
@@ -0,0 +1,68 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.PluginGetter;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.globalevents.EventDataClass;
import me.lifelessnerd.purekitpvp.utils.PlayerUtils;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.NotImplementedException;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Random;
import java.util.Set;
public class JuggernautEvent extends AbstractEvent {
public JuggernautEvent(Plugin plugin) {
super(plugin);
this.eventLength = plugin.getConfig().getInt("juggernaut-length");
}
@Override
public String getEventName() {
return "Juggernaut";
}
@Override
public Component getEventDescription() {
return LanguageConfig.lang.get("EVENTS_JUGGERNAUT_DESC");
}
@Override
public void onStart() {
this.running = true;
startEndListener(null);
EventDataClass.juggernautRunning = true;
// Pick a juggernaut
Player nextJuggernaut = null;
Set<Player> players = PlayerUtils.getPlayersInWorld(PluginGetter.Plugin().getConfig().getString("world"));
if(players.size() < 2) return;
//https://stackoverflow.com/questions/124671/picking-a-random-element-from-a-set
int size = players.size();
int item = new Random().nextInt(size); // In real life, the Random object should be rather more shared than this
int i = 0;
for(Player player : players)
{
if (i == item)
nextJuggernaut = player;
i++;
}
EventDataClass.juggernaut = nextJuggernaut.getName();
// Give him strength according to nr. of opponents
// TODO For every opponent + 30% strength, +30% resistance
int opponentsAmount = players.size() - 1;
}
@Override
public void pauseResumePasser(boolean paused) {
pauseResumeAbstractEvent(paused, null);
}
@Override
public void onEnd() {
// TODO reset everything
throw new NotImplementedException();
}
}
@@ -0,0 +1,20 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.globalevents.EventDataClass;
import org.bukkit.entity.Player;
public class JuggernautListeners {
public static void onDeath(Player killed, Player killer){
if(!EventDataClass.juggernautRunning){
return;
}
if (!(killed.getName().equalsIgnoreCase(EventDataClass.juggernaut))){
return;
}
// Juggernaut has been killed!
}
}
@@ -0,0 +1,41 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.globalevents.EventDataClass;
import net.kyori.adventure.text.Component;
import org.bukkit.plugin.Plugin;
public class PickupFrenzyEvent extends AbstractEvent {
public PickupFrenzyEvent(Plugin plugin) {
super(plugin);
this.eventLength = plugin.getConfig().getInt("pickup-frenzy-length");
}
@Override
public String getEventName() {
return "Pickup Frenzy";
}
@Override
public Component getEventDescription() {
return LanguageConfig.lang.get("EVENTS_PICKUP_DESC");
}
@Override
public void onStart() {
this.running = true;
EventDataClass.dropInventoryOnDeath = true;
startEndListener(null);
}
@Override
public void pauseResumePasser(boolean paused) {
pauseResumeAbstractEvent(paused, null);
}
@Override
public void onEnd() {
this.running = false;
EventDataClass.dropInventoryOnDeath = false;
}
}
@@ -0,0 +1,98 @@
package me.lifelessnerd.purekitpvp.globalevents.events;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.List;
public class TeleMadnessEvent extends AbstractEvent {
BukkitTask eventLoop;
public TeleMadnessEvent(Plugin plugin) {
super(plugin);
this.eventLength = plugin.getConfig().getInt("telemadness-length");
}
@Override
public String getEventName() {
return "TeleMadness";
}
@Override
public Component getEventDescription() {
return LanguageConfig.lang.get("EVENTS_TELEMADNESS_DESC");
}
@Override
public void onStart() {
this.running = true;
eventLoop = new BukkitRunnable() {
@Override
public void run() {
taskId = this.getTaskId();
giveEnderpearls();
}
}.runTaskTimer(plugin, 0, 20);
startEndListener(eventLoop);
}
@Override
public void pauseResumePasser(boolean paused) {
pauseResumeAbstractEvent(paused, eventLoop);
}
@Override
public void onEnd() {
this.running = false;
World pvpWorld = Bukkit.getWorld(plugin.getConfig().getString("world"));
List<Player> players = pvpWorld.getPlayers();
if (players.isEmpty()) {
return;
}
ItemStack pearl = new ItemStack(Material.ENDER_PEARL);
ItemMeta pearlMeta = pearl.getItemMeta();
pearlMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "telemadness"), PersistentDataType.BOOLEAN, true);
pearlMeta.lore(ComponentUtils.splitComponent(LanguageConfig.lang.get("EVENTS_TELEMADNESS_ITEM_LORE")));
pearlMeta.displayName(Component.text("TeleMadness Pearl").color(NamedTextColor.LIGHT_PURPLE));
pearl.setItemMeta(pearlMeta);
pearl.setAmount(99999999); // will do
for (Player player : players) {
player.getInventory().removeItemAnySlot(pearl);
}
}
public void giveEnderpearls() {
World pvpWorld = Bukkit.getWorld(plugin.getConfig().getString("world"));
List<Player> players = pvpWorld.getPlayers();
if (players.isEmpty()) {
return;
}
for (Player player : players) {
ItemStack pearl = new ItemStack(Material.ENDER_PEARL);
ItemMeta pearlMeta = pearl.getItemMeta();
pearlMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "telemadness"), PersistentDataType.BOOLEAN, true);
pearlMeta.lore(ComponentUtils.splitComponent(LanguageConfig.lang.get("EVENTS_TELEMADNESS_ITEM_LORE")));
pearlMeta.displayName(Component.text("TeleMadness Pearl").color(NamedTextColor.LIGHT_PURPLE));
pearl.setItemMeta(pearlMeta);
pearl.setAmount(1);
player.getInventory().addItem(pearl);
}
}
}
@@ -1,30 +1,18 @@
package me.lifelessnerd.purekitpvp.kitCommand;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkLib;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import net.kyori.adventure.text.Component;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Item;
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.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class GUIListener implements Listener {
@@ -46,55 +34,61 @@ public class GUIListener implements Listener {
InventoryView inv = e.getView();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
TextComponent desiredInvTitle = (TextComponent) LanguageConfig.lang.get("KITS_GUI_TITLE");
if (inv.title().toString().contains((desiredInvTitle.content()))) { //I hate component
if (inv.title().toString().contains("Kits")) { //I hate component
if(clickedItem == null){
return;
}
e.setCancelled(true);
// kit icons branch
if (e.getRawSlot() < 45){
e.setCancelled(true);
if(clickedItem == null){
String displayName = serializer.serialize(clickedItem.getItemMeta().displayName());
// Preview kit button
if (e.getClick() == ClickType.RIGHT){
KitPreviewInventory kitPreviewInventory = new KitPreviewInventory(54,
LanguageConfig.lang.get("KITS_GUI_PREVIEW_TITLE").replaceText(ComponentUtils.replaceConfig("%KIT%", displayName)),
plugin,
displayName, player);
kitPreviewInventory.openInventory(player);
return;
}
String displayName = clickedItem.getItemMeta().getDisplayName();
displayName = ChatColor.stripColor(displayName);
player.chat("/getkit " + displayName);
player.closeInventory();
}
else if (e.getRawSlot() == 53){ // Reset button
e.setCancelled(true);
if (player.hasPermission("purekitpvp.admin.resetkit")){
player.chat("/purekitpvp resetkit");
}
else {
player.chat("/suicide");
}
// options at the bottom branch
int rawSlot = e.getRawSlot();
} else if (e.getRawSlot() == 49){ // Perk help button
e.setCancelled(true);
switch(rawSlot){
case 53: // reset button
if (player.hasPermission("purekitpvp.admin.resetkit")){
player.chat("/purekitpvp resetkit");
}
else {
player.chat("/suicide");
}
break;
player.chat("/perks");
case 49: // Perk help button
player.chat("/perks");
break;
} else if (e.getRawSlot() == 48){ // Prev page button
if (e.getCurrentItem().equals(new ItemStack(Material.AIR))){
return;
}
e.setCancelled(true);
String title = serializer.serialize(e.getView().title());
int prevPage = Integer.parseInt(title.split(" - ")[1]) - 1;
player.chat("/kit " + prevPage);
} else if (e.getRawSlot() == 50){ // Next page button
if (e.getCurrentItem().equals(new ItemStack(Material.AIR))){
return;
}
e.setCancelled(true);
String title = serializer.serialize(e.getView().title());
int nextPage = Integer.parseInt(title.split(" - ")[1]) + 1;
player.chat("/kit " + nextPage);
case 48: // Prev page button
String title = serializer.serialize(e.getView().title());
int prevPage = Integer.parseInt(title.split(" - ")[1]) - 1;
player.chat("/kit " + prevPage);
break;
case 50: // Next page button
String title2 = serializer.serialize(e.getView().title());
int nextPage = Integer.parseInt(title2.split(" - ")[1]) + 1;
player.chat("/kit " + nextPage);
break;
}
}
}
}
@@ -1,9 +1,13 @@
package me.lifelessnerd.purekitpvp.kitCommand;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import me.lifelessnerd.purekitpvp.database.KitDatabase;
import me.lifelessnerd.purekitpvp.database.entities.PlayerKitPreferences;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.KitStatsConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import org.bukkit.ChatColor;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -19,8 +23,11 @@ import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GetKit implements TabExecutor, Listener {
Plugin plugin;
@@ -53,63 +60,68 @@ public class GetKit implements TabExecutor, Listener {
String kitNameArg = args[0].substring(0, 1).toUpperCase() + args[0].substring(1);
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
player.sendMessage("You cannot use that command in this world!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_WORLD").
replaceText(ComponentUtils.replaceConfig("%WORLD%",plugin.getConfig().getString("world"))));
return true;
}
if (hasKit.contains(player.getName())){
player.sendMessage(ChatColor.GRAY + "You already have a kit!");
player.sendMessage(LanguageConfig.lang.get("KITS_ALREADY_SELECTED"));
return true;
}
if (args.length != 1) {
player.sendMessage(ChatColor.RED + "Incorrect arguments!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_ARGS"));
return false;
}
if (!(KitConfig.get().isSet("kits." + kitNameArg))){
player.sendMessage(ChatColor.GRAY + "That kit does not exist.");
player.sendMessage(LanguageConfig.lang.get("KITS_DOES_NOT_EXIST"));
return true;
}
if(!KitConfig.get().isSet("kits." + kitNameArg + ".permission")){
player.sendMessage(ChatColor.GRAY + "That kit does not have a permission associated. Please report this to your administrator.");
player.sendMessage(LanguageConfig.lang.get("KITS_PERMISSION_NOT_DEFINED"));
return true;
}
if (!(player.hasPermission(KitConfig.get().getString("kits." + kitNameArg + ".permission")))){ //IDEA lies
player.sendMessage(ChatColor.GRAY + "You do not have permission!");
player.sendMessage(LanguageConfig.lang.get("GENERIC_NO_PERMISSION"));
return true;
}
//Okay, if all checks are passed, player may get the kit
player.sendMessage(ChatColor.GRAY + "Kit " + ChatColor.BLUE + kitNameArg + ChatColor.GRAY + " given.");
player.sendMessage(LanguageConfig.lang.get("KITS_KIT_GIVEN").replaceText(ComponentUtils.replaceConfig("%KIT%", kitNameArg)));
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitItems = (List<ItemStack>) fileConfiguration.get("kits." + kitNameArg + ".contents");
//Remove any potion effects that make PvP unfair
//Remove any active potion effects that make PvP unfair
for (PotionEffect effect : player.getActivePotionEffects())
player.removePotionEffect(effect.getType());
Map<Integer, Integer> playerPrefs = new HashMap<>();
PureKitPvP pureKitPvP = (PureKitPvP) plugin;
KitDatabase db = pureKitPvP.getKitDatabase();
try {
if(db.hasEntry(player, kitNameArg)){
PlayerKitPreferences playerKitPreferences = db.getEntry(player, kitNameArg);
playerPrefs = playerKitPreferences.getPreferences();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
//Give items
for (int index = 0; index < kitItems.size(); index++) {
ItemStack item = kitItems.get(index);
if (item == null) {
item = new ItemStack(Material.AIR);
}
// This code is from PureKits, idk why it works (.setHelmet is called for every armor piece?)
player.getInventory().setItem(index, item);
ItemStack helmet = fileConfiguration.getItemStack("kits." + kitNameArg + ".helmet");
player.getInventory().setHelmet(helmet);
ItemStack chestplate = fileConfiguration.getItemStack("kits." + kitNameArg + ".helmet");
player.getInventory().setHelmet(chestplate);
ItemStack leggings = fileConfiguration.getItemStack("kits." + kitNameArg + ".helmet");
player.getInventory().setHelmet(leggings);
ItemStack boots = fileConfiguration.getItemStack("kits." + kitNameArg + ".helmet");
player.getInventory().setHelmet(boots);
player.getInventory().setItem(playerPrefs.getOrDefault(index, index), item);
}
hasKit.add(player.getName());
//Add current kit to config
@@ -0,0 +1,194 @@
package me.lifelessnerd.purekitpvp.kitCommand;
import me.lifelessnerd.purekitpvp.AbstractInventory;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import me.lifelessnerd.purekitpvp.database.KitDatabase;
import me.lifelessnerd.purekitpvp.database.entities.PlayerKitPreferences;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.kitadmin.NamespacedKeys;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class KitPreferencesInventory extends AbstractInventory {
String kitName;
Player player;
Component title;
KitDatabase db;
public KitPreferencesInventory(int size, Component title, Plugin plugin, String kitName, Player toBeShownPlayer) {
super(size, title, plugin);
this.kitName = kitName;
this.title = title;
this.player = toBeShownPlayer;
PureKitPvP pureKitPvP = (PureKitPvP) this.plugin;
db = pureKitPvP.getKitDatabase();
initializeItems();
}
@Override
public void initializeItems() {
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitItems = (List<ItemStack>) fileConfiguration.get("kits." + kitName + ".contents");
Map<Integer, Integer> playerPrefs = new HashMap<>();
try {
if(db.hasEntry(player, kitName)){
PlayerKitPreferences playerKitPreferences = db.getEntry(player, kitName);
playerPrefs = playerKitPreferences.getPreferences();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
for (int index = 0; index < kitItems.size(); index++) {
ItemStack item = kitItems.get(index);
if (item == null) continue;
ItemMeta meta = item.getItemMeta();
// Sets defaults indices as PDC - only after this we shift stuff around
meta.getPersistentDataContainer().set(NamespacedKeys.prefsIndexInstance, PersistentDataType.INTEGER, index);
item.setItemMeta(meta);
inv.setItem(playerPrefs.getOrDefault(index, index), item);
}
ItemStack redStainedGlass = new ItemStack(Material.RED_STAINED_GLASS_PANE, 1);
ItemMeta glassMeta = redStainedGlass.getItemMeta();
glassMeta.displayName(Component.text(""));
redStainedGlass.setItemMeta(glassMeta);
for (int i = 41; i < 54; i++) inv.setItem(i, redStainedGlass);
ItemStack barrier = new ItemStack(Material.BARRIER, 1);
ItemMeta resetMeta = barrier.getItemMeta();
resetMeta.displayName(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_RESET.toString()));
barrier.setItemMeta(resetMeta);
inv.setItem(50, barrier);
ItemStack greenConcrete = new ItemStack(Material.GREEN_CONCRETE, 1);
ItemMeta saveMeta = greenConcrete.getItemMeta();
saveMeta.displayName(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_SAVE.toString()));
ArrayList<Component> lore = new ArrayList<>();
lore.add(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_INFO.toString()));
saveMeta.lore(lore);
greenConcrete.setItemMeta(saveMeta);
inv.setItem(49, greenConcrete);
ItemStack arrow = new ItemStack(Material.ARROW, 1);
ItemMeta backMeta = arrow.getItemMeta();
backMeta.displayName(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_BACK.toString()));
arrow.setItemMeta(backMeta);
inv.setItem(48, arrow);
}
@Override
public void onInventoryClickLogic(InventoryClickEvent e) {
if (e.getSlot() < 41){
e.setCancelled(false);
return;
}
if (e.getSlot() >= 41) { // red panes
e.setCancelled(true);
}
if (e.getSlot() == 50){ // reset layout
try {
if(db.hasEntry(player, kitName)){
db.updateEntry(player, kitName, new HashMap<>());
inv.close();
KitPreferencesInventory kitPreferencesInventory = new KitPreferencesInventory(54, title, plugin, kitName, player);
kitPreferencesInventory.openInventory(player);
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
if (e.getSlot() == 48){ // back button
KitPreviewInventory kitPreviewInventory = new KitPreviewInventory(54,
LanguageConfig.lang.get("KITS_GUI_PREVIEW_TITLE").replaceText(ComponentUtils.replaceConfig("%KIT%", kitName)),
plugin,
kitName, player);
kitPreviewInventory.openInventory(player);
return;
}
if (e.getSlot() == 49) { // save icon
HashMap<Integer, Integer> newPrefs = new HashMap<>();
// See changes in inventory
int index = 0;
for (ItemStack item : inv.getContents()){
if (index >= 41) break;
if (item == null) {
index++;
continue;
}
ItemMeta itemMeta = item.getItemMeta();
int oldIndex = itemMeta.getPersistentDataContainer().get(new NamespacedKey(plugin, "KITS_GUI_PREFS_INDEX"), PersistentDataType.INTEGER);
if (oldIndex != index){ // Change is different from standard!
// System.out.println("change! item that was on " + oldIndex + " now on " + index);
newPrefs.put(oldIndex, index);
}
index++;
}
// Update db pref value
try {
db.updateEntry(player, kitName, newPrefs);
} catch(Exception ex){
throw new RuntimeException(ex);
}
player.sendMessage(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_SAVED.toString()));
return;
}
e.setCancelled(true); // ensures no listeners are fighting
}
@EventHandler
public void onInventoryMove(InventoryClickEvent e){
if (!e.getView().getTopInventory().equals(inv)) return;
if (!e.getView().getBottomInventory().getType().equals(InventoryType.PLAYER)) return;
if (e.getRawSlot() >= 54)
e.setCancelled(true);
// I hate this - BUG PRONE (am i missing an InventoryAction - if so > report immediately)
// if (e.getAction() != InventoryAction.PICKUP_ALL || e.getAction() != InventoryAction.DROP_ALL_SLOT)
// e.setCancelled(true);
if(e.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY)
e.setCancelled(true);
if(e.getAction() == InventoryAction.HOTBAR_SWAP)
e.setCancelled(true);
if(e.getClickedInventory() != e.getView().getTopInventory())
e.setCancelled(true);
}
@EventHandler
// Should prevent issue https://www.spigotmc.org/threads/cancelling-inventoryclickevent-being-inconsistent.631817/
public void onInventoryDrag(InventoryDragEvent e){
if (!e.getView().getTopInventory().equals(inv)) return;
if (!e.getView().getBottomInventory().getType().equals(InventoryType.PLAYER)) return;
for (int slot : e.getRawSlots()){
if (slot >= 54){
e.setCancelled(true);
}
}
}
}
@@ -0,0 +1,148 @@
package me.lifelessnerd.purekitpvp.kitCommand;
import me.lifelessnerd.purekitpvp.AbstractInventory;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import me.lifelessnerd.purekitpvp.database.KitDatabase;
import me.lifelessnerd.purekitpvp.database.entities.PlayerKitPreferences;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.KitStatsConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class KitPreviewInventory extends AbstractInventory {
public String kitName;
KitDatabase db;
Player player;
public KitPreviewInventory(int size, Component title, Plugin plugin, String kitName, Player playerToBeShown) {
super(size, title, plugin);
this.kitName = kitName;
this.player = playerToBeShown;
PureKitPvP pureKitPvP = (PureKitPvP) this.plugin;
db = pureKitPvP.getKitDatabase();
initializeItems();
}
@Override
public void initializeItems() {
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitItems = (List<ItemStack>) fileConfiguration.get("kits." + kitName + ".contents");
Map<Integer, Integer> playerPrefs = new HashMap<>();
try {
if(db.hasEntry(player, kitName)){
PlayerKitPreferences playerKitPreferences = db.getEntry(player, kitName);
playerPrefs = playerKitPreferences.getPreferences();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
for (int index = 0; index < kitItems.size(); index++) {
ItemStack item = kitItems.get(index);
if (item == null) continue;
inv.setItem(playerPrefs.getOrDefault(index, index), item);
}
ItemStack redStainedGlass = new ItemStack(Material.RED_STAINED_GLASS_PANE, 1);
ItemMeta glassMeta = redStainedGlass.getItemMeta();
glassMeta.displayName(Component.text(""));
redStainedGlass.setItemMeta(glassMeta);
inv.setItem(45, redStainedGlass);
inv.setItem(46, redStainedGlass);
inv.setItem(52, redStainedGlass);
inv.setItem(53, redStainedGlass);
ItemStack selectItem = new ItemStack(Material.GREEN_CONCRETE, 1);
ItemMeta selectMeta = selectItem.getItemMeta();
selectMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREVIEW_SELECT"));
selectMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Select");
selectMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM_KIT"), PersistentDataType.STRING, kitName);
selectItem.setItemMeta(selectMeta);
inv.setItem(50, selectItem);
ItemStack paper = new ItemStack(Material.PAPER, 1);
ItemMeta paperMeta = paper.getItemMeta();
paperMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREVIEW_STATS"));
paperMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Stats");
ArrayList<Component> lore2 = new ArrayList<>();
int kitChosen = KitStatsConfig.get().getInt(kitName);
lore2.add(Component.text("Times Chosen: ", NamedTextColor.AQUA).append(Component.text(kitChosen, NamedTextColor.GREEN)).decoration(TextDecoration.ITALIC, false));
paperMeta.lore(lore2);
paper.setItemMeta(paperMeta);
inv.setItem(51, paper);
ItemStack anvil = new ItemStack(Material.ANVIL, 1);
ItemMeta anvilMeta = anvil.getItemMeta();
anvilMeta.displayName(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREVIEW_PREFS.toString()));
anvilMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Edit");
anvilMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM_KIT"), PersistentDataType.STRING, kitName);
anvil.setItemMeta(anvilMeta);
inv.setItem(49, anvil);
ItemStack backItem = new ItemStack(Material.ARROW, 1);
ItemMeta backMeta = selectItem.getItemMeta();
backMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREVIEW_BACK"));
backMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Back");
backItem.setItemMeta(backMeta);
inv.setItem(48, backItem);
}
@Override
public void onInventoryClickLogic(InventoryClickEvent e) {
e.setCancelled(true);
ItemStack clickedItem = e.getCurrentItem();
Player player = (Player) e.getWhoClicked();
InventoryView inv = e.getView();
String kitName;
if (clickedItem.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"))){
String pdcValue = clickedItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING);
switch(pdcValue){
case "Select":
kitName = clickedItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM_KIT"), PersistentDataType.STRING);
player.chat("/getkit " + kitName);
player.closeInventory();
break;
case "Stats":
//Can be used later?
break;
case "Back":
player.chat("/kit");
break;
case "Edit":
kitName = clickedItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM_KIT"), PersistentDataType.STRING);
KitPreferencesInventory kitPreferencesInventory = new KitPreferencesInventory(54,
LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_TITLE.toString()).
replaceText(ComponentUtils.replaceConfig("%KIT%", kitName)).
decoration(TextDecoration.ITALIC, false),
plugin, kitName, player);
kitPreferencesInventory.openInventory(player);
break;
default:
break;
}
}
}
}
@@ -1,28 +0,0 @@
package me.lifelessnerd.purekitpvp.kitCommand;
import me.lifelessnerd.purekitpvp.files.KitStatsConfig;
import org.bukkit.configuration.file.FileConfiguration;
public class KitStats {
public static void updateValue(String kitName){
FileConfiguration kitStats = KitStatsConfig.get();
if (!(kitStats.isSet(kitName))){
kitStats.set(kitName, 1);
return;
}
int value = kitStats.getInt(kitName);
int newValue = value + 1;
kitStats.set(kitName, newValue);
KitStatsConfig.reload();
KitStatsConfig.save();
}
}
@@ -2,18 +2,19 @@ package me.lifelessnerd.purekitpvp.kitCommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
@@ -25,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.bukkit.util.NumberConversions.floor;
@@ -41,30 +41,33 @@ public class KitsGUI implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player)){
if (!(sender instanceof Player player)){
return false;
}
Player player = (Player) sender;
if (!KitConfig.get().isSet("kits.")) {
player.sendMessage(ChatColor.GRAY + "There aren't any kits yet!");
player.sendMessage(LanguageConfig.lang.get("KITS_NO_KITS"));
return true;
}
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
player.sendMessage(ChatColor.RED + "You can only use this menu in " + ChatColor.GRAY + plugin.getConfig().getString("world"));
player.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_WORLD").
replaceText(ComponentUtils.replaceConfig("%WORLD%",plugin.getConfig().getString("world"))));
return true;
}
// Only argument is used for page, the plugin will run /kits 2 at some point for the second page of kits
int currentPage = 1;
if (args.length >= 1) {
currentPage = Integer.parseInt(args[0]);
try {
if (args.length >= 1) {
currentPage = Integer.parseInt(args[0]);
}
} catch (Exception e){
player.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_ARGS").replaceText(ComponentUtils.replaceConfig("%ARG%", args[0])));
}
//Create inventory GUI
TextComponent inventoryTitle = Component.text("Kits - ").
color(TextColor.color(255, 150, 20)).
append(Component.text(currentPage));
Component inventoryTitle = LanguageConfig.lang.get("KITS_GUI_TITLE").appendSpace().append(Component.text(currentPage));
Inventory kits = Bukkit.createInventory(null, 54, inventoryTitle);
int amountOfKits = KitConfig.get().getConfigurationSection("kits").getKeys(false).size();
int lastPage = floor(((double) amountOfKits / 46)) + 1;
@@ -73,32 +76,18 @@ public class KitsGUI implements TabExecutor {
// Create next page item
ItemStack nextPageButton = new ItemStack(Material.ARROW);
ItemMeta nextPageButtonMeta = nextPageButton.getItemMeta();
nextPageButtonMeta.displayName(Component.text("Next").decoration(TextDecoration.ITALIC, false));
List<Component> loreList = new ArrayList<>();
TextComponent txt = Component.text("Go to the next kit selection page.").
decoration(TextDecoration.ITALIC, false).
color(TextColor.color(100,100,100));
loreList.add(txt);
nextPageButtonMeta.lore(loreList);
nextPageButtonMeta.displayName(LanguageConfig.lang.get("KITS_GUI_NEXT"));
nextPageButton.setItemMeta(nextPageButtonMeta);
kits.setItem(50, nextPageButton);
loreList.clear();
}
if (currentPage > 1){
// If this, we need a prev button too
ItemStack prevPageButton = new ItemStack(Material.ARROW);
ItemMeta prevPageButtonMeta = prevPageButton.getItemMeta();
prevPageButtonMeta.displayName(Component.text("Previous").decoration(TextDecoration.ITALIC, false));
List<Component> loreList = new ArrayList<>();
TextComponent txt = Component.text("Go to the previous kit selection page.").
decoration(TextDecoration.ITALIC, false).
color(TextColor.color(100,100,100));
loreList.add(txt);
prevPageButtonMeta.lore(loreList);
prevPageButtonMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREV"));
prevPageButton.setItemMeta(prevPageButtonMeta);
kits.setItem(48, prevPageButton);
loreList.clear();
}
int kitNumber = 1;
@@ -116,42 +105,44 @@ public class KitsGUI implements TabExecutor {
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
//Set gui item
// Set gui item
itemStack.setType(Material.getMaterial(KitConfig.get().getString("kits." + key + ".guiitem")));
LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand();
//Set lore
String loreText = KitConfig.get().getString("kits." + key + ".guilore");
loreText = ChatColor.translateAlternateColorCodes('&', loreText);
ArrayList<String> lore = new ArrayList<>();
// Set lore
ArrayList<Component> lore = new ArrayList<>();
// Quip lore at the top
Component loreText = serializer.deserialize(KitConfig.get().getString("kits." + key + ".guilore"));
lore.add(loreText);
// If no permission: set gui item to red stained glass pane and a bit of lore is added to explain the situation
if (!(player.hasPermission(KitConfig.get().getString("kits." + key + ".permission")))){
itemStack.setType(Material.RED_STAINED_GLASS_PANE);
lore.add(ChatColor.translateAlternateColorCodes('&', "&4&lNo permission for this kit!"));
lore.add(LanguageConfig.lang.get("KITS_GUI_NO_PERMISSION"));
}
// Item lore that consists of contents of kit
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitContent = (List<ItemStack>) fileConfiguration.get("kits." + key + ".contents");
lore.add(ChatColor.BLUE + "Weapons:");
lore.add(LanguageConfig.lang.get("KITS_GUI_WEAPONS"));
for (int index = 0; index < kitContent.size(); index++) {
ItemStack item = kitContent.get(index);
switch (index) {
case 3 -> lore.add(ChatColor.BLUE + "Items:");
case 3 -> lore.add(LanguageConfig.lang.get("KITS_GUI_ITEMS")); //TODO change 3 value to user-config?
case 36 -> {
if(kitContent.get(36) != null | kitContent.get(37) != null | kitContent.get(38) != null | kitContent.get(39) != null) {
lore.add(ChatColor.BLUE + "Armor:");
lore.add(LanguageConfig.lang.get("KITS_GUI_ARMOR"));
} else {
lore.add(ChatColor.BLUE + "No Armor");
lore.add(LanguageConfig.lang.get("KITS_GUI_NO_ARMOR"));
}
}
case 40 -> {
if (item != null){
lore.add(ChatColor.BLUE + "Offhand:");
lore.add(LanguageConfig.lang.get("KITS_GUI_OFFHAND"));
}
}
}
@@ -167,32 +158,38 @@ public class KitsGUI implements TabExecutor {
} else if (item.getType().toString().equalsIgnoreCase("SPLASH_POTION")){
//Do stuff with potions
String amount = String.valueOf(item.getAmount());
lore.add(ChatColor.GRAY + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase(item.getType().toString()));
lore.add(" " + ChatColor.GRAY + MyStringUtils.itemMetaToEffects(item.getItemMeta().toString()));
lore.add(Component.text(amount + "x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).append(
Component.text(MyStringUtils.itemCamelCase(item.getType().toString()), NamedTextColor.YELLOW)));
lore.add(Component.text(" " + MyStringUtils.itemMetaToEffects(item.getItemMeta().toString()), NamedTextColor.GRAY));
} else if (item.getType().toString().equalsIgnoreCase("POTION")){
//Do stuff with potions
String amount = String.valueOf(item.getAmount());
lore.add(ChatColor.GRAY + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase(item.getType().toString()));
lore.add(" " + ChatColor.GRAY + MyStringUtils.itemMetaToEffects(item.getItemMeta().toString()));
lore.add(Component.text(amount + "x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).append(
Component.text(MyStringUtils.itemCamelCase(item.getType().toString()), NamedTextColor.YELLOW)));
lore.add(Component.text(" " + MyStringUtils.itemMetaToEffects(item.getItemMeta().toString()), NamedTextColor.GRAY));
} else if (item.getType().toString().equalsIgnoreCase("PLAYER_HEAD")){
String amount = String.valueOf(item.getAmount());
lore.add(ChatColor.GRAY + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase("golden_head"));
lore.add(ChatColor.GRAY + " " + item.getItemMeta().getLore().get(0));
lore.add(Component.text(amount + "x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).append(
Component.text("Golden Head", NamedTextColor.YELLOW).decoration(TextDecoration.ITALIC, false)));
lore.add(Component.text(" ", NamedTextColor.GRAY).append(item.getItemMeta().lore().get(0).color(NamedTextColor.GRAY)));
} else if (item.getType().toString().equalsIgnoreCase("CHEST")){
String amount = String.valueOf(item.getAmount());
lore.add(ChatColor.GRAY + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase("random_loot_chest"));
lore.add(ChatColor.GRAY + " " + item.getItemMeta().getLore().get(0));
lore.add(Component.text(amount + "x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).append(
Component.text("Random Loot Chest", NamedTextColor.YELLOW).decoration(TextDecoration.ITALIC, false)));
lore.add(Component.text(" ", NamedTextColor.GRAY).append(item.getItemMeta().lore().get(0).color(NamedTextColor.GRAY)));
} else {
String amount = String.valueOf(item.getAmount());
lore.add(ChatColor.GRAY + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase(item.getType().toString()));
lore.add(Component.text(amount + "x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).append(
Component.text(MyStringUtils.itemCamelCase(item.getType().toString()), NamedTextColor.YELLOW)));
//If it has enchants, view them
if (!(item.getEnchantments().isEmpty())){
lore.add(" " + ChatColor.GRAY + MyStringUtils.mapStringToEnchantment(item.getEnchantments().toString()));
lore.add(Component.text(" " + MyStringUtils.mapStringToEnchantment(item.getEnchantments().toString()), NamedTextColor.GRAY));
}
}
@@ -201,32 +198,42 @@ public class KitsGUI implements TabExecutor {
ItemStack killItem = (ItemStack) KitConfig.get().get("kits." + key + ".killitem");
if (killItem.getType().toString().equalsIgnoreCase("PLAYER_HEAD")) {
lore.add(ChatColor.WHITE + "Item on Kill:");
lore.add(ChatColor.GRAY + "1x " + ChatColor.YELLOW + "Golden Head"); //fixedI would just get the displayname to make this more dynamic but I cant because of fecking component
lore.add(ChatColor.GRAY + " " + killItem.getItemMeta().getLore().get(0));
lore.add(LanguageConfig.lang.get("KITS_GUI_KILL_ITEM"));
lore.add(Component.text("1x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).append(
Component.text("Golden Head", NamedTextColor.YELLOW).decoration(TextDecoration.ITALIC, false)));
lore.add(Component.text(" ", NamedTextColor.GRAY).append(Component.text("Healing Item")).color(NamedTextColor.GRAY));
} else if (killItem.getType().toString().equalsIgnoreCase("CHEST")){
lore.add(ChatColor.WHITE + "Item on Kill:");
lore.add(LanguageConfig.lang.get("KITS_GUI_KILL_ITEM"));
int amount = killItem.getAmount();
lore.add(ChatColor.GRAY + "" + amount + "x " + ChatColor.YELLOW + "Random Loot Chest");
lore.add(ChatColor.GRAY + " " + killItem.getItemMeta().getLore().get(0));
lore.add(Component.text("1x ", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false).
append(Component.text("Random Loot Chest", NamedTextColor.YELLOW).decoration(TextDecoration.ITALIC, false)));
lore.add(Component.text(" " + killItem.getItemMeta().lore().get(0), NamedTextColor.GRAY)); //might not be needed
//System.out.println(killItem.getItemMeta().getLore().get(0));
} else if (killItem.getType().toString().equalsIgnoreCase("AIR")){
lore.add(ChatColor.WHITE + "No Item on Kill");
lore.add(LanguageConfig.lang.get("KITS_GUI_NO_KILL_ITEM"));
} else {
lore.add(ChatColor.WHITE + "Item on Kill:");
lore.add(LanguageConfig.lang.get("KITS_GUI_KILL_ITEM"));
int amount = killItem.getAmount();
lore.add(ChatColor.GRAY + "" + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase(killItem.getType().toString()));
lore.add(Component.text(amount + "x ", NamedTextColor.GRAY).
append(Component.text(MyStringUtils.itemCamelCase(killItem.getType().toString()), NamedTextColor.YELLOW)));
}
itemMeta.setLore(lore); //Heck you Component
// Preview kit lore
lore.add(Component.text(""));
lore.add(LanguageConfig.lang.get("KITS_GUI_PREVIEW"));
itemMeta.lore(lore);
//Set meta
String kitDisplayColor = KitConfig.get().getString("kits." + key + ".displayname");
kitDisplayColor = ChatColor.translateAlternateColorCodes('&', kitDisplayColor);
itemMeta.setDisplayName(kitDisplayColor + key); //Heck you Component
if (kitDisplayColor.startsWith("&")){
itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', kitDisplayColor + key)); //For legacy kits
} else {
itemMeta.displayName(Component.text(key, NamedTextColor.NAMES.value(kitDisplayColor)).decoration(TextDecoration.ITALIC, false));
}
itemStack.setItemMeta(itemMeta);
//Add items to inventory
@@ -235,12 +242,9 @@ public class KitsGUI implements TabExecutor {
//Reset button
ItemStack resetButton = new ItemStack(Material.BARRIER);
ItemMeta resetButtonMeta = resetButton.getItemMeta();
resetButtonMeta.displayName(Component.text("Reset kit").decoration(TextDecoration.ITALIC, false));
resetButtonMeta.displayName(LanguageConfig.lang.get("KITS_GUI_RESET"));
List<Component> loreList = new ArrayList<>();
TextComponent txt = Component.text("If you do not have permission to reset your kit,").decoration(TextDecoration.ITALIC, false).color(TextColor.color(100,100,100));
TextComponent txt2 = Component.text("this will run /suicide on your behalf.").decoration(TextDecoration.ITALIC, false).color(TextColor.color(100,100,100));
loreList.add(txt);
loreList.add(txt2);
loreList.addAll(ComponentUtils.splitComponent(LanguageConfig.lang.get("KITS_GUI_RESET_LORE")));
resetButtonMeta.lore(loreList);
resetButton.setItemMeta(resetButtonMeta);
kits.setItem(53, resetButton);
@@ -248,21 +252,15 @@ public class KitsGUI implements TabExecutor {
// Perk Redirect Button
ItemStack perkHelpButton = new ItemStack(Material.BOOK);
ItemMeta perkHelpButtonMeta = perkHelpButton.getItemMeta();
perkHelpButtonMeta.displayName(Component.text("Perk Info").decoration(TextDecoration.ITALIC, false));
List<Component> loreList2 = new ArrayList<>();
TextComponent txt21 = Component.text("Click here to change your perks!").decoration(TextDecoration.ITALIC, false).color(TextColor.color(100,100,100));
loreList2.add(txt21);
perkHelpButtonMeta.lore(loreList2);
perkHelpButtonMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PERKS"));
perkHelpButtonMeta.lore(ComponentUtils.splitComponent(LanguageConfig.lang.get("KITS_GUI_PERKS_LORE")));
perkHelpButton.setItemMeta(perkHelpButtonMeta);
kits.setItem(49, perkHelpButton);
player.openInventory(kits);
}
return true;
}
@@ -0,0 +1,160 @@
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.util.Arrays;
public class CreateKit extends Subcommand {
Plugin plugin;
public CreateKit(Plugin plugin) {
this.plugin = plugin;
}
@Override
public String getName() {
return "createkit";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Create a kit from the contents of your inventory";
}
@Override
public String getSyntax() {
return "/purekitpvp kit create <kitName> <displayColor> <kitIcon> <kitPermission> <killItem>";
}
@Override
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
if (!player.hasPermission("purekitpvp.admin.createkit")){
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_NO_PERMISSION.toString()));
return true;
}
if (!(args.length > 3)){
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_LACK_OF_ARGS.toString()));
return false;
}
//Store default arguments
KitIcon kitIconLib = new KitIcon();
String killItem;
String kitPermission = "kit.other";
String kitName = args[1].toLowerCase();
kitName = kitName.substring(0, 1).toUpperCase() + kitName.substring(1);
NamedTextColor displayColor;
try {
displayColor = NamedTextColor.NAMES.value(args[2]);
// System.out.println(displayColor);
if (displayColor == null){
throw new NullPointerException();
}
} catch(Exception e) {
player.sendMessage(Component.text("Color is not valid!", NamedTextColor.RED));
return false;
}
String kitIcon;
if (Arrays.asList(kitIconLib.materialList).contains(args[3])){
kitIcon = args[3].toUpperCase();
} else {
player.sendMessage(Component.text(args[3] + " is not a valid material.", NamedTextColor.RED));
return true;
}
if (args.length >= 5){
kitPermission = args[4];
}
// Kill item
if (args.length >= 6){
if (Arrays.asList(kitIconLib.materialList).contains(args[5])){
killItem = args[5].toUpperCase();
}else {
player.sendMessage(Component.text(args[3] + " is not a valid material.", NamedTextColor.RED));
return true;
}
} else {
killItem = "AIR";
}
ItemStack[] kitContents = player.getInventory().getContents();
int i = 0;
for (ItemStack item : kitContents) {
// This terribleness prevents a bug with the playerPrefs; when making a kit when you have the items of
// another kit (with certain PDC values) this hecks up the mechanism; thus we remove the PDC value associated
if (item == null){
i++;
continue;
}
ItemMeta itemMeta = item.getItemMeta();
itemMeta.getPersistentDataContainer().remove(NamespacedKeys.prefsIndexInstance);
// and it also has to be the exact instance of the NamespacedKey, and its quite far way thus the static class ;-;
item.setItemMeta(itemMeta);
kitContents[i] = item;
// System.out.println(item.getItemMeta().getPersistentDataContainer().getKeys());
i++;
}
//Create kit in config
KitConfig.get().createSection("kits." + kitName);
KitConfig.get().set("kits." + kitName + ".permission", kitPermission);
KitConfig.get().set("kits." + kitName + ".displayname", displayColor.toString());
KitConfig.get().set("kits." + kitName + ".guiitem", kitIcon);
KitConfig.get().set("kits." + kitName + ".guilore", "");
KitConfig.get().set("kits." + kitName + ".contents", kitContents);
//Killitem
Material killItemMat = Material.getMaterial(killItem);
ItemStack killItemStack = new ItemStack(killItemMat); // Forced by contains in MatList above
// KitConfig.get().addDefault("kits." + kitName + ".killitem", "GOLDEN_APPLE"); //what does addDefault even do? not this at least
KitConfig.get().set("kits." + kitName + ".killitem", killItemStack);
KitConfig.get().options().copyDefaults(true);
KitConfig.save();
KitConfig.reload();
player.sendMessage(
Component.text("Kit created with the following properties:", NamedTextColor.GREEN).appendNewline().append(
Component.text("Kit Name: ", NamedTextColor.GOLD).append(Component.text(kitName).color(NamedTextColor.WHITE).appendNewline().append(
Component.text("Kit Color: ", NamedTextColor.GOLD).append(Component.text(displayColor.toString()).color(displayColor)).appendNewline().append(
Component.text("Kit Icon: ", NamedTextColor.GOLD).append(Component.text(kitIcon).color(NamedTextColor.WHITE).appendNewline().append(
Component.text("Kit Permission: ", NamedTextColor.GOLD).append(Component.text(kitPermission).color(NamedTextColor.WHITE).appendNewline().append(
Component.text("Kill Item: ", NamedTextColor.GOLD).append(Component.text(killItem).color(NamedTextColor.WHITE)
)))))))))); // Component LUL
player.sendMessage(Component.text("You can change these in the kits.yml file, but remember to back-up the file when manually editing."));
return true;
}
}
@@ -1,19 +1,14 @@
package me.lifelessnerd.purekitpvp.createKit;
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class DeleteKit extends Subcommand {
Plugin plugin;
@@ -40,19 +35,24 @@ public class DeleteKit extends Subcommand {
@Override
public String getSyntax() {
return "/purekitpvp deletekit <kitName>";
return "/purekitpvp kit delete <kitName>";
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return true;
}
if (!player.hasPermission("purekitpvp.admin.deletekit")){
player.sendMessage(ChatColor.RED + "No permission!");
@Override
public boolean perform(CommandSender sender, String[] args) {
if (!sender.hasPermission("purekitpvp.admin.deletekit")){
sender.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_NO_PERMISSION.toString()));
return true;
}
if (!(args.length >= 2)){
player.sendMessage(ChatColor.RED + "Please provide arguments!");
sender.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_LACK_OF_ARGS.toString()));
return false;
}
@@ -61,14 +61,14 @@ public class DeleteKit extends Subcommand {
if(KitConfig.get().get("kits." + kitName) == null){
player.sendMessage(ChatColor.GRAY + "That kit does not exist.");
sender.sendMessage(LanguageConfig.lang.get(LanguageKey.KITS_DOES_NOT_EXIST.toString()));
return true;
}
KitConfig.get().getConfigurationSection("kits").set(kitName, null);
KitConfig.save();
KitConfig.reload();
player.sendMessage("You removed kit " + ChatColor.BLUE + kitName);
sender.sendMessage(Component.text("You removed kit ", NamedTextColor.GREEN).append(Component.text(kitName, NamedTextColor.WHITE)));
return true;
@@ -0,0 +1,77 @@
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class EditKit extends Subcommand {
Plugin plugin;
public EditKit(Plugin plugin) {
this.plugin = plugin;
}
@Override
public String getName() {
return "editkit";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Edit a kit";
}
@Override
public String getSyntax() {
return "/purekitpvp editkit <kitName>";
}
@Override
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
if (!player.hasPermission("purekitpvp.admin.editkit")){
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_NO_PERMISSION.toString()));
return true;
}
if (!(args.length >= 2)){
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_LACK_OF_ARGS.toString()));
return false;
}
String kitName = args[1].toLowerCase();
kitName = kitName.substring(0, 1).toUpperCase() + kitName.substring(1);
if(KitConfig.get().get("kits." + kitName) == null){
player.sendMessage(LanguageConfig.lang.get(LanguageKey.KITS_DOES_NOT_EXIST.toString()));
return true;
}
EditKitInventory editKitInventory = new EditKitInventory(54,
Component.text("Editing " + kitName, NamedTextColor.GOLD).decoration(TextDecoration.ITALIC, false),
plugin, kitName);
editKitInventory.openInventory(player);
return true;
}
}
@@ -0,0 +1,91 @@
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.AbstractInventory;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
public class EditKitInventory extends AbstractInventory {
Plugin plugin;
String kitName;
public EditKitInventory(int size, Component title, Plugin plugin, String kitName) {
super(size, title, plugin);
this.kitName = kitName;
this.plugin = plugin;
initializeItems();
}
@Override
public void initializeItems() {
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitItems = (List<ItemStack>) fileConfiguration.get("kits." + kitName + ".contents");
for (int index = 0; index < kitItems.size(); index++) {
ItemStack item = kitItems.get(index);
if (item == null) {
item = new ItemStack(Material.AIR);
}
inv.setItem(index, item);
}
ItemStack redStainedGlass = new ItemStack(Material.RED_STAINED_GLASS_PANE, 1);
ItemMeta glassMeta = redStainedGlass.getItemMeta();
glassMeta.displayName(Component.text(""));
redStainedGlass.setItemMeta(glassMeta);
for (int i = 41; i < 54; i++) inv.setItem(i, redStainedGlass);
ItemStack greenConcrete = new ItemStack(Material.GREEN_CONCRETE, 1);
ItemMeta saveMeta = greenConcrete.getItemMeta();
saveMeta.displayName(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_SAVE.toString()));
ArrayList<Component> lore = new ArrayList<>();
lore.add(LanguageConfig.lang.get(LanguageKey.KITS_GUI_PREFS_INFO.toString()));
saveMeta.lore(lore);
saveMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_GUI_EDIT_ITEM"), PersistentDataType.STRING, "Save");
saveMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_GUI_EDIT_ITEM_KIT"), PersistentDataType.STRING, kitName);
greenConcrete.setItemMeta(saveMeta);
inv.setItem(49, greenConcrete);
}
@Override
public void onInventoryClickLogic(InventoryClickEvent e) {
if (e.getSlot() >= 41){ // red panes
e.setCancelled(true);
}
if (e.getSlot() == 49){ // save icon
e.setCancelled(true);
ItemStack[] kitContents = inv.getContents();
int index = 0;
for (ItemStack item : inv.getContents()){
if (index >= 41) {
kitContents[index] = null;
}
index++;
}
KitConfig.get().set("kits." + kitName + ".contents", kitContents);
KitConfig.save();
KitConfig.reload();
e.getWhoClicked().sendMessage(LanguageConfig.lang.get(LanguageKey.KITS_GUI_EDIT_SAVED.toString()));
inv.close();
}
}
}
@@ -1,4 +1,4 @@
package me.lifelessnerd.purekitpvp.createKit;
package me.lifelessnerd.purekitpvp.kitadmin;
public class KitIcon {
@@ -163,7 +163,7 @@ public class KitIcon {
"chiseled_sandstone",
"cut_sandstone",
"cobweb",
"grass",
"short_grass",
"fern",
"azalea",
"flowering_azalea",
@@ -0,0 +1,88 @@
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class KitSupercommand extends Subcommand {
PureKitPvP plugin;
public KitSupercommand(PureKitPvP plugin) {
this.plugin = plugin;
}
@Override
public String getName() {
return "kit";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "All admin commands related to kits";
}
@Override
public String getSyntax() {
return "/purekitpvp kit <create/delete/edit/setkillitem> <optional-identifiers>";
}
@Override
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
if (args.length < 2){
player.sendMessage(LanguageConfig.lang.get("GENERIC_LACK_OF_ARGS"));
return true;
}
String suboption = args[1];
args = Arrays.stream(args, 1, args.length).toArray(String[]::new);
switch(suboption){
case "create":
CreateKit createKit = new CreateKit(plugin);
createKit.perform(player, args);
break;
case "delete":
DeleteKit deleteKit = new DeleteKit(plugin);
deleteKit.perform(player, args);
break;
case "reset":
ResetKit resetKit = new ResetKit();
resetKit.perform(player, args);
break;
case "edit":
EditKit editKit = new EditKit(plugin);
editKit.perform(player, args);
break;
case "setkillitem":
SetKillItem setKillItem = new SetKillItem(plugin);
setKillItem.perform(player, args);
break;
case "convertFromYAML":
// TODO
break;
default:
player.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_ARGS").replaceText(ComponentUtils.replaceConfig("%ARG%", suboption)));
}
return true;
}
}
@@ -0,0 +1,8 @@
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.PluginGetter;
public class NamespacedKeys {
// See comment in CreateKit for why this class exists
public static org.bukkit.NamespacedKey prefsIndexInstance = new org.bukkit.NamespacedKey(PluginGetter.Plugin(), "KITS_GUI_PREFS_INDEX");
}
@@ -1,16 +1,11 @@
package me.lifelessnerd.purekitpvp.kitCommand;
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.Subcommand;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.kitCommand.GetKit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class ResetKit extends Subcommand {
@@ -35,12 +30,18 @@ public class ResetKit extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return false;
}
if(!(player.hasPermission("purekitpvp.admin.resetkit"))){
player.sendMessage(ChatColor.RED + "You do not have permission!");
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
// if(!(player.hasPermission("purekitpvp.admin.resetkit"))){
// player.sendMessage(LanguageConfig.lang.get("GENERIC_NO_PERMISSION"));
// return false;
// } Redundant, admin.* check is done in superclass
for (PotionEffect effect : player.getActivePotionEffects()) {
player.removePotionEffect(effect.getType());
@@ -50,7 +51,7 @@ public class ResetKit extends Subcommand {
player.setLevel(0);
player.getInventory().clear();
GetKit.hasKit.remove(player.getName());
player.sendMessage(ChatColor.GRAY + "You have reset your kit.");
player.sendMessage(LanguageConfig.lang.get("KITS_RESET_KIT"));
return true;
@@ -1,21 +1,16 @@
package me.lifelessnerd.purekitpvp.createKit;
package me.lifelessnerd.purekitpvp.kitadmin;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class SetKillItem extends Subcommand {
Plugin plugin;
@@ -45,27 +40,34 @@ public class SetKillItem extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return false;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
Player player = (Player) sender;
if (!player.hasPermission("purekitpvp.admin.createkit")){
player.sendMessage(ChatColor.RED + "No permission!");
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_NO_PERMISSION.toString()));
return true;
}
if (!(args.length >= 2)){
player.sendMessage(ChatColor.RED + "Please provide arguments!");
player.sendMessage(LanguageConfig.lang.get(LanguageKey.GENERIC_LACK_OF_ARGS.toString()));
return false;
}
String kitNameArg = MyStringUtils.camelCaseWord(args[1]);
if (!(KitConfig.get().isSet("kits." + kitNameArg))){
player.sendMessage(ChatColor.GRAY + "That kit does not exist.");
player.sendMessage(LanguageConfig.lang.get(LanguageKey.KITS_DOES_NOT_EXIST.toString()));
return true;
}
ItemStack itemStack = player.getInventory().getItemInMainHand();
KitConfig.get().set("kits." + kitNameArg + ".killitem", itemStack);
player.sendMessage("Set the kill item of the kit " + kitNameArg + " to " + itemStack.getType());
player.sendMessage(Component.text("Set the kill item of the kit " + kitNameArg + " to " + itemStack.getType()));
KitConfig.save();
KitConfig.reload();
@@ -0,0 +1,90 @@
package me.lifelessnerd.purekitpvp.legacy;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.KitStatsConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
public class KitPreview {
Plugin plugin;
String kitName;
Player player;
public KitPreview(Plugin plugin, String kitName, Player player) {
this.plugin = plugin;
this.kitName = kitName;
this.player = player;
}
public void openPreviewInventory(){
Inventory previewInv = Bukkit.createInventory(null, 54, LanguageConfig.lang.get("KITS_GUI_PREVIEW_TITLE").replaceText(ComponentUtils.replaceConfig("%KIT%", kitName)));
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitItems = (List<ItemStack>) fileConfiguration.get("kits." + kitName + ".contents");
for (int index = 0; index < kitItems.size(); index++) {
ItemStack item = kitItems.get(index);
if (item == null) {
item = new ItemStack(Material.AIR);
}
previewInv.setItem(index, item);
}
ItemStack redStainedGlass = new ItemStack(Material.RED_STAINED_GLASS_PANE, 1);
ItemMeta glassMeta = redStainedGlass.getItemMeta();
glassMeta.displayName(Component.text(""));
redStainedGlass.setItemMeta(glassMeta);
previewInv.setItem(45, redStainedGlass);
previewInv.setItem(46, redStainedGlass);
previewInv.setItem(52, redStainedGlass);
previewInv.setItem(53, redStainedGlass);
ItemStack selectItem = new ItemStack(Material.GREEN_CONCRETE, 1);
ItemMeta selectMeta = selectItem.getItemMeta();
selectMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREVIEW_SELECT"));
selectMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Select");
selectMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM_KIT"), PersistentDataType.STRING, kitName);
selectItem.setItemMeta(selectMeta);
previewInv.setItem(50, selectItem);
ItemStack anvil = new ItemStack(Material.ANVIL, 1);
ItemMeta anvilMeta = anvil.getItemMeta();
anvilMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREVIEW_STATS"));
anvilMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Stats");
ArrayList<Component> lore2 = new ArrayList<>();
int kitChosen = KitStatsConfig.get().getInt(kitName);
lore2.add(Component.text("Times Chosen: ", NamedTextColor.AQUA).append(Component.text(kitChosen, NamedTextColor.GREEN)).decoration(TextDecoration.ITALIC, false));
anvilMeta.lore(lore2);
anvil.setItemMeta(anvilMeta);
previewInv.setItem(49, anvil);
ItemStack backItem = new ItemStack(Material.ARROW, 1);
ItemMeta backMeta = selectItem.getItemMeta();
backMeta.displayName(LanguageConfig.lang.get("KITS_GUI_PREVIEW_BACK"));
backMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING, "Back");
backItem.setItemMeta(backMeta);
previewInv.setItem(48, backItem);
player.openInventory(previewInv);
}
}
@@ -0,0 +1,71 @@
package me.lifelessnerd.purekitpvp.legacy;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
public class KitPreviewListener implements Listener {
Plugin plugin;
public KitPreviewListener(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
Player player = (Player) e.getWhoClicked();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (e.getCurrentItem() == null){
return;
}
ItemStack clickedItem = e.getCurrentItem();
InventoryView inv = e.getView();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
TextComponent desiredInvTitle = (TextComponent) LanguageConfig.lang.get("KITS_GUI_PREVIEW_TITLE").replaceText(ComponentUtils.replaceConfig("%KIT%", ""));
String desiredInvTitleString = serializer.serialize(desiredInvTitle); // I hate this
if (inv.title().toString().contains(desiredInvTitleString)) {
//I sometimes hate component - gotta do this with UUID in the future
// Not components fault - my system is just shitty, heck me
e.setCancelled(true);
if (clickedItem.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"))){
String pdcValue = clickedItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM"), PersistentDataType.STRING);
switch(pdcValue){
case "Select":
String kitName = clickedItem.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "KITS_PREVIEW_GUI_ITEM_KIT"), PersistentDataType.STRING);
player.chat("/getkit " + kitName);
player.closeInventory();
break;
case "Stats":
//Can be used later?
break;
case "Back":
player.chat("/kit");
break;
default:
break;
}
}
}
}
}
@@ -2,13 +2,10 @@ package me.lifelessnerd.purekitpvp.noncombatstats.commands;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.KitStatsConfig;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -40,7 +37,13 @@ public class GetKitStats extends Subcommand {
}
@Override
public boolean perform(Player player, String[] args) {
public boolean getConsoleExecutable() {
return true;
}
@Override
public boolean perform(CommandSender sender, String[] args) {
FileConfiguration kitStats = KitStatsConfig.get();
ArrayList<String> kitStatsKeys = new ArrayList<>(kitStats.getKeys(false));
@@ -68,7 +71,7 @@ public class GetKitStats extends Subcommand {
for(String key : sortedMap.keySet()){
player.sendMessage(key + " - " + kitStats.getInt(key));
sender.sendMessage(Component.text(key + " - " + kitStats.getInt(key)));
}
return true;
@@ -1,20 +1,23 @@
package me.lifelessnerd.purekitpvp.noncombatstats.commands;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -40,34 +43,23 @@ public class GetStats implements TabExecutor {
Set<String> allKeys = playerStatsConfig.getKeys(true);
if (!(allKeys.contains(argumentPlayer))){
player.sendMessage("That player does not have any stats attached to them.");
player.sendMessage(LanguageConfig.lang.get(LanguageKey.STATS_NO_STATS.toString()));
return true;
}
player.sendMessage(LanguageConfig.lang.get(LanguageKey.STATS_TITLE.toString()).
replaceText(ComponentUtils.replaceConfig("%PLAYER%", argumentPlayer)));
player.sendMessage(argumentPlayer + "'s " + ChatColor.BLUE + "Statistics");
for (String key : allKeys){
if (key.split("\\.").length == 1){
continue;
}
if (key.split("\\.")[0].equalsIgnoreCase(argumentPlayer)) {
ConfigurationSection playerStatsSection = PlayerStatsConfig.get().getConfigurationSection(argumentPlayer);
//Only children of player
if (key.split("\\.")[1].equalsIgnoreCase("kdratio")) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a " +
MyStringUtils.itemCamelCase(key.split("\\.")[1]) + "&c- &r" + playerStatsConfig.getDouble(key)));
} else if (key.split("\\.")[1].equalsIgnoreCase("current_kit")){
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a " +
MyStringUtils.itemCamelCase(key.split("\\.")[1]) + "&c- &r" + playerStatsConfig.getString(key)));
} else {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a " +
MyStringUtils.itemCamelCase(key.split("\\.")[1]) + "&c- &r" + playerStatsConfig.getInt(key)));
}
}
for (String key : playerStatsSection.getKeys(false)){
player.sendMessage(
Component.text(" " + MyStringUtils.itemCamelCase(key)).color(NamedTextColor.GREEN).append(
Component.text("- ").color(NamedTextColor.RED).append(
Component.text(playerStatsSection.get(key).toString()).color(NamedTextColor.WHITE)
)));
}
return true;
}
@@ -3,9 +3,7 @@ package me.lifelessnerd.purekitpvp.noncombatstats.listeners;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityShootBowEvent;
@@ -1,32 +1,31 @@
package me.lifelessnerd.purekitpvp.perks.perkCommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.PerkData;
import me.lifelessnerd.purekitpvp.kitCommand.GetKit;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkLib;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class PerkCommand implements CommandExecutor {
Plugin plugin;
@@ -44,38 +43,41 @@ public class PerkCommand implements CommandExecutor {
Player player = (Player) sender;
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
player.sendMessage(ChatColor.RED + "You can only use this menu in " + ChatColor.GRAY + plugin.getConfig().getString("world"));
player.sendMessage(LanguageConfig.lang.get("GENERIC_WRONG_WORLD").
replaceText(ComponentUtils.replaceConfig("%WORLD%",plugin.getConfig().getString("world"))));
return true;
}
if (GetKit.hasKit.contains(player.getName())){
player.sendMessage(ChatColor.RED + "You can only change perks when you have no kit selected!");
player.sendMessage(LanguageConfig.lang.get("PERKS_ALREADY_SELECTED"));
return true;
}
//Create inventory GUI
TextComponent invTitle = Component.text("Perks Menu").color(TextColor.color(255, 150, 20));
Component invTitle = LanguageConfig.lang.get("PERKS_GUI_TITLE").decoration(TextDecoration.ITALIC, false);
Inventory perksInventory = Bukkit.createInventory(null, 54, invTitle);
//Info item
ItemStack infoItem = new ItemStack(Material.BOOK);
TextComponent infoItemName = Component.text("Perks Info").color(TextColor.color(233, 67, 47)).decoration(TextDecoration.ITALIC, false);
Component infoItemName = LanguageConfig.lang.get("PERKS_GUI_INFO_TITLE");
ItemMeta infoMeta = infoItem.getItemMeta();
infoMeta.displayName(infoItemName);
infoMeta = ComponentUtils.setLore(infoMeta, "&aYou can equip a total of &e5 &aperks total.", 0);
infoMeta = ComponentUtils.setLore(infoMeta, "&7Click on a perk slot to choose a perk for that slot.", 1);
infoMeta = ComponentUtils.setLore(infoMeta, "&7It will replace any perk currently in that slot.", 2);
infoMeta = ComponentUtils.setLore(infoMeta, "&7Perks are abilities that are always active.", 3);
infoMeta = ComponentUtils.setLore(infoMeta, "&7Duplicate perks do not stack.", 4);
ArrayList<Component> infoLore = ComponentUtils.splitComponent(LanguageConfig.lang.get("PERKS_GUI_INFO_LORE"));
infoMeta.lore(infoLore);
infoItem.setItemMeta(infoMeta);
perksInventory.setItem(13, infoItem);
//Back to kits item
ItemStack kitItem = new ItemStack(Material.ARROW);
TextComponent kitItemName = Component.text("Back to Kits").color(TextColor.color(0, 255, 47)).decoration(TextDecoration.ITALIC, false);
Component kitItemName = LanguageConfig.lang.get("PERKS_GUI_BACK_KITS");
ItemMeta kitItemMeta = kitItem.getItemMeta();
kitItemMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "PERKS_GUI_BACK_KITS"), PersistentDataType.BOOLEAN, true);
kitItemMeta.displayName(kitItemName);
kitItem.setItemMeta(kitItemMeta);
perksInventory.setItem(49, kitItem);
// Notoriety and marksman perk lore could be better if we replaceText with the config value; but then there
// would need to be edge cases below (if notoriety -> replace lore with value ) - dats ugly tho
//Fill perk slots with either empty or actual perk icon
for (int index = 20; index <= 24; index++){
@@ -85,35 +87,37 @@ public class PerkCommand implements CommandExecutor {
if (fileContent == null){
// No perk selected in this slot; show red stained-glass
ItemStack perkSlot = new ItemStack(Material.RED_STAINED_GLASS_PANE);
TextComponent perkSlotName = Component.text("Perk Slot " + slot).color(TextColor.color(233, 67, 47)).decoration(TextDecoration.ITALIC, false);
Component perkSlotName = LanguageConfig.lang.get("PERKS_GUI_SLOT_TITLE").
replaceText(ComponentUtils.replaceConfig("%SLOT%", String.valueOf(slot)));
ItemMeta perkSlotMeta = perkSlot.getItemMeta();
perkSlotMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "PERKS_GUI_SLOT_TITLE"), PersistentDataType.INTEGER, slot);
perkSlotMeta.displayName(perkSlotName);
perkSlotMeta = ComponentUtils.setLore(perkSlotMeta, "&aClick to select a perk for this slot!", 0);
perkSlotMeta.lore(ComponentUtils.splitComponent(LanguageConfig.lang.get("PERKS_GUI_SLOT_LORE")));
perkSlot.setItemMeta(perkSlotMeta);
perkSlot.setAmount(slot);
perksInventory.setItem(index, perkSlot);
} else {
PerkLib perkLib = new PerkLib();
ItemStack perkSlot = new ItemStack(perkLib.perkIcons.get(fileContent));
TextComponent perkSlotName = Component.text("Perk Slot " + slot).color(TextColor.color(233, 67, 47)).decoration(TextDecoration.ITALIC, false);
Component perkSlotName = LanguageConfig.lang.get("PERKS_GUI_SLOT_TITLE").
replaceText(ComponentUtils.replaceConfig("%SLOT%", String.valueOf(slot)));
ItemMeta perkSlotMeta = perkSlot.getItemMeta();
perkSlotMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "PERKS_GUI_SLOT_TITLE"), PersistentDataType.INTEGER, slot);
perkSlotMeta.displayName(perkSlotName);
//Component style - not my own class util (okay, only the decoder)
ArrayList<Component> loreTBA = new ArrayList<>();
TextComponent loreTitle = Component.text(fileContent).color(TextColor.color(0, 230, 0)).decoration(TextDecoration.ITALIC, false);
Component loreTitle = Component.text(fileContent).color(TextColor.color(0, 230, 0)).decoration(TextDecoration.ITALIC, false);
loreTBA.add(loreTitle);
if (perkLib.perks.get(fileContent).contains("\n")) {
String[] decodedLore = MyStringUtils.perkLoreDecoder(perkLib.perks.get(fileContent));
for (String line : decodedLore) {
loreTBA.add(Component.text(line).color(TextColor.color(150, 150, 150)).decoration(TextDecoration.ITALIC, false));
}
} else {
loreTBA.add(Component.text(perkLib.perks.get(fileContent)).color(TextColor.color(150, 150, 150)).decoration(TextDecoration.ITALIC, false));
}
ArrayList<Component> perkLore = ComponentUtils.splitComponent(perkLib.perks.get(fileContent));
loreTBA.addAll(perkLore);
perkSlotMeta.lore(loreTBA);
perkSlotMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
perkSlotMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
perkSlot.setItemMeta(perkSlotMeta);
perkSlot.setAmount(slot);
perksInventory.setItem(index, perkSlot);
@@ -121,6 +125,15 @@ public class PerkCommand implements CommandExecutor {
}
player.openInventory(perksInventory);
// System.out.println(PerkData.get().getString(player.getName()));
// Create perks config values if not present
if (PerkData.get().getString(player.getName()) == null){
Set<String> empty = new HashSet<>();
PerkData.get().set(player.getName(), empty);
PerkData.save();
PerkData.reload();
}
return true;
}
}
@@ -1,8 +1,9 @@
package me.lifelessnerd.purekitpvp.perks.perkCommand;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.PerkData;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkLib;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
@@ -10,18 +11,19 @@ import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
@@ -46,19 +48,24 @@ public class PerkGUIListener implements Listener {
if (e.getCurrentItem() == null || e.getRawSlot() >= 53) {
return;
}
// For later (for the else if)
TextComponent desiredInvTitle = (TextComponent) LanguageConfig.lang.get("PERKS_GUI_SLOT_TITLE").
replaceText(ComponentUtils.replaceConfig("%SLOT%", ""));
PlainTextComponentSerializer ptcs = PlainTextComponentSerializer.plainText();
//
ItemStack clickedItem = e.getCurrentItem();
InventoryView inv = e.getView();
if (inv.title().toString().contains("Perks Menu")) { //I hate component
if (inv.title().equals(LanguageConfig.lang.get("PERKS_GUI_TITLE"))) {
e.setCancelled(true);
Component itemDisplayName = clickedItem.displayName();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
String itemName = serializer.serialize(itemDisplayName);
// This is when you click on a perk slot to modify it
if (itemName.contains("Perk Slot")) {
int slot = Integer.parseInt(String.valueOf(itemName.charAt(itemName.length() - 2)));
if (clickedItem.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "PERKS_GUI_SLOT_TITLE"), PersistentDataType.INTEGER)) {
int slot = clickedItem.getAmount();
//Create inventory GUI
TextComponent invTitle = Component.text("Perk Slot " + slot).color(TextColor.color(255, 150, 20));
Component invTitle = LanguageConfig.lang.get("PERKS_GUI_SLOT_TITLE").
replaceText(ComponentUtils.replaceConfig("%SLOT%", String.valueOf(slot)));
Inventory perkSlotInventory = Bukkit.createInventory(null, 54, invTitle);
//Fill inventory with interactive perk items
@@ -77,7 +84,7 @@ public class PerkGUIListener implements Listener {
if (perk.equals(selectedPerk)){
itemMeta.addEnchant(Enchantment.DAMAGE_ALL, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
itemMeta.displayName(Component.text(perk).color(TextColor.color(50, 200, 0)).decoration(TextDecoration.BOLD, true));
itemMeta.displayName(Component.text(perk).color(TextColor.color(50, 200, 0)).decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false));
}
}
@@ -85,14 +92,8 @@ public class PerkGUIListener implements Listener {
ArrayList<Component> loreTBA = new ArrayList<>();
if (perkLib.perks.get(perk).contains("\n")) {
String[] decodedLore = MyStringUtils.perkLoreDecoder(perkLib.perks.get(perk));
for (String line : decodedLore) {
loreTBA.add(Component.text(line).color(TextColor.color(150, 150, 150)).decoration(TextDecoration.ITALIC, false));
}
} else {
loreTBA.add(Component.text(perkLib.perks.get(perk)).color(TextColor.color(150, 150, 150)).decoration(TextDecoration.ITALIC, false));
}
Component perkLore = perkLib.perks.get(perk);
loreTBA.addAll(ComponentUtils.splitComponent(perkLore));
icon.lore(loreTBA);
perkSlotInventory.addItem(icon);
@@ -100,7 +101,8 @@ public class PerkGUIListener implements Listener {
ItemStack backButton = new ItemStack(Material.ARROW);
ItemMeta backButtonMeta = backButton.getItemMeta();
backButtonMeta.displayName(Component.text("Go Back").color(TextColor.color(0, 250, 0)).decoration(TextDecoration.ITALIC, false));
backButtonMeta.displayName(LanguageConfig.lang.get("PERKS_GUI_BACK"));
backButtonMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, "PERKS_GUI_BACK"), PersistentDataType.BOOLEAN, true);
backButtonMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
backButton.setItemMeta(backButtonMeta);
perkSlotInventory.setItem(49,backButton);
@@ -108,20 +110,17 @@ public class PerkGUIListener implements Listener {
player.openInventory(perkSlotInventory);
}
else if (itemName.contains("Back to Kits")){
inv.close();
else if (clickedItem.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "PERKS_GUI_BACK_KITS"), PersistentDataType.BOOLEAN)){
player.chat("/kit");
}
}
else if (inv.title().toString().contains("Perk Slot")){
else if (ptcs.serialize(inv.title()).contains(desiredInvTitle.content())){
e.setCancelled(true);
Component title = inv.title();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
String itemName = serializer.serialize(title);
String clickedItemName = serializer.serialize(e.getCurrentItem().displayName());
if (clickedItemName.contains("Go Back")){
inv.close();
// String clickedItemName = serializer.serialize(e.getCurrentItem().displayName());
if (e.getCurrentItem().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "PERKS_GUI_BACK"))){
player.chat("/perks");
} else {
@@ -134,7 +133,6 @@ public class PerkGUIListener implements Listener {
PerkData.save();
PerkData.reload();
inv.close();
player.chat("/perks");
}
@@ -1,14 +1,12 @@
package me.lifelessnerd.purekitpvp.perks.perkfirehandler;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.PerkData;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.*;
@@ -20,7 +18,6 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.Collections;
@@ -71,16 +68,18 @@ public class PerkFireHandler {
break;
case "NOTORIETY":
if(Math.random() <= 0.15) {
ItemStack weapon = player.getInventory().getItemInMainHand();
ItemMeta weaponMeta = weapon.getItemMeta();
if (weaponMeta == null){continue;} // If weapon is hand
int sharpnessLevel = weaponMeta.getEnchantLevel(Enchantment.DAMAGE_ALL);
ItemStack weapon = player.getInventory().getItemInMainHand();
ItemMeta weaponMeta = weapon.getItemMeta();
if (weaponMeta == null){continue;} // If weapon is hand TODO maybe - check if it is a weapon?
if (weapon.getType() == Material.BOW){continue;} // meh
int sharpnessLevel = weaponMeta.getEnchantLevel(Enchantment.DAMAGE_ALL);
double rnd = Math.random();
if(rnd * 100 <= (100 - plugin.getConfig().getInt("notoriety-chance-decrease") * sharpnessLevel)) {
if (plugin.getConfig().getInt("notoriety-maximum") != -1){
// So if the boundary is set to SOME value
if (sharpnessLevel >= plugin.getConfig().getInt("notoriety-maximum")){
player.sendMessage(ChatColor.YELLOW + "You have reached the maximum Notoriety!");
player.sendMessage(LanguageConfig.lang.get("PERKS_PERK_NOTORIETY_MAX"));
player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_FALL, 1,0);
continue;
}
@@ -88,7 +87,9 @@ public class PerkFireHandler {
weaponMeta.removeEnchant(Enchantment.DAMAGE_ALL);
weaponMeta.addEnchant(Enchantment.DAMAGE_ALL, sharpnessLevel + 1, true);
weapon.setItemMeta(weaponMeta);
player.sendMessage(ChatColor.YELLOW + "Your sharpness level has increased!");
player.sendMessage(LanguageConfig.lang.get("PERKS_PERK_NOTORIETY_UPGRADE").
replaceText(ComponentUtils.replaceConfig("%CHANCE%",
String.valueOf(100 - plugin.getConfig().getInt("notoriety-chance-decrease") * sharpnessLevel))));
}
break;
case "ENDERMAGIC":
@@ -96,7 +97,7 @@ public class PerkFireHandler {
if(Math.random() <= 0.3) {
ItemStack pearl = new ItemStack(Material.ENDER_PEARL, 1);
player.getInventory().addItem(pearl);
player.sendMessage(ChatColor.YELLOW + "You gained an ender pearl!");
player.sendMessage(LanguageConfig.lang.get("PERKS_PERK_ENDERMAGIC_OCCUR"));
}
break;
case "SPEEDSTER":
@@ -104,25 +105,30 @@ public class PerkFireHandler {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 1));
break;
case "MARKSMAN":
if(Math.random() <= 0.5) {
ItemStack weapon = player.getInventory().getItemInMainHand();
ItemMeta weaponMeta = weapon.getItemMeta();
if (weapon.getType() != Material.BOW){continue;}
if (weaponMeta == null){continue;} // If weapon is hand
int powerLevel = weaponMeta.getEnchantLevel(Enchantment.ARROW_DAMAGE);
ItemStack weaponMarksman = player.getInventory().getItemInMainHand();
ItemMeta weaponMarksmanMeta = weaponMarksman.getItemMeta();
if (weaponMarksman.getType() != Material.BOW){continue;}
if (weaponMarksmanMeta == null){continue;} // If weapon is hand
int powerLevel = weaponMarksmanMeta.getEnchantLevel(Enchantment.ARROW_DAMAGE);
double rnd2 = Math.random();
if(rnd2 * 100 <= (100 - plugin.getConfig().getInt("notoriety-chance-decrease") * powerLevel)) {
if (plugin.getConfig().getInt("marksman-maximum") != -1){
// So if the boundary is set to SOME value
if (powerLevel >= plugin.getConfig().getInt("marksman-maximum")){
player.sendMessage(ChatColor.YELLOW + "You have reached the maximum power level!");
player.sendMessage(LanguageConfig.lang.get("PERKS_PERK_MARKSMAN_MAX"));
player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_FALL, 1,0);
continue;
}
}
weaponMeta.removeEnchant(Enchantment.ARROW_DAMAGE);
weaponMeta.addEnchant(Enchantment.ARROW_DAMAGE, powerLevel + 1, true);
weapon.setItemMeta(weaponMeta);
player.sendMessage(ChatColor.YELLOW + "Your power level has increased!");
weaponMarksmanMeta.removeEnchant(Enchantment.ARROW_DAMAGE);
weaponMarksmanMeta.addEnchant(Enchantment.ARROW_DAMAGE, powerLevel + 1, true);
weaponMarksman.setItemMeta(weaponMarksmanMeta);
player.sendMessage(LanguageConfig.lang.get("PERKS_PERK_MARKSMAN_UPGRADE").
replaceText(ComponentUtils.replaceConfig("%CHANCE%",
String.valueOf(100 - plugin.getConfig().getInt("notoriety-chance-decrease") * powerLevel))));
}
break;
@@ -189,7 +195,10 @@ public class PerkFireHandler {
}
// I could have just always swapped, sometimes swap with air
// oh well shite
damaged.sendMessage(ChatColor.YELLOW + "You were disarmed!");
damaged.sendMessage(LanguageConfig.lang.get("PERKS_PERK_ROBBERY_DISARMED").
replaceText(ComponentUtils.replaceConfig("%PLAYER%", damager.getName())));
damager.sendMessage(LanguageConfig.lang.get("PERKS_PERK_ROBBERY_DISARMER").
replaceText(ComponentUtils.replaceConfig("%PLAYER%", damaged.getName())));
}
break;
}
@@ -210,11 +219,12 @@ public class PerkFireHandler {
//Main logic
double damageDealt = event.getDamage();
double regen = damageDealt / 2;
if (player.getHealth() + regen <= 20){
double maxHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
// System.out.println(maxHealth);
if (player.getHealth() + regen <= maxHealth){
player.setHealth(player.getHealth() + regen);
} else {
player.setHealth(20);
player.setHealth(maxHealth);
}
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_BURP, 1,0);
@@ -1,30 +1,35 @@
package me.lifelessnerd.purekitpvp.perks.perkfirehandler;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import java.util.HashMap;
public class PerkLib {
public HashMap<String, String> perks = new HashMap<>();
public HashMap<String, Component> perks = new HashMap<>();
public HashMap<String, Material> perkIcons = new HashMap<>();
public PerkLib(){
perks.put("JUGGERNAUT", "Gain regeneration 1 (5s) after every kill");
perks.put("BULLDOZER", "Gain strength 2 (3s) after every kill");
perks.put("KNOWLEDGE", "Gain 1 XP level on kill");
perks.put("NOTORIETY","15% chance of gaining a sharpness level on each kill\nSharpness will be added to the item held");
perks.put("ENDERMAGIC", "30% chance of gaining an ender pearl on kill");
perks.put("SPEEDSTER","Gain 10 seconds of speed 2 after every kill");
perks.put("ROBBERY","30% chance of disarming someone if hit with your fist\nThe weapon will be swapped with a slot in the inventory");
perks.put("SNOWMAN","Give slowness 1 (3s) when you hit someone with a snowball");
perks.put("DISRUPTOR","Give poison 1 (5s) when you hit someone with an egg");
perks.put("ENDERMAN", "You can now ride ender pearls; they do no damage");
perks.put("VAMPIRE", "On critical hits, gain 50% of the damage\nyou dealt, as instant health");
perks.put("MARKSMAN", "50% chance of gaining a power level on each bow kill\nPower is added to the item held, if it's a bow");
perks.put("APOLLO", "You get each arrow you hit on a player back\nA kill nets one extra arrow of that type");
perks.put("ADRENALINE", "When below 6 HP (3 hearts), you get a speed boost");
perks.put("JUGGERNAUT", LanguageConfig.lang.get("PERKS_PERK_JUGGERNAUT"));
perks.put("BULLDOZER", LanguageConfig.lang.get("PERKS_PERK_BULLDOZER"));
perks.put("KNOWLEDGE", LanguageConfig.lang.get("PERKS_PERK_KNOWLEDGE"));
perks.put("NOTORIETY", LanguageConfig.lang.get("PERKS_PERK_NOTORIETY"));
perks.put("ENDERMAGIC", LanguageConfig.lang.get("PERKS_PERK_ENDERMAGIC"));
perks.put("SPEEDSTER",LanguageConfig.lang.get("PERKS_PERK_SPEEDSTER"));
perks.put("ROBBERY",LanguageConfig.lang.get("PERKS_PERK_ROBBERY"));
perks.put("SNOWMAN",LanguageConfig.lang.get("PERKS_PERK_SNOWMAN"));
perks.put("DISRUPTOR",LanguageConfig.lang.get("PERKS_PERK_DISRUPTOR"));
perks.put("ENDERMAN", LanguageConfig.lang.get("PERKS_PERK_ENDERMAN"));
perks.put("VAMPIRE", LanguageConfig.lang.get("PERKS_PERK_VAMPIRE"));
perks.put("MARKSMAN", LanguageConfig.lang.get("PERKS_PERK_MARKSMAN"));
perks.put("APOLLO", LanguageConfig.lang.get("PERKS_PERK_APOLLO"));
perks.put("ADRENALINE", LanguageConfig.lang.get("PERKS_PERK_ADRENALINE"));
perkIcons.put("JUGGERNAUT" , Material.DIAMOND_CHESTPLATE);
perkIcons.put("BULLDOZER" , Material.ANVIL);
@@ -0,0 +1,22 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.files.lang.LanguageKey;
import java.util.HashMap;
import java.util.Map;
public class sample {
public static void main(String[] args) {
Map<Integer, Integer> playerPrefs = new HashMap<>();
playerPrefs.put(0, 8);
playerPrefs.put(1, 7);
System.out.println(playerPrefs);
}
}
@@ -0,0 +1,249 @@
package me.lifelessnerd.purekitpvp.scoreboards;
import me.catcoder.sidebar.ProtocolSidebar;
import me.catcoder.sidebar.Sidebar;
import me.catcoder.sidebar.pager.SidebarPager;
import me.lifelessnerd.purekitpvp.files.lang.LanguageConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.DoubleUtils;
import me.lifelessnerd.purekitpvp.utils.PlayerUtils;
import me.lifelessnerd.purekitpvp.versioning.MinecraftVersion;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
public class SidebarScoreboard implements Listener {
Plugin plugin;
public SidebarScoreboard(Plugin plugin) {
this.plugin = plugin;
if (plugin.getConfig().getBoolean("scoreboard-enabled")){
refreshLeaderboard();
}
System.out.println(MinecraftVersion.getVersion());
}
public void refreshLeaderboard() {
Set<Player> players = PlayerUtils.getPlayersInWorld(plugin.getConfig().getString("world"));
List<String> enabled = plugin.getConfig().getStringList("enabled-slides");
ArrayList<Sidebar<Component>> enabledSidebars = new ArrayList<>();
Component titleComponent = LanguageConfig.lang.get("SCOREBOARD_MAIN_TITLE");
for (String panel : enabled) {
switch(panel){
case "GlobalStats":
Sidebar<Component> globalStatsSidebar = ProtocolSidebar.newAdventureSidebar(titleComponent, plugin);
globalStatsSidebar.getObjective().scoreNumberFormatBlank();
fillGlobalSidebar(globalStatsSidebar);
enabledSidebars.add(globalStatsSidebar);
break;
case "PersonalStats":
Sidebar<Component> personalStatsSidebar = ProtocolSidebar.newAdventureSidebar(titleComponent, plugin);
personalStatsSidebar.getObjective().scoreNumberFormatBlank();
fillPersonalSidebar(personalStatsSidebar);
enabledSidebars.add(personalStatsSidebar);
break;
}
}
long period = plugin.getConfig().getInt("scoreboard-period") * 20L;
SidebarPager<Component> pager = new SidebarPager<>(
enabledSidebars, period, plugin);
// add page status line to all sidebars in pager
pager.addPageLine((page, maxPage, sidebar) ->
sidebar.addLine(Component.text("Page " + page + "/" + maxPage).color(NamedTextColor.GREEN)));
for (Player player : players){
pager.show(player);
if (!(plugin.getConfig().getBoolean("scoreboard-enabled"))){
pager.hide(player);
}
}
new BukkitRunnable() {
@Override
public void run() {
if (plugin.getConfig().getBoolean("scoreboard-enabled")){
refreshLeaderboard();
}
pager.destroy();
}
}.runTaskLater(plugin, period * 2);
}
private void fillGlobalSidebar(Sidebar<Component> sidebar) {
int places = plugin.getConfig().getInt("global-stats-place-amount");
List<String> enabled = plugin.getConfig().getStringList("global-stats-components");
sidebar.addLine(LanguageConfig.lang.get("SCOREBOARD_GLOBAL_TITLE"));
for (String component : enabled){
ArrayList<Component> createdLeaderboard = null;
switch(component) {
case "Killstreak":
sidebar.addLine(LanguageConfig.lang.get("SCOREBOARD_GLOBAL_KILLSTREAK"));
createdLeaderboard = createLeaderboard(".killstreak", places);
break;
case "Level":
sidebar.addLine(LanguageConfig.lang.get("SCOREBOARD_GLOBAL_LEVEL"));
createdLeaderboard = createLeaderboard(".level", places);
break;
case "Kills":
sidebar.addLine(LanguageConfig.lang.get("SCOREBOARD_GLOBAL_KILLS"));
createdLeaderboard = createLeaderboard(".kills", places);
break;
case "KD":
sidebar.addLine(LanguageConfig.lang.get("SCOREBOARD_GLOBAL_KD"));
createdLeaderboard = createLeaderboard(".kdratio", places);
break;
default:
plugin.getLogger().warning("Global leaderboard components are wrongly defined! " +
"If you do not want a global scoreboard, change this in the enabled-slides value.");
createdLeaderboard = new ArrayList<>(); // This is empty; only happens when there are no/faulty values defined
break;
}
for (Component line : createdLeaderboard){
sidebar.addUpdatableLine(
(player) -> {
return line;
}
);
}
}
sidebar.updateLinesPeriodically(0, 20);
}
private ArrayList<Component> createLeaderboard(String statKey, int places) {
HashMap<String, Double> leaderboard = new HashMap<>();
Set<String> players = PlayerStatsConfig.get().getKeys(false);
for (String player : players){
double statValue = PlayerStatsConfig.get().getDouble(player + statKey);
leaderboard.put(player, statValue);
}
ArrayList<Component> toBeReturned = new ArrayList<>();
for (int i = 0; i < places; i++) {
double highestScore = 0;
String highestPlayer = null;
for (String player : leaderboard.keySet()) {
if (leaderboard.get(player) > highestScore) {
highestScore = leaderboard.get(player);
highestPlayer = player;
}
}
if (highestPlayer != null) {
highestScore = DoubleUtils.round(highestScore, 2);
if (highestScore % 1 == 0){
int highestScoreInt = (int) highestScore;
toBeReturned.add(Component.text(" " + highestPlayer + " - ", NamedTextColor.GRAY).append(Component.text(highestScoreInt, NamedTextColor.AQUA)));
} else {
toBeReturned.add(Component.text(" " + highestPlayer + " - ", NamedTextColor.GRAY).append(Component.text(highestScore, NamedTextColor.AQUA)));
}
leaderboard.remove(highestPlayer);
}
}
return toBeReturned;
}
private void fillPersonalSidebar(Sidebar<Component> sidebar){
sidebar.addLine(LanguageConfig.lang.get("SCOREBOARD_PERSONAL_TITLE"));
List<String> enabled = plugin.getConfig().getStringList("personal-stats-components");
for (String component : enabled){
switch(component){
case "Killstreak":
sidebar.addUpdatableLine(
(player) -> LanguageConfig.lang.get("SCOREBOARD_PERSONAL_KILLSTREAK").
replaceText(ComponentUtils.replaceConfig("%VALUE%",
PlayerStatsConfig.get().getString(player.getName() + ".killstreak")))
);
break;
case "Kills":
sidebar.addUpdatableLine(
(player) -> LanguageConfig.lang.get("SCOREBOARD_PERSONAL_KILLS").
replaceText(ComponentUtils.replaceConfig("%VALUE%",
PlayerStatsConfig.get().getString(player.getName() + ".kills")))
);
break;
case "Deaths":
sidebar.addUpdatableLine(
(player) -> LanguageConfig.lang.get("SCOREBOARD_PERSONAL_DEATHS").
replaceText(ComponentUtils.replaceConfig("%VALUE%",
PlayerStatsConfig.get().getString(player.getName() + ".deaths")))
);
break;
case "KD":
sidebar.addUpdatableLine(
(player) -> LanguageConfig.lang.get("SCOREBOARD_PERSONAL_KD").
replaceText(ComponentUtils.replaceConfig("%VALUE%",
String.valueOf(DoubleUtils.round(
PlayerStatsConfig.get().getDouble(player.getName() + ".kdratio"), 2)
)))
);
break;
case "Level":
sidebar.addUpdatableLine(
(player) -> LanguageConfig.lang.get("SCOREBOARD_PERSONAL_LEVEL").
replaceText(ComponentUtils.replaceConfig("%VALUE%",
PlayerStatsConfig.get().getString(player.getName() + ".level")))
);
break;
}
}
sidebar.updateLinesPeriodically(0, 20);
}
private HashMap<String, Integer> orderLeaderboard(HashMap<String, Integer> unordered){
HashMap<String, Integer> sortedMap = new HashMap<>();
ArrayList<Integer> list = new ArrayList<>();
for (Map.Entry<String, Integer> entry : unordered.entrySet()) {
list.add(entry.getValue());
}
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer int1, Integer int2) {
return (int1).compareTo(int2);
}
});
for (Integer integer : list) {
for (Map.Entry<String, Integer> entry : unordered.entrySet()) {
if (entry.getValue().equals(integer)) {
sortedMap.put(entry.getKey(), integer);
}
}
}
return sortedMap;
}
}
@@ -0,0 +1,64 @@
//package me.lifelessnerd.purekitpvp.scoreboards;
//
//
//import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
//import me.lifelessnerd.purekitpvp.utils.PlayerUtils;
//import net.kyori.adventure.text.Component;
//import net.minecraft.network.protocol.game.ClientboundTabListPacket;
//import net.minecraft.server.level.ServerPlayer;
//import org.bukkit.Bukkit;
//import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer;
//import org.bukkit.entity.Player;
//import org.bukkit.plugin.Plugin;
//
//import java.util.Set;
//
//
//public class TabManager {
//
// private Plugin plugin;
// private Component header = Component.text("");
// private Component footer = Component.text("");
//
// public TabManager(Plugin plugin) {
// this.plugin = plugin;
// }
// // CURRENTLY NOT IN USE
// public void showTab(){
// if(header == null && footer == null) return;
//
// Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
//
//
// @Override
// public void run() {
//
// // CURRENTLY NOT IN USE
//
// net.minecraft.network.chat.Component headerTBS = ComponentUtils.toMojangComponent(header);
// net.minecraft.network.chat.Component footerTBS = ComponentUtils.toMojangComponent(footer);
//
// ClientboundTabListPacket packet = new ClientboundTabListPacket(headerTBS, footerTBS);
//
// Set<Player> inWorld = PlayerUtils.getPlayersInWorld(plugin.getConfig().getString("world"));
// if (inWorld.size() != 0){
// for (Player player : inWorld){
// CraftPlayer cPlayer = (CraftPlayer) player; // frick nms
// ServerPlayer serverPlayer = cPlayer.getHandle();
// serverPlayer.connection.send(packet);
// }
// }
//
//
// }
// }, 10, plugin.getConfig().getLong("tab-refresh-period"));
//
// }
// // CURRENTLY NOT IN USE
// public void addHeader(Component header){
// this.header = this.header.append(header).appendNewline();
// }
// public void addFooter(Component footer){
// this.footer = this.footer.append(footer).appendNewline();
// }
//}
@@ -1,12 +1,15 @@
package me.lifelessnerd.purekitpvp.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import me.lifelessnerd.purekitpvp.PluginGetter;
import net.kyori.adventure.text.*;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.bukkit.inventory.meta.ItemMeta;
import org.w3c.dom.Text;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -111,4 +114,49 @@ public class ComponentUtils {
toBeAdded.toString()).color(lastColor)).decoration(TextDecoration.ITALIC, false);
return textComponent;
}
public static TextReplacementConfig replaceConfig(String find, String replace){
return replaceConfig(find, replace, 1);
}
public static TextReplacementConfig replaceConfig(String find, String replace, int times){
return TextReplacementConfig.builder().matchLiteral(find).replacement(replace).times(times).build();
}
public static ArrayList<Component> splitComponent(Component massiveComponent){
ArrayList<Component> output = new ArrayList<>();
// System.out.println(massiveComponent);
Component prevChild = Component.text("");
int children = 0;
for (Component child : massiveComponent.iterable(ComponentIteratorType.DEPTH_FIRST, ComponentIteratorFlag.INCLUDE_HOVER_SHOW_ENTITY_NAME)){
try {
TextComponent textChild = (TextComponent) child;
if (child.equals(massiveComponent)) { // DFS through Component will also return itself; now its just its children
continue;
}
if (textChild.content().endsWith("\n")) {
TextComponent replaced = (TextComponent) textChild.replaceText(ComponentUtils.replaceConfig("\n", ""));
prevChild = prevChild.append(replaced).decoration(TextDecoration.ITALIC, false);
output.add(prevChild);
prevChild = Component.text("");
} else {
prevChild = prevChild.append(child);
}
} catch(Exception e){
PluginGetter.Plugin().getLogger().severe(e.toString());
}
children++;
}
if (children == 0){ // Edge case i hate myself
ArrayList<Component> edgeOutput = new ArrayList<>();
edgeOutput.add(massiveComponent.replaceText(ComponentUtils.replaceConfig("\n", "")));
return edgeOutput;
}
return output;
}
}
@@ -27,29 +27,27 @@ public class MyStringUtils {
public static String mapStringToEnchantment(String string){
//I {Enchantment:[minecraft:fire_protection, PROTECTION_FIRE]=4, Enchantment:[minecraft:infinity, INFINITY]=1}
StringBuilder result = new StringBuilder("");
//{CraftEnchantment[minecraft:knockback]=11, CraftEnchantment[minecraft:fire_aspect]=2}
StringBuilder result = new StringBuilder();
StringBuilder builder = new StringBuilder(string);
builder.deleteCharAt(0);
builder.deleteCharAt(string.length() -2);
builder.deleteCharAt(string.length() - 2);
string = builder.toString();
String[] split = string.split("minecraft:");
for (int index = 1; index < split.length; index++){
String word = split[index];
String[] splitAgain = word.split(",");
String levelString = splitAgain[1];
String[] isolateLevel = levelString.split("=");
int level = Integer.parseInt(isolateLevel[isolateLevel.length - 1]); //HERE
word = splitAgain[0];
word = MyStringUtils.itemCamelCase(word);
result.append(word).append(level).append(" ");
String[] split = string.split(",");
for(String substring : split){
substring = substring.trim();
substring = substring.substring(16);
String level = substring.split("=")[1];
String splitEnchantment = substring.split("]")[0];
String enchantment = splitEnchantment.split(":")[1];
result.append(MyStringUtils.itemCamelCase(enchantment)).append(level);
result.append(", ");
}
return result.toString();
//Output: Fire Protection 4, Infinity 1
return result.substring(0, result.length() - 2);
//Output: Knockback 11, Fire Aspect 2
}
public static String itemMetaToEffects(String string){
@@ -0,0 +1,22 @@
package me.lifelessnerd.purekitpvp.utils;
import me.lifelessnerd.purekitpvp.PluginGetter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class PlayerUtils {
public static Set<Player> getPlayersInWorld(String worldName){
Set<Player> players = new HashSet<>();
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld().getName().equalsIgnoreCase(PluginGetter.Plugin().getConfig().getString("world"))) {
players.add(onlinePlayer);
}
}
return players;
}
}
@@ -0,0 +1,25 @@
package me.lifelessnerd.purekitpvp.versioning;
import org.bukkit.Bukkit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MinecraftVersion {
public static String getVersion(){
return extractVersion(Bukkit.getVersion());
}
public static String extractVersion(String input) {
// Define a regular expression pattern to match the version number
Pattern pattern = Pattern.compile("\\b(\\d+\\.\\d+\\.\\d+)\\b");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
return matcher.group(1);
} else {
throw new IllegalArgumentException("No version number found in the input string");
}
}
}
@@ -0,0 +1,38 @@
package me.lifelessnerd.purekitpvp.versioning;
import org.jetbrains.annotations.NotNull;
import static java.lang.Integer.parseInt;
public class Version implements Comparable<Version> {
int major;
int minor;
int build;
public Version(int major, int minor, int build) {
this.major = major;
this.minor = minor;
this.build = build;
}
public Version(String versionString){
// versionString: 1.20.6
String[] split = versionString.split("\\.");
this.major = parseInt(split[0]);
this.minor = parseInt(split[1]);
this.build = parseInt(split[2]);
}
public int getVersionNumber(){
String versionNumber = major + String.valueOf(minor) + build; // hacky
return parseInt(versionNumber);
}
@Override
public int compareTo(@NotNull Version o) {
// TODO
return 0;
}
}
+82 -3
View File
@@ -1,12 +1,25 @@
# PureKitPvP by LifelessNerd
# Made to work with PureKits kit files
# 2022 - 2023
# 2022 - 2024
# World in which the plugin should be active: i.e. kits, deaths, stats and such
world: pvp
# Clear inventory after player is killed, default is true (BETA feature)
inventory-clear: true
# After you are killed, with what delay /kit should automatically be ran (-1 to disable this feature entirely)
auto-kit-delay: 20
#Quick kill when falling in void, only works when suicide-command is enabled
quick-voidkill: true
# Remove any blocks that people in survival/adventure place in your pvp world after a set time
remove-blocks: true
# If above true, delay in seconds after which blocks should automatically be removed
remove-blocks-delay: 30
#If above true, Y level at which you should die in pvp, please provide double (something like 0.0 or -10.0)
voidY: 0.0
@@ -29,29 +42,95 @@ suicide-command: true
# Whether the level of the player should be displayed in front of the message as prefix (only in the enabled world)
level-chat: true
#In loottables, tell the player they got lucky if the drop was below or equal to this percentage
loottable-message-percentage: 1
#Notoriety perk boundary
#If the notoriety perk is too OP, restrict the maximum level of sharpness that can be gained
#Set to -1 if infinite
notoriety-maximum: -1
# Notoriety chance depends on sharpness level already on the item - upgrade chance is (100 - (%DECREASE% * Sharpness Level))
notoriety-chance-decrease: 25
#Marksman perk boundary
#If the marksman perk is too OP, restrict the maximum level of power that can be gained
#Set to -1 if infinite
marksman-maximum: -1
# Marksman chance depends on power level already on the item - upgrade chance is (100 - (%DECREASE% * Power Level))
marksman-chance-decrease: 25
#Default kill effect
default-kill-effect: "firework"
#Default projectile trail
default-projectile-trail: "none"
# If projectile trails should be present on fishing rods (players can be hooked; with trails this is very annoying)
fishing-rod-trail: true
# Projectile trail period delay
# The amount of time between each particle, in ticks (20 ticks = 1 particle per second)
projectile-trail-period: 1
# Projectile trail count
# Amount of particles per spawn (also controlled by projectile-trail-period)
projectile-trail-count: 5
projectile-trail-count: 1
# Chicken prevention: kits with eggs might spawn chicken; when this is true they are prevented from spawning
chicken-prevention: true
chicken-prevention: true
# Global Kit PvP combat event loop
# enabled?
global-event-loop: true
# Seconds between global combat events - events themselves have different times (see below)
global-event-period: 300
# Events that occur in global combat event loop
global-events-enabled: ["TeleMadness","Pickup Frenzy", "Double Health"]
# Event lengths in seconds
telemadness-length: 30
pickup-frenzy-length: 60
double-health-length: 60
# Scoreboard is in BETA; reloading the plugin might not fully reload scoreboard or it might introduce bugs
# When any bugs relating to the scoreboard arise, reloading will most likely solve them.
# If bugs are persistent; report them please -> /purekitpvp info
# NOT WORKING ON 1.20.4!!! Library I depend on is yet to be updated to 1.20.4 - ViaVersion might solve this
# Scoreboard Sidebar - enabled?
scoreboard-enabled: true
# Time between slides in seconds
scoreboard-period: 10
# Slides of the sidebar scoreboard
# Choices: GlobalStats, PersonalStats
enabled-slides:
- GlobalStats
- PersonalStats
# What components of the global stats should be displayed
# Choices: Killstreak, Level, Kills, KD
global-stats-components:
- Killstreak
- Level
- Kills
- KD
# Amount of places for players per component:
# !! If all components above are enabled 2 IS MAX HERE - otherwise stuff wont fit
global-stats-place-amount: 2
# What components of the personal stats should be displayed
# Choices: Killstreak, Level, Kills, KD, Deaths
personal-stats-components:
- Killstreak
- Kills
- Deaths
- KD
- Level
+9 -7
View File
@@ -4,25 +4,27 @@ main: me.lifelessnerd.purekitpvp.PureKitPvP
api-version: 1.19
authors: [ LifelessNerd ]
description: KitPVP plugin, made to work with PureKits kits (abandoned)
softdepend:
- WorldGuard
commands:
getkit:
description: Gives you a kit.
description: Gives you a kit
usage: /getkit <kitName>
kit:
description: Shows kit selection GUI.
description: Shows kit selection GUI
usage: /kit
suicide:
description: Kill yourself in pvp.
description: Kill yourself in pvp
usage: /suicide
getstats:
description: Get the stats of a player.
description: Get the stats of a player
usage: /getstats <player>
aliases:
- stats
- pvpstats
purekitpvp:
description: All admin commands. See documentation for help.
usage: /purekitpvp <createkit/deletekit/kitstats/setkillitem/getcustomitem/createloottable/reload/help/info>
description: All admin commands. See documentation for help
usage: /purekitpvp <createloottable/custommob/event/getcustomitem/help/info/kit/kitstats/reload/resetkit>
aliases:
- kitpvp
- pkpvp
@@ -34,7 +36,7 @@ commands:
- pvphelp
perks:
description: Perk menu
usage: /perk
usage: /perks
aliases:
- perk
cosmetics:
+83 -35
View File
@@ -1,103 +1,151 @@
![\[Banner\]](https://i.imgur.com/tl2TQuw.png)
# PureKitPvP (1.1)
# PureKitPvP (1.3.1)
PureKitPvP lets you create a kit pvp environment quickly, with your own custom kits. These kits work similar to the plugin PureKits, but since that plugin is abandoned, I decided to extend it with other features. A quick overview of all features:
PureKitPvP lets you create a kit pvp environment quickly, with your own custom kits. A quick overview of all features:
- Death Recaps
- Kill Credit on void/environmental damage
- Assist credit
- Tracks Killstreaks, Kills, Deaths and a lot more stats
- Level system based on kills, deaths and assists
- Kits can be made in-game
- Kits can be made in-game, layout customizable per player
- Kits can have a kill item, an item that will be aquired on kill
- Pick only one kit per minecraft life (reset after death)
- Per kit permissions
- Clean Kit GUI
- Clean Kit GUI (multiple pages support)
- Golden Heads (can be set as kit items or/and as kill items)
- Random Loot Chests that can be set as kit item or as kill item
- Create these random loot chests ingame, change percentages in config
- See Kit usage stats for balancing
- Mobs can be used in kits, they despawn when the player has died
- Custom mobs can be created with gear and weapons
- Mob AI only targets enemy players
- Quickly die when falling in the void
- 11 Perks, with GUI selection
- 14 Perks, with GUI selection
- Cosmetics: Projectile Trails, Kill Effect, Kill/Death Message
- Global PvP-related Events
- Customizable language file: most player-visible messages can be changed
## Commands
All commands can be seen in-game via _/purekitpvp help_.
### Admin commands
* **/purekitpvp createkit \<kitName> \<displayColor> \<kitIcon> \<kitPermission> \<killItem>**
* Create a kit with the contents of your inventory
* \<kitIcon> / \<killItem> - _All material names within the autocomplete menu_
* Use _air_ if you don't want a kill item
* **/purekitpvp deletekit\<kitName>**
* Remove a kit
All admin commands are preceded with /purekitpvp.
* **/purekitpvp kit <create/delete/edit/setkillitem>**
* **create** \<kitName> \<displayColor> \<kitIcon> \<kitPermission> \<killItem>
* Create a kit with the contents of your inventory
* \<kitIcon> / \<killItem> - _All material names within the autocomplete menu_
* Use _air_ if you don't want a kill item
* **delete** \<kitName>
* Remove a kit
* **edit** \<kitName>
* Edit a kit's contents in a GUI
* **setkillitem** \<kitName>
* Set the killitem to the item in your hand
* **/purekitpvp resetkit**
* Reset your kit (dying will also reset your kit)
* **/purekitpvp resetkit**
* Resets kit, if the executor has the sufficient permission.
* **/purekitpvp setkillitem \<kitName>**
* Set the killitem to the item in your hand
* **/purekitpvp createloottable \<name> \<lore> \<displayName>**
* **/purekitpvp createloottable** **\<name> \<lore> \<displayName>**
* Create a loottable of the chest you are looking at
* \<lore> - _The lore on the item chest that will be right clicked for the random items_
* \<displayName> -_The displayname on the item chest that will be right clicked for the random items_
* I suggest editing the above values in the loottables config, because multi-line is possible there
* Make sure to follow the format in the loottables config, as YAML can be quite finicky
* **/purekitpvp getcustomitem \<golden_head/random_chest>**
* **/purekitpvp getcustomitem \<golden_head/random_chest/custom_mob_egg>**
* Get the custom item to use in a kit
* \<random_chest> requires a loottable name
* \<custom_mob> requires a custom mob name
* **/purekitpvp custommob \<create/set/delete>**
* **create** \<name> \<type>
* Creates custom mob with a certain type, can be any entity (mobs are officially supported)
* **set** \<name> \<mainhand/offhand/boots/leggings/chestplate/helmet/child>
* Sets a property of a mob to the item in hand, or with the child property; true or false must be specified
* **delete** \<name>
* Deletes a custom mob
* **/purekitpvp event \<start/stop/pause>**
* **start** \<eventName>
* You may only start one event at a time. Timer can be skipped to the end of the event timer.
* **stop** \<eventName>
* Stops current event.
* **pause**
* Pauses the global event loop timer. Events already active stay active. If you want the global event loop to stop, you may disable it in the config, or pause when no event is active to keep any events from triggering.
* **/purekitpvp getkitstats**
* Outputs kit usage stats to see what kit is most popular (for balancing)
* **/purekitpvp help/info/reload**
* Self explanatory
* **/purekitpvp \<help/info/reload>**
* Reload does not fully reload the config file; any settings pertaining to the event loop are not updated, because the event loop is continuous.
### Player commands
* **/kit**
* Show Kit GUI
![\[IMG\]](https://i.imgur.com/JLFvel3.png)
Kits can be customized per player; see video:
Per Player Preferences feature showcase - https://youtu.be/wVQJzBPUlQU
* **/perks**
* Show Perk GUI, click on a slot to change the perk in that slot (see img2)
* Show Perk GUI, click on a slot to change the perk in that slot (see image)
![\[IMG\]](https://i.imgur.com/Yau99d1.png)
![\[IMG\]](https://i.imgur.com/DB81qVL.png)
* **/getkit <kitName>**
* **/cosmetics**
* Brings up cosmetics menu
* In this menu, the kill effect, death/kill message and projectile trail can be changed
* **/getkit \<kitName>**
* Get a kit directly
* **/stats <player>**
* **/stats \<player>**
* Show stats of any player
![enter image description here](https://i.imgur.com/ATOzlVD.png)
* **/suicide**
* Commit suicide (if enabled)
* Enabling this improves accuracy of death messages
## Files
There are several files, most are used internally to track stats and such. The config has some feature toggles that are explained there.
I would recommend not editing the kits.yml unless you know how to check if your YAML is valid, because the file may reset when wrong YAML is parsed.
For the loottables.yml, follow the format that is provided in the example in the file. Write lore bare, and the displayname with single apostrophes (like so: '&6Lootchest').
There are several files, most are used internally to track stats and such. The **config.yml** has some feature toggles that are explained there.
I would recommend not editing the **kits.yml** unless you know how to check if your YAML is valid, because the file may reset when wrong YAML is parsed (don't ask me why).
For the **loottables.yml**, follow the format that is provided in the example in the file. Write lore bare, and the displayname with single apostrophes (like so: '&6Lootchest').
The **lang.yml** file has a plethora of language keys, each of which corresponds with a single or more instances of text in-game. Most text that is visible to a default player - that is a non-admin - is customizable. Item tooltips in GUI's, scoreboard text, all perk explanations et cetera. Be sure to follow the format of each key individually, since some are made for single-line text (such as a display name of an item), and others for multiple lines of lore (think perk explanations). Resetting a value is as easy as deleting it from the file and reloading: missing values are always added back in with their default values. Text that pertains to the kill messages is currently not customizable; the system is not made for this and I question whether the two systems can live side-by-side.
If you have any questions please reach out via Discord (see #Support).
## How to create a kit
*Also see the video that covers this topic below.*
Have all the items you want to be in your kit in your inventory, and type the command. A kit will be created with the arguments and automatically added to the kit menu (/kit). You either provide a kill item in the base command, or, if you want the kill item to be a special item (i.e. a golden head or a random loot chest), use the /purekitpvp getcustomitem command to get that item, and run the command /purekitpvp setkillitem \<kitName> while holding that item.
Have all the items you want to be in your kit in your inventory, and type the command /purekitpvp createkit \<name> . A kit will be created with the arguments and automatically added to the kit menu (/kit). You either provide a kill item in the base command, or, if you want the kill item to be a special item (i.e. a golden head or a random loot chest), use the /purekitpvp getcustomitem command to get that item, and run the command /purekitpvp setkillitem \<kitName> while holding that item.
The contents of the kit will be shown in a clean hoverbox when choosing the kit, which will categorize the first 3 items in your hotbar as weapons, the rest of the inventory as items, the armor as armor and the offhand as offhand. If the kit has no armor, it will tell you aswell. A piece of lore can be set in the kits.yml.
Basic potions that can be found in the inventory are translated as well, although they do not show their potency and lenght, due to how these items work in spigot. Custom potions created with commands however do work perfectly and show potency and lenght, so I recommend to create your own potions with commands when working with them.
## Perks
The perks menu can be brought up using /perks, or via the /kit command. These perks can be changed anytime (so also during combat. Any suggestions on how to forbid this are welcome), and these perks are active at any time. You can have a total of 5 perks active at any time. Perks are activated based on what they do, some active on kill, some during combat etc.
Some configuration is provided in the config, but these perks are not as customizable as the kits and loot tables, due to most perks being quite unlike each other.
There are currently around 11 perks to choose from. Suggestions can be made (see contact info below).
The perks menu can be brought up using /perks, or via the /kit command. These perks can only be changed when the player has not yet chosen a kit. You can have a total of 5 perks actively selected. Perks are activated based on what they do, some active on kill, some during combat etc. Some configuration is provided in the config, but these perks are not as customizable as the kits and loot tables, due to most perks being quite unique.
There are currently around 13 perks to choose from. Suggestions can be made (see contact info below).
## How to create a loot table
*Also see the video that covers this topic below.*
Place a chest and put all items you want to be in your loottable in the chest. The chance of each item will be 0.1 by default. You can change this in the loottables.yml file, but if you want you can just put 2 identical items in the chest if you want the chance to be 0.2. When finished, run the command /purekitpvp createloottable \<name> \<lore> \<displayName>. The lore and displayname are important for the item this loot table with be attached to. Now you may change the chance values of each item in the loottables.yml file. You may also change the lore and displayname to get multi-line text. If guaranteed is set to a true, the plugin will keep cycling through all item of the lootchest until exactly that amount is given. Check if your YAML is valid before reloading the plugin (or back it up), otherwise the file may reset (!). To get the item with the loot table, run the command /purekitpvp getcustomitem random_chest \<loottable> (will auto-complete). With this item in your inventory you can use it in a kit, or set it as kill item.
## Video
https://youtu.be/wZcZ4DcRfgU
Place a chest and put all items you want to be in your loottable in the chest. The chance of each item will be 0.1 by default. You can change this in the loottables.yml file, but if you want you can just put 2 identical items in the chest if you want the chance to be 0.2. When finished, look at the chest and run the command /purekitpvp createloottable \<name> \<lore> \<displayName>. The lore and displayname are important for the item this loot table with be attached to. Now you may change the chance values of each item in the loottables.yml file. You may also change the lore and displayname to get multi-line text. If guaranteed is set to a true, the plugin will keep cycling through all item of the lootchest until exactly that amount is given. Check if your YAML is valid before reloading the plugin (or back it up), otherwise the file may reset (!). To get the item with the loot table, run the command /purekitpvp getcustomitem random_chest \<loottable> (will auto-complete). With this item in your inventory you can use it in a kit, or set it as kill item.
## Known issues
## How to create a custom mob
*Also see the video that covers this topic below.*
Use /purekitpvp custommob create \<name> \<type> to create your mob . All entitytypes are possible, but only monsters are officially supported to work well. After you have created your mob, you can set properties using /purekitpvp custommob set \<property>. You can put equipment on the mob using the property associated with the armor piece - so chestplace or leggings for example. The mob can also be made a baby (if possible for that mob), using the property child, followed by either true or false. Spawning the mob or using it in a kit is simple. Get the spawn egg that spawns the custom mob with /purekitpvp getcustomitem custom_mob_egg /<name>. This will give you a spawn egg, that can be used in kits, loottables and more.
## Videos
https://youtu.be/wZcZ4DcRfgU - Create Kits and Loot tables
https://youtu.be/tLelKptr6wA - Custom Mobs and how to use them
https://youtu.be/wVQJzBPUlQU - Per Player Kit Preferences feature showcase
## Known issues & Support
Issues can be found [here](https://github.com/LifelessNerd/PureKitPvP/issues).
I am sure there will be issues, but finding all of them takes a lot of testing time. Please submit any problems!
If there are any problems, create a message on [Spigot](https://bit.ly/PureKitPvPSpigotMC), add them on GitHub, [here](https://github.com/LifelessNerd/PureKitPvP), or DM me on [Twitter](https://twitter.com/nerdlifeless).
If there are any problems, create a message on [Spigot](https://bit.ly/PureKitPvPSpigotMC), add them on GitHub, [here](https://github.com/LifelessNerd/PureKitPvP), or DM me on [Twitter](https://twitter.com/lukadevrij). For direct support you may also join the support [Discord server](https://discord.com/invite/8n65jSEkVf).