28 Commits
Author SHA1 Message Date
Luka de Vrij 7de536d4b3 1.2? 2023-07-22 16:45:49 +02:00
Luka de Vrij 5488d4d72d Merge branch 'main' of https://github.com/LifelessNerd/PureKitPvP 2023-07-22 00:08:43 +02:00
Luka de Vrij f2d36d9f85 Open chest inventory fix 2023-07-22 00:08:41 +02:00
Luka de Vrij f9d5b687a4 Update GetCustomItem.java
tab update
2023-07-19 23:58:29 +02:00
Luka de Vrij 3df3dfb0c9 +2 kill effects 2023-07-18 21:34:45 +02:00
Luka de Vrij e3a83fe225 KitsGUI permissions + config add
also warning of world plugin is active in on stratup
2023-07-17 22:52:15 +02:00
Luka de Vrij df8c74ac09 bugfixes. small additions
The big Un-italicizing of 2023
Projectile trail for arrows
ChickenPreventer for eggs
Child addition to custom mobs via commands
2023-07-16 23:17:53 +02:00
Luka de Vrij 6fc21c8229 draft voor page 2 van kits 2023-07-15 23:53:29 +02:00
Luka de Vrij 4470a4ea21 KillMessages
en taffes veel bug fixes
2023-07-12 00:01:55 +02:00
Luka de Vrij 56653d938d 1.20.1 paper + camel fix
1.20.1
2023-07-10 22:55:08 +02:00
Luka 10814c981a Kill Message WIP + fixes/minor features
Level in chat
Projectile Trails
Kill Message WIP
Auto-/kit on death
2023-06-19 23:25:49 +02:00
Luka 610e102c08 KillEffects done
Golden head bug fix
2023-06-17 23:24:59 +02:00
Luka 614deac7da bugfixes
- Adrenaline no longer interferes with Scout
- Golden Head as Killitem now has ItemMeta aswell; making it functional
2023-05-26 22:34:08 +02:00
Luka 19b017f7f0 kleine go back button 2023-05-15 23:23:29 +02:00
Luka f0087503f1 fall damage bug fixed, cosmetics progress 2023-05-14 23:28:14 +02:00
Luka d71ebdc54e new perks and shit 2023-05-13 23:31:58 +02:00
Luka e7e6348ebe new perk?
needs testing
2023-05-12 23:14:49 +02:00
Luka 2de2c502b0 Zombie and skeleton mobs work 2023-05-12 18:06:39 +02:00
Luka 7ba4ef1063 extra perks + kleine patch 2023-05-09 23:12:54 +02:00
Luka 6bbab07bb5 patch
perk balancing
snowballs geven poison/snowballs fixed
assist op zelf is niet meer mogelijk
death xp naar 0
2023-05-07 22:54:36 +02:00
Luka daea1242a0 untested - cosmetics inventories 2023-04-19 23:50:40 +02:00
Luka 35c7f54e31 Cosmetics - nog geen menu - enkel samples 2023-04-18 23:13:16 +02:00
Luka 2685c1570a draft for cosmetics 2023-04-17 23:59:04 +02:00
Luka d33408169e niets eigenlijk 2023-02-07 23:57:44 +01:00
Luka c64a63a02c Perks exploit fixed + custom mobs implemented
The custom mobs command is still full of NPE's tho
2023-01-31 23:42:03 +01:00
Luka 06b8b36042 tabcomplete command 2023-01-30 23:18:13 +01:00
Luka 6e69f1b06f command finalized 2023-01-29 23:11:45 +01:00
Luka ee3886a162 CustomMob basic command draft + target behaviour is mediocre but functional 2023-01-27 23:35:46 +01:00
57 changed files with 2410 additions and 293 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" />
</component>
</module>
+13
View File
@@ -0,0 +1,13 @@
<?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
@@ -0,0 +1,7 @@
<?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
@@ -0,0 +1,30 @@
<?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
@@ -0,0 +1,19 @@
<?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
@@ -0,0 +1,8 @@
<?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
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+13
View File
@@ -0,0 +1,13 @@
<?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>
+4 -4
View File
@@ -6,12 +6,12 @@
<groupId>me.lifelessnerd.purekitpvp</groupId>
<artifactId>PureKitPvP</artifactId>
<version>1.1</version>
<version>1.2</version>
<packaging>jar</packaging>
<name>PureKitPvP</name>
<description>PureKits fork, customised</description>
<description>Full KitPvP experience, customizable kits and items</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -55,7 +55,7 @@
<repositories>
<repository>
<id>papermc-repo</id>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
@@ -68,7 +68,7 @@
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<version>1.20.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -1,6 +1,7 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkLib;
import me.lifelessnerd.purekitpvp.custommobs.CustomMobCommand;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import me.lifelessnerd.purekitpvp.createKit.*;
import me.lifelessnerd.purekitpvp.customitems.GetCustomItem;
import me.lifelessnerd.purekitpvp.customitems.loottablelogic.CreateLootTable;
@@ -12,26 +13,31 @@ 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.entity.*;
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;
import java.util.function.Consumer;
import static org.bukkit.Bukkit.getPlayer;
import static org.bukkit.Bukkit.getServer;
public class AdminCommandManager implements TabExecutor {
ArrayList<Subcommand> subcommands = new ArrayList<>();
Plugin plugin;
public AdminCommandManager(Plugin plugin){
public AdminCommandManager(Plugin plugin) {
subcommands.add(new CreateKit(plugin));
subcommands.add(new DeleteKit(plugin));
subcommands.add(new ResetKit());
subcommands.add(new SetKillItem(plugin));
subcommands.add(new SetPerk(plugin));
//subcommands.add(new SetPerk(plugin));
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());
@@ -42,25 +48,25 @@ 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)){
if (!(sender instanceof Player)) {
sender.sendMessage("The console cannot perform these commands.");
return false;
}
Player player = (Player) sender;
if(!(player.hasPermission("purekitpvp.admin.*"))){
if (!(player.hasPermission("purekitpvp.admin.*"))) {
player.sendMessage(ChatColor.RED + "You do not have permission!");
return true;
}
if (args.length < 1){
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())){
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
}
@@ -72,112 +78,93 @@ public class AdminCommandManager implements TabExecutor {
}
public ArrayList<Subcommand> getSubcommands(){
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) {
if (args.length == 1) {
List<String> arguments = new ArrayList<>();
for (Subcommand subcommand : subcommands){
for (Subcommand subcommand : subcommands) {
arguments.add(subcommand.getName());
}
return arguments;
}
if (args[0].equalsIgnoreCase("getcustomitem")){
if (args[0].equalsIgnoreCase("getcustomitem")) {
if (args[1].equalsIgnoreCase("random_chest")){
if (args[1].equalsIgnoreCase("random_chest")) {
List<String> arguments = new ArrayList<>(LootTablesConfig.get().getKeys(false));
return arguments;
} else if (args[1].equalsIgnoreCase("golden_head")) {
return new ArrayList<>();
} else if (args[1].equalsIgnoreCase("custom_mob_egg")) {
return new ArrayList<>(MobSpawnConfig.get().getKeys(false));
}
else if (args[1].equalsIgnoreCase("golden_head")){
if (args.length > 3) {
return new ArrayList<>();
}
List<String> arguments = new ArrayList<>();
arguments.add("random_chest");
arguments.add("golden_head");
arguments.add("custom_mob_egg");
return arguments;
}
if (args[0].equalsIgnoreCase("createloottable")){
if (args[0].equalsIgnoreCase("createloottable")) {
if (args.length == 2){
if (args.length == 2) {
List<String> arguments = new ArrayList<>();
arguments.add("<name>");
return arguments;
}
if (args.length == 3){
if (args.length == 3) {
List<String> arguments = new ArrayList<>();
arguments.add("<lore>");
return arguments;
}
if (args.length == 4){
if (args.length == 4) {
List<String> arguments = new ArrayList<>();
arguments.add("<displayName>");
return arguments;
}
}
if (args[0].equalsIgnoreCase("setkillitem")){
if (args[0].equalsIgnoreCase("setkillitem")) {
if (args.length == 2){
if (args.length == 2) {
List<String> autoComplete = new ArrayList<>();
for(String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)){
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
};
}
;
return autoComplete;
}
}
if (args[0].equalsIgnoreCase("setperk")){
if (args[0].equalsIgnoreCase("deletekit")) {
if (args.length == 2){ //kit
if (args.length == 2) {
List<String> autoComplete = new ArrayList<>();
for(String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)){
for (String key : KitConfig.get().getConfigurationSection("kits.").getKeys(false)) {
key = key.toLowerCase();
autoComplete.add(key);
};
autoComplete.add("all");
return autoComplete;
}
if (args.length == 3){ //perk
List<String> autoComplete = new ArrayList<>();
PerkLib perkLib = new PerkLib();
for(String perkName : perkLib.perks.keySet()){
autoComplete.add(perkName.toLowerCase());
};
autoComplete.add("all");
return autoComplete;
}
if (args.length == 4){ //true/false
List<String> autoComplete = new ArrayList<>();
autoComplete.add("true");
autoComplete.add("false");
}
;
return autoComplete;
}
}
if (args[0].equalsIgnoreCase("deletekit")){
if (args[0].equalsIgnoreCase("createkit")) {
if (args.length == 2){
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("createkit")){
if (args.length == 2){
if (args.length == 2) {
List<String> arguments = new ArrayList<>();
arguments.add("<kitName>");
return arguments;
}
if (args.length == 3){
if (args.length == 3) {
List<String> arguments = new ArrayList<>();
arguments.add("&1");
arguments.add("&2");
@@ -192,23 +179,77 @@ public class AdminCommandManager implements TabExecutor {
return arguments;
}
if (args.length == 4){
if (args.length == 4) {
KitIcon kitIconLib = new KitIcon();
return Arrays.asList(kitIconLib.materialList);
}
if (args.length == 5){
if (args.length == 5) {
List<String> arguments = new ArrayList<>();
arguments.add("kit.other");
return arguments;
}
if (args.length == 6){
if (args.length == 6) {
KitIcon kitIconLib = new KitIcon();
return Arrays.asList(kitIconLib.materialList);
}
}
if (args[0].equalsIgnoreCase("custommob")) {
if (args.length == 2) {
List<String> arguments = new ArrayList<>();
arguments.add("create");
arguments.add("set");
arguments.add("delete");
return arguments;
}
if (args[1].equalsIgnoreCase("create")) {
if (args.length == 3) {
List<String> arguments = new ArrayList<>();
arguments.add("<identifier>");
return arguments;
}
if (args.length == 4) {
List<EntityType> entities = Arrays.asList(EntityType.values());
ArrayList<String> arguments = new ArrayList<>();
// AAAH LAMBDA IN JAVA? sure
Consumer<EntityType> method = (entityType) -> {
Entity entity;
try {
// This is stupid, only reason i am keeping this here is because it won't run that often
entity = getServer().getWorlds().get(0).spawnEntity(getServer().getWorlds().get(0).getSpawnLocation(), entityType);
if (entity instanceof Monster) {
arguments.add(entityType.toString().toLowerCase());
}
entity.remove();
} catch(Exception e){
// System.out.println(entityType);
}
};
entities.forEach(method);
return arguments;
}
}
if (args[1].equalsIgnoreCase("set")) {
if (args.length == 3) {
return new ArrayList<>(MobSpawnConfig.get().getKeys(false));
}
if (args.length == 4) {
String[] possibleArgs = {"helmet", "chestplate", "leggings", "boots", "mainhand", "offhand", "child"};
return Arrays.asList(possibleArgs);
}
if (args.length == 5){
if (args[3].equalsIgnoreCase("child")){
String[] possibleArgs = {"true", "false"};
return Arrays.asList(possibleArgs);
}
}
}
if (args.length == 3) {
return new ArrayList<>(MobSpawnConfig.get().getKeys(false));
}
}
return new ArrayList<>();
}
}
@@ -1,6 +1,7 @@
package me.lifelessnerd.purekitpvp;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@@ -55,11 +56,6 @@ public class AdminHelpCommand extends Subcommand {
if (args[1].equalsIgnoreCase("2")){
if (!(player.hasPermission("purekitpvp.admin.*"))){
player.sendMessage("No permission!");
return true;
}//Obsolete, any AdminCommandManager subcommands require admin perm
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&bPureKitPvP - Admin Commands"));
for (Subcommand subcommand : subcommands){
String message =
@@ -4,6 +4,8 @@ import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class InfoCommand extends Subcommand{
@Override
public String getName() {
return "info";
@@ -29,11 +31,11 @@ public class InfoCommand extends Subcommand{
String message =
"""
&bPureKitPvP - version 1.1
&bPureKitPvP - version 1.2
&6SpigotMC: &ohttps://bit.ly/PureKitPvPSpigotMC
&6Github: &ohttps://github.com/LifelessNerd/PureKitPvP
&6Developer: &ohttps://twitter.com/NerdLifeless
&rIf you have any problems, bugs or glitches, reach out to me via any of the links above.
&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));
@@ -0,0 +1,17 @@
package me.lifelessnerd.purekitpvp;
import org.bukkit.plugin.Plugin;
public class PluginGetter {
static Plugin plugin;
public PluginGetter(Plugin plugin) {
PluginGetter.plugin = plugin;
}
public static Plugin Plugin(){
return plugin;
}
}
@@ -1,9 +1,17 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.combathandlers.PearlListener;
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.VoidKiller;
import me.lifelessnerd.purekitpvp.combathandlers.mobhandler.OnPlayerSpawnMob;
import me.lifelessnerd.purekitpvp.combathandlers.killhandler.DeathHandler;
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;
@@ -22,7 +30,7 @@ public final class PureKitPvP extends JavaPlugin {
@Override
public void onEnable() {
getLogger().info("Enabled PureKitPvP");
getConfig().options().copyDefaults();
saveDefaultConfig();
@@ -50,11 +58,18 @@ public final class PureKitPvP extends JavaPlugin {
LootTablesConfig.get().options().copyDefaults(true);
LootTablesConfig.save();
MobSpawnConfig.setup();
MobSpawnConfig.get().options().copyDefaults(true);
MobSpawnConfig.save();
PlayerStatsConfig.setup();
PlayerStatsConfig.get().options().copyDefaults(true);
PlayerStatsConfig.save();
PerkFireHandler perkFireHandler = new PerkFireHandler(this);
CosmeticsConfig.setup();
CosmeticsConfig.get().options().copyDefaults(true);
CosmeticsConfig.save();
getCommand("getkit").setExecutor(new GetKit(this));
getCommand("kit").setExecutor(new KitsGUI(this));
getCommand("perk").setExecutor(new PerkCommand(this));
@@ -62,6 +77,7 @@ public final class PureKitPvP extends JavaPlugin {
getCommand("getstats").setExecutor(new GetStats(this));
getCommand("purekitpvphelp").setExecutor(new HelpCommand());
getCommand("purekitpvp").setExecutor(new AdminCommandManager(this));
getCommand("cosmetics").setExecutor(new CosmeticsCommand(this));
getServer().getPluginManager().registerEvents(new GetKit(this), this);
getServer().getPluginManager().registerEvents(new GUIListener(this), this);
getServer().getPluginManager().registerEvents(new PerkGUIListener(this), this);
@@ -73,10 +89,28 @@ public final class PureKitPvP extends JavaPlugin {
getServer().getPluginManager().registerEvents(new OpenRandomChest(this), this);
getServer().getPluginManager().registerEvents(new OnPlayerSpawnMob(this), this);
getServer().getPluginManager().registerEvents(new PearlListener(this), this);
getServer().getPluginManager().registerEvents(new HealthEvents(this), this);
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 CosmeticsGUIListener(this), this);
getServer().getPluginManager().registerEvents(new KillEffect(this), this);
getServer().getPluginManager().registerEvents(new KillEffectInventory(this), this);
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.");
}
@Override
public void onDisable() {
getLogger().info("Goodbye!");
}
}
@@ -1,9 +1,6 @@
package me.lifelessnerd.purekitpvp;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.KitStatsConfig;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.files.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@@ -39,17 +36,28 @@ public class ReloadPlugin extends Subcommand {
@Override
public boolean perform(Player player, String[] args) {
//TODO Reload should read the files, even if they are manually edited, and load them into the plugin
// NO WORKIE
KitConfig.reload();
KitConfig.save();
KitStatsConfig.reload();
KitStatsConfig.save();
LootTablesConfig.reload();
LootTablesConfig.save();
PlayerStatsConfig.reload();
PlayerStatsConfig.save();
PerkData.reload();
PerkData.save();
MobSpawnConfig.reload();
MobSpawnConfig.save();
CosmeticsConfig.reload();
CosmeticsConfig.save();
plugin.reloadConfig();
plugin.getConfig();
plugin.saveConfig();
@@ -1,5 +1,6 @@
package me.lifelessnerd.purekitpvp;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
@@ -0,0 +1,35 @@
package me.lifelessnerd.purekitpvp.combathandlers;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.plugin.Plugin;
public class ChickenPrevention implements Listener {
public Plugin plugin;
public ChickenPrevention(Plugin plugin){
this.plugin = plugin;
}
@EventHandler
public void onChickenSpawn(EntitySpawnEvent event) {
if (!(plugin.getConfig().getBoolean("chicken-prevention"))){
return;
}
Entity spawned = event.getEntity();
if (!(spawned.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (spawned.getType().equals(EntityType.CHICKEN)){
event.setCancelled(true);
}
}
}
// This class prevents chicken from spawning -> some kits may have eggs for combo material, they would spawn chicken, not anymore
@@ -0,0 +1,48 @@
package me.lifelessnerd.purekitpvp.combathandlers;
import me.lifelessnerd.purekitpvp.perks.perkfirehandler.PerkFireHandler;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.plugin.Plugin;
public class HealthEvents implements Listener {
public static Plugin plugin;
public HealthEvents(Plugin plugin){
HealthEvents.plugin = plugin;
}
@EventHandler
public void onHealthRegen(EntityRegainHealthEvent event){
if (!(event.getEntity() instanceof Player)){
return;
}
Player player = (Player) event.getEntity();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
PerkFireHandler.fireHealthPerks(player);
}
@EventHandler
public void onEntityDamage(EntityDamageEvent event){
if (!(event.getEntity() instanceof Player)){
return;
}
Player player = (Player) event.getEntity();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
PerkFireHandler.fireHealthPerks(player);
}
}
@@ -5,11 +5,13 @@ 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;
import org.spigotmc.event.entity.EntityDismountEvent;
public class PearlListener implements Listener {
@@ -33,7 +35,13 @@ public class PearlListener implements Listener {
PerkFireHandler.fireEnderpearlPerks(player, event);
}
@EventHandler
public void onDismount(EntityDismountEvent e) {
if(e.getDismounted() instanceof EnderPearl) {
e.getDismounted().remove();
}
}
}
@@ -0,0 +1,42 @@
package me.lifelessnerd.purekitpvp.combathandlers;
import me.lifelessnerd.purekitpvp.PureKitPvP;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerAttemptPickupItemEvent;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
public class PickupListener implements Listener {
Plugin plugin;
public PickupListener(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onItemPickup(PlayerAttemptPickupItemEvent e){
Player player = e.getPlayer();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
Item itemOnGround = e.getItem();
PersistentDataContainer itemContainer = itemOnGround.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(plugin, "cosmetic");
if (itemContainer.get(key, PersistentDataType.BOOLEAN) == null){
return;
}
if (!(itemContainer.get(key, PersistentDataType.BOOLEAN))){ //lies
return;
}
e.setCancelled(true);
}
}
@@ -1,8 +1,10 @@
package me.lifelessnerd.purekitpvp.combathandlers.killhandler;
import me.lifelessnerd.purekitpvp.combathandlers.PlayerLeveling;
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.perks.perkfirehandler.PerkFireHandler;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
@@ -26,6 +28,7 @@ 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.util.ArrayList;
import java.util.HashMap;
@@ -33,6 +36,13 @@ import java.util.logging.Level;
public class DeathHandler implements Listener {
// To whoever sees this; I profoundly apologise: this code is garbage
// It hangs together with duct tape and iterative bug fixes everywhere
// I should really redesign or at least clean up this class
// But I feel like I would just make it worse; so I probably won't ever do that
// good luck trying to read what is going on
// You can ping me, but I won't probably know either
Plugin plugin;
public DeathHandler(Plugin plugin) {
@@ -55,13 +65,21 @@ public class DeathHandler implements Listener {
Bukkit.getScheduler().runTaskLater((Plugin)this.plugin, () ->
player.teleport(new Location(player.getWorld(), x, y, z, 0, 0)), 1L);
Bukkit.getScheduler().runTaskLater((Plugin)this.plugin, () ->
player.setHealth(20), 2L);
player.getInventory().clear();
player.getActivePotionEffects().clear();
player.setExp(0f);
player.setLevel(0);
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 5, 254)); //Kinda jank, works tho
Bukkit.getScheduler().runTaskLater((Plugin)this.plugin, () -> {
player.getInventory().clear();
player.getActivePotionEffects().clear();
player.setExp(0f);
player.setLevel(0);
player.setArrowsInBody(0);
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 5, 254)); //Kinda jank, works tho
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);
DamageCauseLib damageCauseLib = new DamageCauseLib();
@@ -72,7 +90,7 @@ public class DeathHandler implements Listener {
String message = "&c&lYou died!";
player.sendMessage(ChatColor.translateAlternateColorCodes('&',message));
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&7Death Recap:"));
// Printing process and formatting
int totalDamageDone = 0;
for (String hashmapKey : damageData.damageDistributionMap.keySet()){
totalDamageDone += damageData.damageDistributionMap.get(hashmapKey);
@@ -96,38 +114,47 @@ public class DeathHandler implements Listener {
}
//Broadcasting and stuff
// use 'lastPlayerBlow' to determine kill message and such
String deathMessage = player.getName();
String credit = " was killed by a mysterious force";
String deathMessage = "";
String lastEnvironmentHit;
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
lastEnvironmentHit = damageData.lastOtherDamager;
credit = damageCauseLib.deathMessages.get(lastEnvironmentHit);
deathMessage = KillMessage.create.byEnvironment(player.getName(), lastEnvironmentHit);
playerInvolved = false;
}
if (damageData.lastPlayerDamager != null && damageData.lastOtherDamager != null){
//This means player got damage from both
credit = damageData.lastPlayerDamager;
deathMessage += " was killed by ";
// 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);
} else {
deathMessage = KillMessage.create.byEnvironmentAndPlayer(player.getName(), damageData.lastPlayerDamager, damageData.lastOtherDamager);
}
}
if (damageData.lastPlayerDamager != null && damageData.lastOtherDamager == null){
//Means player has only been hit by other players
credit = damageData.lastPlayerDamager;
deathMessage += " was killed by ";
deathMessage = KillMessage.create.byPlayer(player.getName(), damageData.lastPlayerDamager);
}
deathMessage = deathMessage + credit;
// deathMessage = deathMessage + credit;
// Death message shows who got credit, broadcast to every player in pvp world
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (onlinePlayer.getWorld() == player.getWorld()) {
@@ -152,7 +179,9 @@ public class DeathHandler implements Listener {
String highestAssistor = null;
for (String key2 : damageData.damageDistributionMap.keySet()){
if (!(key2.equalsIgnoreCase(credit)) && pvpPlayers.contains(key2)){ // Dont count the killer in the assist check
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
//Only check players for assist
if (highestAssistor == null){
highestAssistor = key2;
@@ -176,10 +205,6 @@ public class DeathHandler implements Listener {
player.getPersistentDataContainer().remove(key);
player.setFireTicks(0);
player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 5, 1));
player.addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 10 , 1));
//Sound effects and such
player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_HURT, 1,0);
@@ -212,8 +237,8 @@ public class DeathHandler implements Listener {
//update level
PlayerLeveling.createLevelXPPath(player.getName());
PlayerLeveling.addExperience(player, 1, "Death"); // 1 for DEATH
PlayerLeveling.updateLevels();
// PlayerLeveling.addExperience(player, 1, "Death"); // 1 for DEATH// Ah no: can be exploited
// PlayerLeveling.updateLevels();
//remove any mobs player spawned
MobRemover.removeMobs(player);
@@ -265,7 +290,7 @@ public class DeathHandler implements Listener {
if (creditStats.getInt(creditPlayer.getName() + ".killstreak") >= 5) {
int duration = plugin.getConfig().getInt("killstreak-glowing-duration");
creditPlayer.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, duration * 20, 2));
creditPlayer.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, duration * 20, 2, true, false));
}
}
@@ -298,6 +323,8 @@ public class DeathHandler implements Listener {
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);
}
@@ -308,7 +335,8 @@ public class DeathHandler implements Listener {
//PerkHandler
PerkFireHandler.fireKillPerks(creditPlayer);
//The killcosmetic that the creditPlayer has fires
KillEffect.fireKillCosmetic(player, creditPlayer);
} else {
@@ -341,7 +369,8 @@ public class DeathHandler implements Listener {
assistor.sendActionBar(actionBarText);
//update level
//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();
@@ -358,8 +387,6 @@ public class DeathHandler implements Listener {
}
}
}
@@ -367,7 +394,11 @@ public class DeathHandler implements Listener {
public void onPlayerCombatHit(EntityDamageByEntityEvent event){
Player player = null;
Player damager = null;
// HAND TO HAND COMBAT
// 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
return;
} // This function should make all other copies obsolete - removed all affected copies (I think)
if (event.getDamager() instanceof Player && event.getEntity() instanceof Player) {
@@ -382,34 +413,44 @@ public class DeathHandler implements Listener {
PerkFireHandler.fireCombatPerks(player, damager);
PerkFireHandler.fireVampirePerk(event);
} else if (event.getDamager() instanceof Arrow && event.getEntity() instanceof Player) {
} 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
//Projectile combat
player = (Player) event.getEntity();
Arrow arrow = (Arrow) event.getDamager();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
if(((AbstractArrow) event.getDamager()).getShooter() instanceof Player){
player = (Player) event.getEntity();
if (event.getDamager() instanceof Arrow) {
Arrow arrow = (Arrow) event.getDamager();
damager = (Player) arrow.getShooter();
} else {
SpectralArrow arrow = (SpectralArrow) event.getDamager();
damager = (Player) arrow.getShooter();
}
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();
Monster skeleton = (Monster) ((AbstractArrow) event.getDamager()).getShooter();
String mobName = skeleton.getName();
damager = Bukkit.getPlayerExact(mobName.split("'s")[0]);
damager = (Player) arrow.getShooter();
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 ThrownPotion && event.getEntity() instanceof Player){
//Splash potion threw (only potions that do damage, only those are seen by this event)
player = (Player) event.getEntity();
ThrownPotion potion = (ThrownPotion) event.getDamager();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
damager = (Player) potion.getShooter(); //works
double damage = event.getDamage();
double playerHP = player.getHealth() - damage;
@@ -421,14 +462,10 @@ public class DeathHandler implements Listener {
} else if (event.getDamager() instanceof Trident && event.getEntity() instanceof Player){
//Splash potion threw (only potions that do damage, only those are seen by this event)
//Trident
player = (Player) event.getEntity();
Trident trident = (Trident) event.getDamager();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))){
return;
}
damager = (Player) trident.getShooter(); //works
double damage = event.getDamage();
double playerHP = player.getHealth() - damage;
@@ -438,8 +475,27 @@ public class DeathHandler implements Listener {
damager.sendMessage(ChatColor.translateAlternateColorCodes(
'&', "&a" + player.getName() + " &cis on &a" + (int) playerHP + " &cHP."));
} else {
} else if (event.getDamager() instanceof Monster && event.getEntity() instanceof Player) {
String mobName = event.getDamager().getName();
damager = Bukkit.getPlayerExact(mobName.split("'s")[0]);
player = ((Player) event.getEntity()).getPlayer();
} else if (event.getDamager() instanceof EnderPearl && event.getEntity() instanceof Player) {
PerkFireHandler.fireEnderpearlDamagePerks((Player) event.getEntity(), event);
return;
}
else if (event.getDamager() instanceof Firework && event.getEntity() instanceof Player){
Firework fw = (Firework) event.getDamager();
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;
}
@@ -487,7 +543,6 @@ public class DeathHandler implements Listener {
//Put the edited object back in the player
player.getPersistentDataContainer().set(key, new PlayerDamageDistributionDataType(), pulledPlayerData);
}
@EventHandler
@@ -514,14 +569,40 @@ public class DeathHandler implements Listener {
}
if (event.getCause() == EntityDamageEvent.DamageCause.MAGIC){
return;
}
int damageAmount = (int) event.getDamage();
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){
Location fallLocation = player.getLocation();
// - 0.5 because block and player location are off by 0.5 because Minecraft
double minX = plugin.getConfig().getDouble("respawnX") - 0.5 - plugin.getConfig().getInt("spawn-radius");
double maxX = plugin.getConfig().getDouble("respawnX") - 0.5 + plugin.getConfig().getInt("spawn-radius");
double minZ = plugin.getConfig().getDouble("respawnZ") - 0.5 - plugin.getConfig().getInt("spawn-radius");
double maxZ = plugin.getConfig().getDouble("respawnZ") - 0.5 + plugin.getConfig().getInt("spawn-radius");
if(fallLocation.getBlockX() >= minX && fallLocation.getBlockX() <= maxX){
if(fallLocation.getBlockZ() >= minZ && fallLocation.getBlockZ() <= maxZ) { // If inside spawn square
// event.setDamage(0);
event.setCancelled(true); //might have other implications - none found
return;
}
}
}
// 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) {
if (fw.hasMetadata("nodamage")) {
event.setCancelled(true);
return;
}
}
}
//If player has just started combat, make a dataContainer with the empty object above
NamespacedKey key = new NamespacedKey(plugin, "damageDistributionInfo");
@@ -577,7 +658,7 @@ public class DeathHandler implements Listener {
shooter = (Player) event.getEntity().getShooter();
PerkFireHandler.fireSnowballPerks(player, shooter);
PerkFireHandler.fireSnowballPerks(event, player, shooter);
}
else {
@@ -0,0 +1,35 @@
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;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.plugin.Plugin;
public class PlayerLevelChat implements Listener {
public Plugin plugin;
public PlayerLevelChat(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerChat(AsyncPlayerChatEvent event){
// Some shenanigans regarding async, but should be fine for this use case
if (!(plugin.getConfig().getBoolean("level-chat"))){
return;
}
Player player = event.getPlayer();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
event.setFormat("[" + PlayerStatsConfig.get().getString(player.getName() + ".level") + "] " + event.getFormat());
}
}
@@ -1,4 +1,4 @@
package me.lifelessnerd.purekitpvp.combathandlers;
package me.lifelessnerd.purekitpvp.combathandlers.leveling;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import org.bukkit.Bukkit;
@@ -36,6 +36,7 @@ public class DamageCauseLib {
deathMessages.put("DRYOUT"," had no more water");
deathMessages.put("FREEZE"," froze to death");
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");
@@ -64,6 +65,7 @@ public class DamageCauseLib {
damageCauseTranslations.put("DRYOUT"," Dryout");
damageCauseTranslations.put("FREEZE"," Freezing");
damageCauseTranslations.put("SONIC_BOOM"," Warden");
damageCauseTranslations.put("MONSTER"," Custom Mob");
}
}
@@ -0,0 +1,48 @@
package me.lifelessnerd.purekitpvp.combathandlers.libs;
import java.util.ArrayList;
import java.util.HashMap;
public class DeathCauseLib {
public HashMap<String, String> defaultDeathMessages = new HashMap<>();
public ArrayList<String> defaultKillMessages = new ArrayList<>();
public HashMap<String, String> flexDeathMessages = new HashMap<>();
public ArrayList<String> flexKillMessages = new ArrayList<>();
public HashMap<String, String> nerdDeathMessages = new HashMap<>();
public ArrayList<String> nerdKillMessages = new ArrayList<>();
public DeathCauseLib() {
defaultDeathMessages.put("VOID", " was thrown into the void by {killer}");
defaultDeathMessages.put("LAVA", " jumped into lava trying to escape {killer}");
defaultDeathMessages.put("FIRE", " stood in fire trying to escape {killer}");
defaultDeathMessages.put("FIRE_TICK", " burnt to a crisp trying to escape {killer}");
defaultDeathMessages.put("ENTITY_EXPLOSION", " exploded trying to escape {killer}");
defaultDeathMessages.put("FALL", " fell off a cliff trying to escape {killer}");
defaultKillMessages.add(" was killed by {killer}");
flexDeathMessages.put("VOID", " was yeeted into the void by {killer}");
flexDeathMessages.put("LAVA", " jumped in lava, he couldn't kill {killer}");
flexDeathMessages.put("FIRE", " stood in fire trying to escape {killer}");
flexDeathMessages.put("FIRE_TICK", " burnt to a crisp trying to escape {killer}");
flexDeathMessages.put("ENTITY_EXPLOSION", " exploded trying to escape {killer}");
flexDeathMessages.put("FALL", " was thrown off a cliff by {killer}");
flexKillMessages.add(" became kill #{kills} of {killer}");
nerdDeathMessages.put("VOID", " was thrown into the void by {killer}");
nerdDeathMessages.put("LAVA", " jumped into lava trying to escape {killer}");
nerdDeathMessages.put("FIRE", " stood in fire trying to escape {killer}");
nerdDeathMessages.put("FIRE_TICK", " burnt to a crisp trying to escape {killer}");
nerdDeathMessages.put("ENTITY_EXPLOSION", " exploded trying to escape {killer}");
nerdDeathMessages.put("FALL", " thought this was Borderlands, being chased by {killer}");
nerdKillMessages.add(" was Ctrl+Alt+Deleted by {killer}");
}
}
@@ -37,7 +37,7 @@ public class Suicide implements CommandExecutor {
}
player.teleport(new Location(player.getWorld(),
player.getLocation().getX(),
plugin.getConfig().getDouble("voidY") - 150.0,
plugin.getConfig().getDouble("voidY"),
player.getLocation().getY()
));
@@ -1,25 +1,34 @@
package me.lifelessnerd.purekitpvp.combathandlers.mobhandler;
import me.lifelessnerd.purekitpvp.PluginGetter;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.*;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
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;
@@ -39,30 +48,86 @@ public class OnPlayerSpawnMob implements Listener {
return;
}
if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK || e.getAction() == Action.RIGHT_CLICK_AIR)) {
if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK)) {
return;
}
Component itemDisplayName = player.getInventory().getItemInMainHand().displayName();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
String itemName = serializer.serialize(itemDisplayName);
if (!(itemName.contains("Spawn Egg"))) {
if (!(player.getInventory().getItemInMainHand().getType().toString().contains("_SPAWN_EGG"))){
return;
}
String[] entityToBeSpawnedList = player.getInventory().getItemInMainHand().getType().toString().split("_SPAWN_EGG");
String entityToBeSpawned = entityToBeSpawnedList[0];
EntityType entityTypeTBS;
ItemStack item = player.getInventory().getItemInMainHand();
boolean customMob = false;
if (item.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "custom_mob_id"), PersistentDataType.STRING)){
// Custom Mob has been attempted to spawn
String customMobId = item.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "custom_mob_id"), PersistentDataType.STRING);
String mobType = MobSpawnConfig.get().getString(customMobId + ".type");
entityTypeTBS = EntityType.valueOf(mobType);
customMob = true;
}
else {
String[] entityToBeSpawnedList = item.getType().toString().split("_SPAWN_EGG");
String entityToBeSpawned = entityToBeSpawnedList[0];
EntityType entityTypeTBS = EntityType.valueOf(entityToBeSpawned);
entityTypeTBS = EntityType.valueOf(entityToBeSpawned);
}
Location lookPlace = e.getInteractionPoint();
Entity spawnedEntity = player.getWorld().spawnEntity(lookPlace, entityTypeTBS);
if (spawnedEntity instanceof Horse){
((Horse) spawnedEntity).setTamed(true);
((Horse) spawnedEntity).getInventory().addItem(new ItemStack(Material.SADDLE));
if (spawnedEntity instanceof Chicken){
if (plugin.getConfig().getBoolean("chicken-prevention")){
player.sendMessage(Component.text("ChickenPrevention prevented your chicken from spawning.").color(NamedTextColor.RED));
return;
}
}
if (spawnedEntity instanceof AbstractHorse) {
((AbstractHorse) spawnedEntity).setTamed(true);
((AbstractHorse) spawnedEntity).getInventory().addItem(new ItemStack(Material.SADDLE));
}
if (spawnedEntity instanceof Monster) {
Player closestPlayer = getNearestPlayer(player);
((Monster) spawnedEntity).setTarget(closestPlayer);
// System.out.println(spawnedEntity + "'s target set to " + closestPlayer);
spawnedEntity.customName(Component.text(player.getName() + "'s " + spawnedEntity.getType().name()));
spawnedEntity.getPersistentDataContainer().set(new NamespacedKey(plugin, "custom_mob"), PersistentDataType.INTEGER, 1);
}
if (customMob) {
String customModId = item.getItemMeta().getPersistentDataContainer().get(new NamespacedKey(plugin, "custom_mob_id"), PersistentDataType.STRING);
// System.out.println(customModId);
if (spawnedEntity instanceof Mob){
ItemStack mainHand = MobSpawnConfig.get().getItemStack(customModId + ".mainhand");
((Mob) spawnedEntity).getEquipment().setItemInMainHand(mainHand);
ItemStack offHand = MobSpawnConfig.get().getItemStack(customModId + ".offhand");
((Mob) spawnedEntity).getEquipment().setItemInOffHand(offHand);
ItemStack boots = MobSpawnConfig.get().getItemStack(customModId + ".boots");
((Mob) spawnedEntity).getEquipment().setBoots(boots);
ItemStack chestplate = MobSpawnConfig.get().getItemStack(customModId + ".chestplate");
((Mob) spawnedEntity).getEquipment().setChestplate(chestplate);
ItemStack leggings = MobSpawnConfig.get().getItemStack(customModId + ".leggings");
((Mob) spawnedEntity).getEquipment().setLeggings(leggings);
ItemStack helmet = MobSpawnConfig.get().getItemStack(customModId + ".helmet");
((Mob) spawnedEntity).getEquipment().setHelmet(helmet);
}
if (spawnedEntity instanceof Zombie) {
if (MobSpawnConfig.get().getBoolean(customModId + ".child")) {
((Zombie) spawnedEntity).setBaby();
}
((Zombie) spawnedEntity).setVisualFire(false);
((Zombie) spawnedEntity).addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 1000000, 20, false, false));
}
if (spawnedEntity instanceof Skeleton) {
((Skeleton) spawnedEntity).setVisualFire(false);
((Skeleton) spawnedEntity).addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 1000000, 20, false, false));
}
}
toBeCancelled = true;
@@ -76,11 +141,23 @@ public class OnPlayerSpawnMob implements Listener {
}, 10L);
mobOwners.put(spawnedEntity, player);
ItemStack heldItem = player.getInventory().getItemInMainHand();
player.getInventory().remove(heldItem);
int amount = item.getAmount();
item.setAmount(amount - 1);
player.getInventory().remove(item);
player.getInventory().setItemInMainHand(item);
}
// Stolen from https://www.spigotmc.org/threads/how-do-i-get-the-nearest-player.506654/
public static @Nullable Player getNearestPlayer(Player player) {
World world = player.getWorld();
Location location = player.getLocation();
ArrayList<Player> playersInWorld = new ArrayList<>(world.getEntitiesByClass(Player.class));
if(playersInWorld.size()==1) return null;
playersInWorld.remove(player); //Removes player itself
playersInWorld.sort(Comparator.comparingDouble(o -> o.getLocation().distanceSquared(location)));
return playersInWorld.get(0);
}
@EventHandler
public void playerSpawnCreature(CreatureSpawnEvent e) {
@@ -95,4 +172,26 @@ public class OnPlayerSpawnMob implements Listener {
}
}
@EventHandler
public void mobTargetEvent(EntityTargetEvent e){
Entity entity = e.getEntity();
Entity target = e.getTarget();
if (!(entity.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (!(entity instanceof Monster)) {
return;
}
e.setCancelled(true);
String entityName = entity.getName();
String playerName = entityName.split("'s")[0]; // Gets name of player who spawned it
Player player = Bukkit.getPlayerExact(playerName); // TODOX: This is quite janky, requires testing: seems to work!
Player closestPlayer = getNearestPlayer(player); // NPE has no effect it seems; target becomes null and zombie is fine with that
((Monster) entity).setTarget(closestPlayer);
// System.out.println(entity + "'s target set to " + closestPlayer);
}
}
@@ -0,0 +1,85 @@
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.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
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.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class CosmeticsCommand implements CommandExecutor {
Plugin plugin;
public CosmeticsCommand(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)) {
return false;
}
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"));
return true;
}
//Create inventory GUI
TextComponent invTitle = Component.text("Cosmetics Menu").color(TextColor.color(255, 150, 20));
Inventory cosmeticsInventory = Bukkit.createInventory(null, 54, invTitle);
// Kill cosmetics button
ItemStack killEffectButton = new ItemStack(Material.DIAMOND_SWORD);
ItemMeta killEffectButtonMeta = killEffectButton.getItemMeta();
killEffectButtonMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
killEffectButtonMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
killEffectButtonMeta.displayName(Component.text("Kill Effect").color(TextColor.color(200, 152, 0)).decoration(TextDecoration.ITALIC, false));
List<Component> loreList2 = new ArrayList<>();
TextComponent txt21 = Component.text("Change your kill effect cosmetic!").color(TextColor.color(100,100,100)).decoration(TextDecoration.ITALIC, false);
loreList2.add(txt21);
killEffectButtonMeta.lore(loreList2);
killEffectButton.setItemMeta(killEffectButtonMeta);
cosmeticsInventory.setItem(20, killEffectButton);
ItemStack trailEffectButton = new ItemStack(Material.ARROW);
ItemMeta trailEffectButtonItemMeta = trailEffectButton.getItemMeta();
trailEffectButtonItemMeta.displayName(Component.text("Projectile Trail").color(TextColor.color(200, 152, 0)).decoration(TextDecoration.ITALIC, false));
List<Component> loreList3 = new ArrayList<>();
TextComponent txt22 = Component.text("Change your projectile trail cosmetic!").color(TextColor.color(100,100,100)).decoration(TextDecoration.ITALIC, false);
loreList3.add(txt22);
trailEffectButtonItemMeta.lore(loreList3);
trailEffectButton.setItemMeta(trailEffectButtonItemMeta);
cosmeticsInventory.setItem(22, trailEffectButton);
ItemStack killMessageEffect = new ItemStack(Material.OAK_SIGN);
ItemMeta killMessageEffectItemMeta = killMessageEffect.getItemMeta();
killMessageEffectItemMeta.displayName(Component.text("Kill Message").color(TextColor.color(200, 152, 0)).decoration(TextDecoration.ITALIC, false));
List<Component> loreList = new ArrayList<>();
TextComponent txt = Component.text("Change your kill message cosmetic!").color(TextColor.color(100,100,100)).decoration(TextDecoration.ITALIC, false);
loreList.add(txt);
killMessageEffectItemMeta.lore(loreList);
killMessageEffect.setItemMeta(killMessageEffectItemMeta);
cosmeticsInventory.setItem(24, killMessageEffect);
player.openInventory(cosmeticsInventory);
return true;
}
}
@@ -0,0 +1,56 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand;
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 net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
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.ItemStack;
import org.bukkit.plugin.Plugin;
public class CosmeticsGUIListener implements Listener {
Plugin plugin;
public CosmeticsGUIListener(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.getView().title().toString().contains("Cosmetics Menu"))) {
return;
}
if (e.getCurrentItem() == null){
return;
}
ItemStack clickedItem = e.getCurrentItem();
e.setCancelled(true);
Component itemDisplayName = clickedItem.displayName();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
String itemName = serializer.serialize(itemDisplayName);
itemName = itemName.substring(1, itemName.length() - 1); // For some reason the itemname has [] around it; frick Component
switch(itemName){
case "Kill Effect":
KillEffectInventory.openKillEffectInventory(player);
return;
case "Projectile Trail":
ProjectileTrailInventory.openProjectileTrailInventory(player);
return;
case "Kill Message":
KillMessageInventory.openKillMessageInventory(player);
return;
}
}
}
@@ -0,0 +1,37 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand;
import org.bukkit.Material;
import java.util.HashMap;
public class CosmeticsLib {
public HashMap<String, Material> killEffects = new HashMap<>();
public HashMap<String, Material> messageEffects = new HashMap<>();
public HashMap<String, Material> trailEffects = new HashMap<>();
public CosmeticsLib() {
killEffects.put("firework", Material.FIREWORK_ROCKET);
killEffects.put("blood_explosion", Material.REDSTONE);
killEffects.put("ritual", Material.FIRE_CHARGE);
killEffects.put("tornado", Material.STRING);
killEffects.put("cow_rocket", Material.COW_SPAWN_EGG);
killEffects.put("dragon_breath", Material.DRAGON_BREATH);
killEffects.put("diamond_rain", Material.DIAMOND);
messageEffects.put("default", Material.DIAMOND_SWORD);
messageEffects.put("flex", Material.GOLDEN_APPLE);
messageEffects.put("nerd", Material.GLASS);
trailEffects.put("none", Material.BARRIER);
trailEffects.put("flame", Material.FIRE_CHARGE);
trailEffects.put("sparkle", Material.END_ROD);
trailEffects.put("water_drip", Material.LILY_PAD);
trailEffects.put("heart", Material.GOLD_INGOT);
trailEffects.put("firework", Material.FIREWORK_ROCKET);
trailEffects.put("totem", Material.TOTEM_OF_UNDYING);
trailEffects.put("smoke", Material.CAMPFIRE);
}
}
@@ -0,0 +1,118 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.inventories;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsCommand;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsLib;
import me.lifelessnerd.purekitpvp.files.CosmeticsConfig;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
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 net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
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.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
public class KillEffectInventory implements Listener {
static Plugin plugin; // static?
public KillEffectInventory(Plugin plugin) {
KillEffectInventory.plugin = plugin;
} // could make this this.plugin
public static void openKillEffectInventory(Player player){
// This method is responsible for drawing items in inventory on clicking 'Kill Effect'
CosmeticsLib lib = new CosmeticsLib();
TextComponent invTitle = Component.text("Change Kill Effect").color(TextColor.color(255, 150, 20));
Inventory cosmeticsInventory = Bukkit.createInventory(null, 54, invTitle);
for (String killEffect : lib.killEffects.keySet()) {
ItemStack effectItem = new ItemStack(lib.killEffects.get(killEffect), 1);
ItemMeta itemMeta = effectItem.getItemMeta();
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
Component displayName = Component.text(MyStringUtils.cosmeticIdToItemName(killEffect));
//MEH: This 4x is not needed; just once at the start and then add green to that item?
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.save();
CosmeticsConfig.reload();
configValue = CosmeticsConfig.get().getString("kill_effect." + player.getName());
}
if (configValue.equalsIgnoreCase(killEffect)){
displayName = displayName.color(NamedTextColor.GREEN).decoration(TextDecoration.ITALIC, false);
displayName = displayName.decoration(TextDecoration.BOLD, true);
itemMeta.addEnchant(Enchantment.DAMAGE_ALL, 1, true);
} else {
displayName = displayName.color(NamedTextColor.RED).decoration(TextDecoration.ITALIC, false);;
}
itemMeta.displayName(displayName);
effectItem.setItemMeta(itemMeta);
cosmeticsInventory.addItem(effectItem);
}
ItemStack backArrow = new ItemStack(Material.ARROW);
ItemMeta backArrowIM = backArrow.getItemMeta();
backArrowIM.displayName(Component.text("Go Back").decoration(TextDecoration.ITALIC, false).color(NamedTextColor.GREEN));
backArrow.setItemMeta(backArrowIM);
cosmeticsInventory.setItem(49, backArrow);
player.openInventory(cosmeticsInventory);
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
// This method is responsible for logic after a cosmetics item is clicked
Player player = (Player) e.getWhoClicked();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (!(e.getView().title().toString().contains("Change Kill Effect"))) {
return;
}
ItemStack clickedItem = e.getCurrentItem();
if (clickedItem == null){
return;
}
e.setCancelled(true);
String itemDisplayName = MyStringUtils.componentToString(clickedItem.displayName());
String attachedCosmeticName = MyStringUtils.itemNameToCosmeticId(itemDisplayName);
// Do stuff to the config with this string
// System.out.println(attachedCosmeticName);
if (itemDisplayName.equalsIgnoreCase("Go Back")){
player.closeInventory();
player.chat("/cosmetics");
return;
}
CosmeticsConfig.get().set("kill_effect." + player.getName(), attachedCosmeticName);
CosmeticsConfig.save();
CosmeticsConfig.reload();
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1,0);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&7Selected " + "&c" + itemDisplayName));
e.getInventory().close(); // This is a choice I made, may not be optimal
}
}
@@ -0,0 +1,116 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.inventories;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsLib;
import me.lifelessnerd.purekitpvp.files.CosmeticsConfig;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
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;
import org.bukkit.ChatColor;
import org.bukkit.Material;
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.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
public class KillMessageInventory implements Listener {
static Plugin plugin; // static?
public KillMessageInventory(Plugin plugin) {
KillMessageInventory.plugin = plugin;
} // could make this this.plugin
public static void openKillMessageInventory(Player player){
// This method is responsible for drawing items in inventory on clicking 'Projectile Trail'
CosmeticsLib lib = new CosmeticsLib();
TextComponent invTitle = Component.text("Change Kill Message").color(TextColor.color(255, 150, 20));
Inventory cosmeticsInventory = Bukkit.createInventory(null, 54, invTitle);
for (String messageEffect : lib.messageEffects.keySet()) {
ItemStack effectItem = new ItemStack(lib.messageEffects.get(messageEffect), 1);
ItemMeta itemMeta = effectItem.getItemMeta();
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
Component displayName = Component.text(MyStringUtils.cosmeticIdToItemName(messageEffect));
//MEH: This 4x is not needed; just once at the start and then add green to that item?
String configValue = CosmeticsConfig.get().getString("kill_message." + player.getName());
// if player is not present in file; add it to config and try again
if (configValue == null){
CosmeticsConfig.get().set("kill_message." + player.getName(), "default");
CosmeticsConfig.save();
CosmeticsConfig.reload();
configValue = CosmeticsConfig.get().getString("kill_message." + player.getName());
}
if (configValue.equalsIgnoreCase(messageEffect)){
displayName = displayName.color(NamedTextColor.GREEN).decoration(TextDecoration.ITALIC, false);
displayName = displayName.decoration(TextDecoration.BOLD, true);
itemMeta.addEnchant(Enchantment.DAMAGE_ALL, 1, true);
} else {
displayName = displayName.color(NamedTextColor.RED).decoration(TextDecoration.ITALIC, false);;
}
itemMeta.displayName(displayName);
effectItem.setItemMeta(itemMeta);
cosmeticsInventory.addItem(effectItem);
}
ItemStack backArrow = new ItemStack(Material.ARROW);
ItemMeta backArrowIM = backArrow.getItemMeta();
backArrowIM.displayName(Component.text("Go Back").decoration(TextDecoration.ITALIC, false).color(NamedTextColor.GREEN));
backArrow.setItemMeta(backArrowIM);
cosmeticsInventory.setItem(49, backArrow);
player.openInventory(cosmeticsInventory);
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
// This method is responsible for logic after a cosmetics item is clicked
Player player = (Player) e.getWhoClicked();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (!(e.getView().title().toString().contains("Change Kill Message"))) {
return;
}
ItemStack clickedItem = e.getCurrentItem();
if (clickedItem == null){
return;
}
e.setCancelled(true);
String itemDisplayName = MyStringUtils.componentToString(clickedItem.displayName());
String attachedCosmeticName = MyStringUtils.itemNameToCosmeticId(itemDisplayName);
// Do stuff to the config with this string
// System.out.println(attachedCosmeticName);
if (itemDisplayName.equalsIgnoreCase("Go Back")){
player.closeInventory();
player.chat("/cosmetics");
return;
}
CosmeticsConfig.get().set("kill_message." + player.getName(), attachedCosmeticName);
CosmeticsConfig.save();
CosmeticsConfig.reload();
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1,0);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&7Selected " + "&c" + itemDisplayName));
e.getInventory().close(); // This is a choice I made, may not be optimal
}
}
@@ -0,0 +1,117 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.inventories;
import me.lifelessnerd.purekitpvp.cosmetics.cosmeticsCommand.CosmeticsLib;
import me.lifelessnerd.purekitpvp.files.CosmeticsConfig;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
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;
import org.bukkit.ChatColor;
import org.bukkit.Material;
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.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
public class ProjectileTrailInventory implements Listener {
static Plugin plugin; // static?
public ProjectileTrailInventory(Plugin plugin) {
ProjectileTrailInventory.plugin = plugin;
} // could make this this.plugin
public static void openProjectileTrailInventory(Player player){
// This method is responsible for drawing items in inventory on clicking 'Projectile Trail'
CosmeticsLib lib = new CosmeticsLib();
TextComponent invTitle = Component.text("Change Projectile Trail").color(TextColor.color(255, 150, 20));
Inventory cosmeticsInventory = Bukkit.createInventory(null, 54, invTitle);
for (String projectileTrail : lib.trailEffects.keySet()) {
ItemStack effectItem = new ItemStack(lib.trailEffects.get(projectileTrail), 1);
ItemMeta itemMeta = effectItem.getItemMeta();
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
Component displayName = Component.text(MyStringUtils.cosmeticIdToItemName(projectileTrail));
//MEH: This 4x is not needed; just once at the start and then add green to that item?
String configValue = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
// if player is not present in file; add it to config and try again
if (configValue == null){
CosmeticsConfig.get().set("projectile_trail." + player.getName(), plugin.getConfig().getString("default-projectile-trail"));
CosmeticsConfig.save();
CosmeticsConfig.reload();
configValue = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
}
if (configValue.equalsIgnoreCase(projectileTrail)){
displayName = displayName.color(NamedTextColor.GREEN).decoration(TextDecoration.ITALIC, false);
displayName = displayName.decoration(TextDecoration.BOLD, true);
itemMeta.addEnchant(Enchantment.DAMAGE_ALL, 1, true);
} else {
displayName = displayName.color(NamedTextColor.RED).decoration(TextDecoration.ITALIC, false);;
}
itemMeta.displayName(displayName);
effectItem.setItemMeta(itemMeta);
cosmeticsInventory.addItem(effectItem);
}
ItemStack backArrow = new ItemStack(Material.ARROW);
ItemMeta backArrowIM = backArrow.getItemMeta();
backArrowIM.displayName(Component.text("Go Back").decoration(TextDecoration.ITALIC, false).color(NamedTextColor.GREEN));
backArrow.setItemMeta(backArrowIM);
cosmeticsInventory.setItem(49, backArrow);
player.openInventory(cosmeticsInventory);
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
// This method is responsible for logic after a cosmetics item is clicked
Player player = (Player) e.getWhoClicked();
if (!(player.getWorld().getName().equalsIgnoreCase(plugin.getConfig().getString("world")))) {
return;
}
if (!(e.getView().title().toString().contains("Change Projectile Trail"))) {
return;
}
ItemStack clickedItem = e.getCurrentItem();
if (clickedItem == null){
return;
}
e.setCancelled(true);
String itemDisplayName = MyStringUtils.componentToString(clickedItem.displayName());
String attachedCosmeticName = MyStringUtils.itemNameToCosmeticId(itemDisplayName);
// Do stuff to the config with this string
// System.out.println(attachedCosmeticName);
if (itemDisplayName.equalsIgnoreCase("Go Back")){
player.closeInventory();
player.chat("/cosmetics");
return;
}
CosmeticsConfig.get().set("projectile_trail." + player.getName(), attachedCosmeticName);
CosmeticsConfig.save();
CosmeticsConfig.reload();
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1,0);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&7Selected " + "&c" + itemDisplayName));
e.getInventory().close(); // This is a choice I made, may not be optimal
}
}
@@ -0,0 +1,207 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners;
import me.lifelessnerd.purekitpvp.files.CosmeticsConfig;
import net.kyori.adventure.text.Component;
import org.bukkit.*;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import javax.swing.text.html.HTMLDocument;
import java.util.logging.Level;
public class KillEffect implements Listener {
public static Plugin plugin;
public KillEffect(Plugin plugin) {
KillEffect.plugin = plugin;
}
public static void fireKillCosmetic(Player player, Player creditPlayer) {
String activeCosmetic = "firework";
try {
// This construct is weird; it works tho
activeCosmetic = CosmeticsConfig.get().getString("kill_effect." + creditPlayer.getName());
if (activeCosmetic == null){
throw new NullPointerException("Player is not defined in Cosmetics config! They have been added with default.");
}
} catch (Exception e) {
String configValue = CosmeticsConfig.get().getString("kill_effect." + creditPlayer.getName());
// if player is not present in file; add it to config and try again
if (configValue == null){
CosmeticsConfig.get().set("kill_effect." + creditPlayer.getName(), plugin.getConfig().getString("default-kill-effect"));
CosmeticsConfig.save();
CosmeticsConfig.reload();
activeCosmetic = CosmeticsConfig.get().getString("kill_effect." + creditPlayer.getName());
}
plugin.getLogger().log(Level.INFO, e.getMessage());
} // If something in the config is wrong; switch statement will pick default and do nothing
Location killLocation = player.getLocation();
Location killerLocation = creditPlayer.getLocation();
switch (activeCosmetic) { // NPE lies, try catch above fixes this
case "firework" -> {
firework(killLocation);
}
case "blood_explosion" -> {
bloodExplosion(killLocation);
}
case "ritual" -> {
ritual(killLocation);
}
case "tornado" -> {
tornado(killLocation);
}
case "cow_rocket" -> {
cow_rocket(killLocation);
}
case "dragon_breath" -> {
dragon_breath(killLocation);
}
case "diamond_rain" -> {
diamond_rain(killLocation);
}
default -> {
//Idk how you would end up here: Do nothing
}
}
}
public static void firework(Location location) {
location = location.add(0,1.4,0);
Firework fw = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
FireworkMeta fwm = fw.getFireworkMeta();
fwm.addEffect(FireworkEffect.builder().withColor(Color.RED).withColor(Color.WHITE).flicker(true).build());
fw.setMetadata("nodamage", new FixedMetadataValue(plugin, true));
fw.setFireworkMeta(fwm);
fw.detonate();
}
@EventHandler
public void preventFireworkDamage(EntityDamageByEntityEvent e) {
if (e.getDamager() instanceof Firework) {
Firework fw = (Firework) e.getDamager();
if (fw.hasMetadata("nodamage")) {
e.setCancelled(true);
}
}
}
public static void bloodExplosion(Location location) {
for (float i = 0.5f; i < 1.8f; i += 0.1) {
location.getWorld().spawnParticle(
Particle.BLOCK_CRACK,
location.add(0,i,0),
20,
Material.REDSTONE_BLOCK.createBlockData()
);
}
}
public static void ritual(Location location) {
for (int i = 0; i < 360; i += 20) {
Location flameloc = location.add(0,1.2,0);
flameloc.setZ(flameloc.getZ() + Math.cos(i) * 0.7);
flameloc.setX(flameloc.getX() + Math.sin(i) * 0.7);
location.getWorld().spawnParticle(Particle.FLAME, flameloc, 10, 0, 0, 0, 0.001);
}
for (int i = 0; i < 360; i += 10) {
Location flameloc = location.add(0,0.6,0);
flameloc.setZ(flameloc.getZ() + Math.cos(i) * 1.5);
flameloc.setX(flameloc.getX() + Math.sin(i) * 1.5);
location.getWorld().spawnParticle(Particle.FLAME, flameloc, 10, 0, 0, 0, 0.001);
}
for (int i = 0; i < 360; i += 5) {
Location flameloc = location;
double extendedZ = flameloc.getZ() + Math.cos(i) / 2;
double extendedX = flameloc.getZ() + Math.cos(i) / 2;
flameloc.setZ(flameloc.getZ() + Math.cos(i) * 2);
flameloc.setX(flameloc.getX() + Math.sin(i) * 2);
location.getWorld().spawnParticle(Particle.CLOUD, flameloc, 1, extendedX, 0, extendedZ, 0.001);
}
}
public static void tornado(Location location) {
for (double i = 1; i < 4; i = i + 0.4) {
double newY = location.getY() + i;
for (double j = 0; j < 360; j += 20) {
double newZ = (location.getZ() + Math.cos(j) * (1 * Math.sqrt(i) - 0.5));
double newX = (location.getX() + Math.sin(j) * (1 * Math.sqrt(i) - 0.5));
location.getWorld().spawnParticle(Particle.FLAME, newX, newY, newZ, 1, 0.1, 0.5, 0.1, 0.001);
}
}
location.getWorld().playSound(location, Sound.ENTITY_ENDER_DRAGON_SHOOT, 1f, 1);
}
public static void cow_rocket(Location location) {
Entity cow = location.getWorld().spawnEntity(location, EntityType.COW);
cow.setGravity(false);
cow.teleport(location.add(0,2,0));
new BukkitRunnable() {
int i = 0;
@Override
public void run () {
cow.teleport(location.add(0,0.2,0));
cow.getLocation().getWorld().playSound(location, Sound.BLOCK_NOTE_BLOCK_PLING, 1, i*0.1f);
cow.getLocation().getWorld().spawnParticle(Particle.GLOW_SQUID_INK, location, 2,0.1, 0.1, 0.1, 0.001);
if (i >= 16){
this.cancel();
cow.remove();
cow.getLocation().createExplosion(0, false, false);
}
i++;
}
}.runTaskTimer(plugin, 0, 1);
}
private static void dragon_breath(Location location) {
location.getWorld().spawnParticle(Particle.DRAGON_BREATH, location, 500, 0.2, 1, 0.2, 0.05);
location.getWorld().playSound(location, Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1, 1);
}
private static void diamond_rain(Location location){
new BukkitRunnable() {
int i = 0;
@Override
public void run() {
ItemStack is = new ItemStack(Material.DIAMOND, 1);
ItemMeta im = is.getItemMeta();
im.displayName(Component.text(i)); // Change display name so they do not stack
is.setItemMeta(im);
Item dropped = location.getWorld().dropItemNaturally(location, is);
dropped.getPersistentDataContainer().set(new NamespacedKey(plugin, "cosmetic"), PersistentDataType.BOOLEAN, true);
// PDC attached to entity instead if itemstack, these (apparently) do not transfer between states
location.getWorld().playSound(location, Sound.ENTITY_ITEM_PICKUP, 1, 1);
Bukkit.getScheduler().runTaskLater(plugin, dropped::remove, 100L); // IDEA lambda magic
if (i >= 10){
this.cancel();
}
i++;
}
}.runTaskTimer(plugin, 0, 2);
}
}
@@ -0,0 +1,98 @@
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;
public class KillMessage {
public static class create {
public static String byEnvironment(String player, String lastEnvironmentHit){
// System.out.println("byEnvironment");
DamageCauseLib damageCauseLib = new DamageCauseLib();
return player + damageCauseLib.deathMessages.get(lastEnvironmentHit);
}
public static String byEnvironmentAndPlayer(String player, String killer, String environmentHit){
// System.out.println("byEnvironmentAndPlayer");
DeathCauseLib deathCauseLib = new DeathCauseLib();
Set<String> interestingCauses = deathCauseLib.defaultDeathMessages.keySet();
if(interestingCauses.contains(environmentHit)){
String preprocessed = player + getCosmeticMessage(player, environmentHit, false);
return preprocessed.replace("{killer}", killer);
} else {
return (player + getCosmeticMessage(player, environmentHit, true)).replace("{killer}", killer);
}
}
public static String byPlayer(String player, String killer){
// System.out.println("byPlayer");
String preprocessed = getCosmeticMessage(killer, null, true);
// System.out.println(preprocessed);
return player + preprocessed.replace("{killer}", killer);
}
}
public static String getCosmeticMessage(String player, String environmentHit, boolean killMessage) {
DeathCauseLib deathCauseLib = new DeathCauseLib();
String activeCosmetic = "default";
try {
// This construct is weird; it works tho
activeCosmetic = CosmeticsConfig.get().getString("kill_message." + player);
if (activeCosmetic == null) {
throw new NullPointerException("Player is not defined in Cosmetics config! They have been added with default.");
}
} catch (Exception e) {
String configValue = CosmeticsConfig.get().getString("kill_message." + player);
// if player is not present in file; add it to config and try again
if (configValue == null) {
CosmeticsConfig.get().set("kill_message." + player, "default");
CosmeticsConfig.save();
CosmeticsConfig.reload();
activeCosmetic = CosmeticsConfig.get().getString("kill_effect." + player);
}
PluginGetter.Plugin().getLogger().log(Level.INFO, e.getMessage());
} // If something in the config is wrong; switch statement will pick default and do nothing
if (killMessage) {
switch (activeCosmetic) {
case "flex":
int kills = 1;
String killsString;
try {
kills = PlayerStatsConfig.get().getInt(player + ".kills");
} catch(Exception e){
kills = 1;
}
killsString = Integer.toString(kills + 1);
return (deathCauseLib.flexKillMessages.get(0)).replace("{kills}", killsString);
case "nerd":
return deathCauseLib.nerdKillMessages.get(0);
case "default":
return deathCauseLib.defaultKillMessages.get(0);
}
} else {
// Death message
switch (activeCosmetic) {
case "flex":
return deathCauseLib.flexDeathMessages.get(environmentHit);
case "nerd":
return deathCauseLib.nerdDeathMessages.get(environmentHit);
case "default":
return deathCauseLib.defaultDeathMessages.get(environmentHit);
}
}
PluginGetter.Plugin().getLogger().warning("Kill Message Cosmetics Error: config file contains faulty values!");
return "???";
}
}
@@ -0,0 +1,173 @@
package me.lifelessnerd.purekitpvp.cosmetics.cosmeticsListeners;
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.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.player.PlayerInteractEvent;
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) {
this.plugin = plugin;
}
@EventHandler
public void onProjectileLaunch(PlayerLaunchProjectileEvent e) {
Player player = e.getPlayer();
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());
}
// 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 projectile = e.getProjectile();
// System.out.println(projectile.toString());
int rotationSpeed = 30;
final double INCREMENT = (2 * Math.PI) / rotationSpeed;
new BukkitRunnable() {
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 onArrowShoot(EntityShootBowEvent e){
if (!(e.getEntity() instanceof Player player)){
return;
}
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());
}
// 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
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
this.cancel();
return;
}
String trail = CosmeticsConfig.get().getString("projectile_trail." + player.getName());
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);
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"));
}
}
@@ -52,7 +52,7 @@ public class CreateKit extends Subcommand {
return true;
}
if (!(args.length >= 2)){
if (!(args.length >= 4)){
player.sendMessage(ChatColor.RED + "Please provide arguments!");
return false;
}
@@ -64,7 +64,7 @@ public class CreateKit extends Subcommand {
String kitName = args[1].toLowerCase();
kitName = kitName.substring(0, 1).toUpperCase() + kitName.substring(1);
String displayColor = args[2];
if (!(args.length >= 4)){
if (!(args.length >= 5)){
player.sendMessage("Provide arguments!");
return false;
@@ -129,7 +129,7 @@ public class CreateKit extends Subcommand {
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
"Kit created with following properties: \nKitName: &a" + kitName +
"&r\n displayColor: &a" + displayColor + "&r\n kitIcon: &a"
"&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.");
@@ -1,15 +1,22 @@
package me.lifelessnerd.purekitpvp.customitems;
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.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 java.util.ArrayList;
import java.util.Arrays;
@@ -33,7 +40,7 @@ public class GetCustomItem extends Subcommand {
@Override
public String getSyntax() {
return "/purekitpvp getcustomitem <golden_head/random_chest>";
return "/purekitpvp getcustomitem <golden_head/random_chest/custom_mob_egg>";
}
@Override
@@ -43,7 +50,7 @@ public class GetCustomItem extends Subcommand {
ItemStack goldenHead = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) goldenHead.getItemMeta();
meta.displayName(Component.text("Golden Head"));
meta.displayName(Component.text("Golden Head").decoration(TextDecoration.ITALIC, false));
String[] loreList = {"Healing Item"};
meta.setLore(Arrays.asList(loreList));
meta.setOwningPlayer(Bukkit.getOfflinePlayer("PhantomTupac"));
@@ -75,6 +82,26 @@ public class GetCustomItem extends Subcommand {
return true;
} else if(args[1].equalsIgnoreCase("custom_mob_egg")){
if (!(MobSpawnConfig.get().isSet(args[2]))){
player.sendMessage("Such custom mob does not exist!");
return false;
}
// Try catch dit miss?
String type = MobSpawnConfig.get().getString(args[2] + ".type");
ItemStack egg = new ItemStack(Material.valueOf(type + "_SPAWN_EGG"));
ItemMeta eggMeta = egg.getItemMeta();
List<Component> lore = new ArrayList<>();
lore.add(Component.text("Custom Mob Spawner Egg"));
eggMeta.lore(lore);
PersistentDataContainer data = eggMeta.getPersistentDataContainer();
data.set(new NamespacedKey(PluginGetter.Plugin(), "custom_mob_id"), PersistentDataType.STRING, args[2]);
egg.setItemMeta(eggMeta);
player.getInventory().addItem(egg);
}
return false;
}
@@ -46,7 +46,7 @@ public class GoldenHeadEat implements Listener {
ItemStack heldItem = player.getInventory().getItemInMainHand();
String desiredLore = "Healing Item"; //TODO: Might have broken it by changing it Golden Head > Healing Item
String desiredLore = "Healing Item";
if (!(heldItem.getItemMeta().hasLore())) {
@@ -57,10 +57,16 @@ public class GoldenHeadEat implements Listener {
return;
}
heldItem.setAmount(heldItem.getAmount() - 1);
int slot = player.getInventory().getHeldItemSlot();
player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 100, 2));
player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 400, 0));
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 1));
player.getInventory().remove(heldItem);
player.getInventory().setItem(slot, heldItem);
// 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,6 +1,7 @@
package me.lifelessnerd.purekitpvp.customitems;
import me.lifelessnerd.purekitpvp.files.LootTablesConfig;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -64,9 +65,13 @@ public class OpenRandomChest implements Listener {
}
}
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!");
plugin.getLogger().warning("Player " + player.getName() + " current kit is " + PlayerStatsConfig.get().getString(player.getName() + ".current_kit"));
return;
}
player.getInventory().remove(heldItem);
// Giving algorithm
if (LootTablesConfig.get().getBoolean(currentLootTable + ".guaranteed.enabled")){
//Guaranteed items algo
@@ -112,7 +117,7 @@ public class OpenRandomChest implements Listener {
}
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_BELL, 1, 1);
player.getInventory().remove(heldItem);
if (heldItem.getAmount() > 1){
int itemsAdded = 0;
@@ -105,7 +105,7 @@ 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!");
" 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.");
LootTablesConfig.save();
@@ -0,0 +1,119 @@
package me.lifelessnerd.purekitpvp.custommobs;
import me.lifelessnerd.purekitpvp.Subcommand;
import me.lifelessnerd.purekitpvp.files.MobSpawnConfig;
import me.lifelessnerd.purekitpvp.utils.ComponentUtils;
import me.lifelessnerd.purekitpvp.utils.MyStringUtils;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
public class CustomMobCommand extends Subcommand {
@Override
public String getName() {
return "custommob";
}
@Override
public String[] getAliases() {
return null;
}
@Override
public String getDescription() {
return "Create custom mobs that can be used in kits as spawn eggs";
}
@Override
public String getSyntax() {
return "/purekitpvp custommob <create/delete/set> <identifier>";
}
@Override
public boolean perform(Player player, String[] args) {
if (args.length <= 1){
player.sendMessage("Please provide arguments!");
return true;
}
if (args[1].equalsIgnoreCase("create")){
if (args.length <= 3){
player.sendMessage("Please provide arguments!");
return true;
}
//String customMobName = args[2];
MobSpawnConfig.get().set(args[2], null);
MobSpawnConfig.get().set(args[2] + ".type", EntityType.valueOf(args[3].toUpperCase()).toString());
MobSpawnConfig.get().set(args[2] + ".child", false);
MobSpawnConfig.get().set(args[2] + ".helmet", null);
MobSpawnConfig.get().set(args[2] + ".chestplate", null);
MobSpawnConfig.get().set(args[2] + ".leggings", null);
MobSpawnConfig.get().set(args[2] + ".boots", null);
MobSpawnConfig.get().set(args[2] + ".mainhand", null);
MobSpawnConfig.get().set(args[2] + ".offhand", null);
player.sendMessage("Custom mob created with type " + args[3] + ", identifier " + args[2]);
player.sendMessage("You can now change its equipment using /purekitpvp custommob set");
MobSpawnConfig.save();
MobSpawnConfig.reload();
return true;
}
if (args[1].equalsIgnoreCase("set")){
if (args.length <= 3){
player.sendMessage("Please provide arguments!");
player.sendMessage("Usage: /purekitpvp custommob set <helmet/chestplate/leggings/boots/mainhand/offhand>");
return true;
}
// First the identifier as arg, check if there is such a key
if (!(MobSpawnConfig.get().isSet(args[2]))) {
player.sendMessage("That custom mob is not defined!");
}
//Possible args should be: helmet, chestplate, leggings, boots, mainhand, offhand
String[] possibleArgs = {"helmet", "chestplate", "leggings", "boots", "mainhand", "offhand"};
if (Arrays.asList(possibleArgs).contains(args[3])) {
setEquipment(player, args[2], args[3]);
player.sendMessage(args[2] + "'s " + args[3] + " was changed to the item you held.");
} else if(args[3].equalsIgnoreCase("child")){
if (args.length == 5 && (args[4].equalsIgnoreCase("true") || args[4].equalsIgnoreCase("false"))){
MobSpawnConfig.get().set(args[2] + ".child", Boolean.valueOf(args[4]));
MobSpawnConfig.save();
MobSpawnConfig.reload();
player.sendMessage("Custom mob " + args[2] + " property " + args[3] + " set to " + args[4]);
} else {
player.sendMessage("When using argument 'child', follow with either true or false.");
return true;
}
} else {
player.sendMessage("Possible arguments are: child (requires true/false argument), helmet, chestplate, leggings, boots, mainhand, offhand");
}
return true;
}
if (args[1].equalsIgnoreCase("delete")){
MobSpawnConfig.get().set(args[2], null);
player.sendMessage("Custom mob " + args[2] + " deleted.");
MobSpawnConfig.save();
MobSpawnConfig.reload();
return true;
}
else {
player.sendMessage("Invalid argument!");
}
return true;
}
public static void setEquipment(Player player, String mobName, String slot){
ItemStack heldItem = player.getInventory().getItemInMainHand();
MobSpawnConfig.get().set(mobName + "." + slot, heldItem);
MobSpawnConfig.save();
MobSpawnConfig.reload();
}
}
@@ -0,0 +1,45 @@
package me.lifelessnerd.purekitpvp.files;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
public class CosmeticsConfig {
private static File file;
private static FileConfiguration customFile;
public static void setup(){
file = new File(Bukkit.getServer().getPluginManager().getPlugin("PureKitPvP").getDataFolder(), "cosmetics.yml");
if (!(file.exists())){
try{
file.createNewFile();
} catch (IOException e){
//pain
}
}
customFile = YamlConfiguration.loadConfiguration(file);
}
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);
}
}
@@ -0,0 +1,45 @@
package me.lifelessnerd.purekitpvp.files;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
public class MobSpawnConfig {
private static File file;
private static FileConfiguration customFile;
public static void setup(){
file = new File(Bukkit.getServer().getPluginManager().getPlugin("PureKitPvP").getDataFolder(), "mobsconfig.yml");
if (!(file.exists())){
try{
file.createNewFile();
} catch (IOException e){
//pain
}
}
customFile = YamlConfiguration.loadConfiguration(file);
}
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);
}
}
@@ -5,9 +5,11 @@ 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.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;
@@ -21,6 +23,7 @@ import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class GUIListener implements Listener {
@@ -41,9 +44,12 @@ public class GUIListener implements Listener {
if (!(e.getCurrentItem() == null && e.getRawSlot() >= 53)){
ItemStack clickedItem = e.getCurrentItem();
InventoryView inv = e.getView();
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
if (inv.title().toString().contains("Kits")) { //I hate component
if (e.getRawSlot() < 52){
if (e.getRawSlot() < 45){
e.setCancelled(true);
if(clickedItem == null){
return;
@@ -63,12 +69,32 @@ public class GUIListener implements Listener {
player.chat("/suicide");
}
} else if (e.getRawSlot() == 52){ // Perk help button
} else if (e.getRawSlot() == 49){ // Perk help button
e.setCancelled(true);
player.chat("/perks");
} 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);
}
}
}
}
@@ -73,7 +73,7 @@ public class GetKit implements TabExecutor, Listener {
}
if(!KitConfig.get().isSet("kits." + kitNameArg + ".permission")){
player.sendMessage(ChatColor.GRAY + "That kit does not have a permission associated. Please report to your administrator.");
player.sendMessage(ChatColor.GRAY + "That kit does not have a permission associated. Please report this to your administrator.");
return true;
}
@@ -6,6 +6,7 @@ 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;
@@ -27,6 +28,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.bukkit.util.NumberConversions.floor;
public class KitsGUI implements TabExecutor {
Plugin plugin;
@@ -52,29 +55,83 @@ public class KitsGUI implements TabExecutor {
player.sendMessage(ChatColor.RED + "You can only use this menu in " + ChatColor.GRAY + 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]);
}
//Create inventory GUI
TextComponent inventoryTitle = Component.text("Kits").color(TextColor.color(255, 150, 20));
TextComponent inventoryTitle = Component.text("Kits - ").
color(TextColor.color(255, 150, 20)).
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;
// Will a second page be necessary?
if (amountOfKits >= 45 && (currentPage != lastPage)){ // On last page? Don't show next item
// 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);
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);
prevPageButton.setItemMeta(prevPageButtonMeta);
kits.setItem(48, prevPageButton);
loreList.clear();
}
int kitNumber = 1;
for (String key : KitConfig.get().getConfigurationSection("kits").getKeys(false)) {
// What page should this kit be put on?
int intendedPage = floor(((double) kitNumber / 46)) + 1;
kitNumber++;
if (intendedPage != currentPage){ // Not this page? Don't do anything
continue;
}
ItemStack itemStack = new ItemStack(Material.BARRIER);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
//NPE GALORE, TODO: idiot proof if these keys do not exist, instead of crashing entire plugin with an NPE
//TODO: Actually i have no idea what this is referring to, I get no NPE's in the GUI ever
//Set block
//Set gui item
itemStack.setType(Material.getMaterial(KitConfig.get().getString("kits." + key + ".guiitem")));
//Set lore
//Set lore
String loreText = KitConfig.get().getString("kits." + key + ".guilore");
loreText = ChatColor.translateAlternateColorCodes('&', loreText);
ArrayList<String> lore = new ArrayList<>();
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!"));
}
// Item lore that consists of contents of kit
FileConfiguration fileConfiguration = KitConfig.get();
List<ItemStack> kitContent = (List<ItemStack>) fileConfiguration.get("kits." + key + ".contents");
@@ -104,6 +161,7 @@ public class KitsGUI implements TabExecutor {
if (item == null) {
item = new ItemStack(Material.AIR);
} else if (item.getType().toString().equalsIgnoreCase("DIAMOND")){
// Some old kits have a diamond for identification of that kit, that is legacy
//Diamond check; do nothing
} else if (item.getType().toString().equalsIgnoreCase("SPLASH_POTION")){
@@ -162,17 +220,6 @@ public class KitsGUI implements TabExecutor {
lore.add(ChatColor.GRAY + "" + amount + "x " + ChatColor.YELLOW + MyStringUtils.itemCamelCase(killItem.getType().toString()));
}
//Add some final lines with active perks on this kit
// ConfigurationSection perksSection = KitConfig.get().getConfigurationSection("kits." + key + ".perks");
// if (perksSection == null || perksSection.getKeys(false).size() == 0){
// lore.add(ChatColor.RED + "No Perks");
// } else {
// lore.add(ChatColor.RED + "Perks:");
// for (String perkKey : perksSection.getKeys(false)) {
// lore.add(" " + ChatColor.YELLOW + MyStringUtils.itemCamelCase(perkKey));
// }
// }
//LEGACY, PERKS ARE NOW SELECTION BASED PER PLAYER
itemMeta.setLore(lore); //Heck you Component
@@ -188,10 +235,10 @@ public class KitsGUI implements TabExecutor {
//Reset button
ItemStack resetButton = new ItemStack(Material.BARRIER);
ItemMeta resetButtonMeta = resetButton.getItemMeta();
resetButtonMeta.displayName(Component.text("Reset kit"));
resetButtonMeta.displayName(Component.text("Reset kit").decoration(TextDecoration.ITALIC, false));
List<Component> loreList = new ArrayList<>();
TextComponent txt = Component.text("If you do not have permission to reset your kit,").color(TextColor.color(100,100,100));
TextComponent txt2 = Component.text("this will run /suicide on your behalf.").color(TextColor.color(100,100,100));
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);
resetButtonMeta.lore(loreList);
@@ -201,13 +248,13 @@ public class KitsGUI implements TabExecutor {
// Perk Redirect Button
ItemStack perkHelpButton = new ItemStack(Material.BOOK);
ItemMeta perkHelpButtonMeta = perkHelpButton.getItemMeta();
perkHelpButtonMeta.displayName(Component.text("Perk Info"));
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!").color(TextColor.color(100,100,100));
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);
perkHelpButton.setItemMeta(perkHelpButtonMeta);
kits.setItem(52, perkHelpButton);
kits.setItem(49, perkHelpButton);
player.openInventory(kits);
@@ -31,13 +31,13 @@ public class GetStats implements TabExecutor {
if (!(sender instanceof Player player)) {
return true;
}
if (!(args.length > 0)){
player.sendMessage("Provide a player!");
return false;
}
FileConfiguration playerStatsConfig = PlayerStatsConfig.get();
String argumentPlayer = args[0];
String argumentPlayer = player.getName();
if (args.length == 1){
argumentPlayer = args[0];
}
Set<String> allKeys = playerStatsConfig.getKeys(true);
if (!(allKeys.contains(argumentPlayer))){
player.sendMessage("That player does not have any stats attached to them.");
@@ -2,12 +2,14 @@ package me.lifelessnerd.purekitpvp.perks.perkCommand;
import me.lifelessnerd.purekitpvp.files.KitConfig;
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;
@@ -45,13 +47,17 @@ public class PerkCommand implements CommandExecutor {
player.sendMessage(ChatColor.RED + "You can only use this menu in " + ChatColor.GRAY + 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!");
return true;
}
//Create inventory GUI
TextComponent invTitle = Component.text("Perks Menu").color(TextColor.color(255, 150, 20));
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));
TextComponent infoItemName = Component.text("Perks Info").color(TextColor.color(233, 67, 47)).decoration(TextDecoration.ITALIC, false);
ItemMeta infoMeta = infoItem.getItemMeta();
infoMeta.displayName(infoItemName);
infoMeta = ComponentUtils.setLore(infoMeta, "&aYou can equip a total of &e5 &aperks total.", 0);
@@ -62,6 +68,14 @@ public class PerkCommand implements CommandExecutor {
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);
ItemMeta kitItemMeta = kitItem.getItemMeta();
kitItemMeta.displayName(kitItemName);
kitItem.setItemMeta(kitItemMeta);
perksInventory.setItem(49, kitItem);
//Fill perk slots with either empty or actual perk icon
for (int index = 20; index <= 24; index++){
@@ -69,9 +83,9 @@ public class PerkCommand implements CommandExecutor {
String fileContent = PerkData.get().getString(player.getName() + ".slot" + slot);
//System.out.println(fileContent);
if (fileContent == null){
// No perk selected in this slot; show red stained glass
// 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));
TextComponent perkSlotName = Component.text("Perk Slot " + slot).color(TextColor.color(233, 67, 47)).decoration(TextDecoration.ITALIC, false);
ItemMeta perkSlotMeta = perkSlot.getItemMeta();
perkSlotMeta.displayName(perkSlotName);
perkSlotMeta = ComponentUtils.setLore(perkSlotMeta, "&aClick to select a perk for this slot!", 0);
@@ -80,21 +94,21 @@ public class PerkCommand implements CommandExecutor {
} 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));
TextComponent perkSlotName = Component.text("Perk Slot " + slot).color(TextColor.color(233, 67, 47)).decoration(TextDecoration.ITALIC, false);
ItemMeta perkSlotMeta = perkSlot.getItemMeta();
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));
TextComponent 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)));
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)));
loreTBA.add(Component.text(perkLib.perks.get(fileContent)).color(TextColor.color(150, 150, 150)).decoration(TextDecoration.ITALIC, false));
}
perkSlotMeta.lore(loreTBA);
perkSlotMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
@@ -6,12 +6,16 @@ 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 net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
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;
@@ -24,10 +28,13 @@ import java.util.ArrayList;
public class PerkGUIListener implements Listener {
Plugin plugin;
public PerkGUIListener(Plugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
@@ -47,7 +54,7 @@ public class PerkGUIListener implements Listener {
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)));
//Create inventory GUI
@@ -60,9 +67,20 @@ public class PerkGUIListener implements Listener {
ItemStack icon = new ItemStack(perkLib.perkIcons.get(perk));
ItemMeta itemMeta = icon.getItemMeta();
itemMeta.displayName(Component.text(perk).color(TextColor.color(200, 0, 0)));
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
itemMeta.displayName(Component.text(perk).color(TextColor.color(200, 0, 0)).decoration(TextDecoration.ITALIC, false));
// Check if it is selected: if so add glint
for(String selectedPerkKey : PerkData.get().getConfigurationSection(player.getName()).getKeys(false)){
String selectedPerk = PerkData.get().getString(player.getName() + "." + selectedPerkKey);
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));
}
}
icon.setItemMeta(itemMeta);
ArrayList<Component> loreTBA = new ArrayList<>();
@@ -70,41 +88,62 @@ public class PerkGUIListener implements Listener {
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)));
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)));
loreTBA.add(Component.text(perkLib.perks.get(perk)).color(TextColor.color(150, 150, 150)).decoration(TextDecoration.ITALIC, false));
}
icon.lore(loreTBA);
perkSlotInventory.addItem(icon);
}
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.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
backButton.setItemMeta(backButtonMeta);
perkSlotInventory.setItem(49,backButton);
player.openInventory(perkSlotInventory);
}
else if (itemName.contains("Back to Kits")){
inv.close();
player.chat("/kit");
}
}
else if (inv.title().toString().contains("Perk Slot")){
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();
player.chat("/perks");
} else {
int slot = Integer.parseInt(String.valueOf(itemName.charAt(itemName.length() - 1)));
ItemStack clickedPerk = e.getCurrentItem();
String displayName = serializer.serialize(clickedPerk.displayName());
displayName = displayName.substring(1, displayName.length() - 1);
PerkData.setPerk(player, displayName, slot);
PerkData.save();
PerkData.reload();
int slot = Integer.parseInt(String.valueOf(itemName.charAt(itemName.length() - 1)));
ItemStack clickedPerk = e.getCurrentItem();
String displayName = serializer.serialize(clickedPerk.displayName());
displayName = displayName.substring(1, displayName.length() - 1);
PerkData.setPerk(player, displayName, slot);
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1,0);
PerkData.save();
PerkData.reload();
inv.close();
player.chat("/perks");
inv.close();
player.chat("/perks");
}
}
}
}
@@ -4,19 +4,23 @@ import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import me.lifelessnerd.purekitpvp.files.KitConfig;
import me.lifelessnerd.purekitpvp.files.PerkData;
import me.lifelessnerd.purekitpvp.files.PlayerStatsConfig;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.entity.*;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
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;
@@ -30,19 +34,26 @@ public class PerkFireHandler {
PerkFireHandler.plugin = plugin;
}
public static void fireKillPerks(Player player){
public static Set<String> getPerks(Player player) {
ConfigurationSection playerPerks = PerkData.get().getConfigurationSection(player.getName());
if (playerPerks == null){
return;
return new HashSet<>(); // No perks? Return empty set; this way nothing happens
}
Set<String> perkSlots = playerPerks.getKeys(false);
Set<String> perks = new HashSet<>();
for (String perkSlot : perkSlots){
perks.add(playerPerks.getString(perkSlot));
}
return perks;
}
public static void fireKillPerks(Player player){
Set<String> perks = getPerks(player);
for(String perk : perks){
//System.out.println(perk);
switch(perk){
@@ -52,7 +63,7 @@ public class PerkFireHandler {
break;
case "BULLDOZER":
player.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 100, 1));
player.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 60, 1));
break;
case "KNOWLEDGE":
@@ -60,9 +71,10 @@ public class PerkFireHandler {
break;
case "NOTORIETY":
if(Math.random() <= 0.1) {
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);
if (plugin.getConfig().getInt("notoriety-maximum") != -1){
@@ -89,26 +101,65 @@ public class PerkFireHandler {
break;
case "SPEEDSTER":
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 200, 2));
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);
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.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!");
}
break;
}
}
}
public static void fireRangedPerks(EntityDamageByEntityEvent event, Player damager){
Set<String> perks = getPerks(damager);
for(String perk : perks){
//System.out.println(perk);
switch(perk){
case "APOLLO":
// Event is already Arrow on Player; damager has already been extracted out of the event
if (event.getDamager() instanceof SpectralArrow arrow){
ItemStack arrowItem = arrow.getItemStack();
arrowItem.setAmount(1);
damager.getInventory().addItem(arrowItem);
} else {
Arrow arrow = (Arrow) event.getDamager();
ItemStack arrowItem = arrow.getItemStack();
arrowItem.setAmount(1);
damager.getInventory().addItem(arrowItem);
}
damager.playSound(damager.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1,0);
break;
}
}
}
public static void fireCombatPerks(Player damaged, Player damager){
ConfigurationSection playerPerks = PerkData.get().getConfigurationSection(damager.getName());
Set<String> perks = getPerks(damager);
if (playerPerks == null){
return;
}
Set<String> perkSlots = playerPerks.getKeys(false);
Set<String> perks = new HashSet<>();
for (String perkSlot : perkSlots){
perks.add(playerPerks.getString(perkSlot));
}
for(String perk : perks){
switch(perk){
@@ -148,17 +199,9 @@ public class PerkFireHandler {
}
public static void fireVampirePerk(EntityDamageByEntityEvent event) {
ConfigurationSection playerPerks = PerkData.get().getConfigurationSection(event.getDamager().getName());
Player player = (Player) event.getDamager();
if (playerPerks == null){
return;
}
Set<String> perks = getPerks(player);
Set<String> perkSlots = playerPerks.getKeys(false);
Set<String> perks = new HashSet<>();
for (String perkSlot : perkSlots){
perks.add(playerPerks.getString(perkSlot));
}
for(String perk : perks){
if (perk.equalsIgnoreCase("VAMPIRE")){
@@ -183,27 +226,22 @@ public class PerkFireHandler {
}
public static void fireSnowballPerks(Player damaged, Player shooter) {
ConfigurationSection playerPerks = PerkData.get().getConfigurationSection(shooter.getName());
public static void fireSnowballPerks(ProjectileHitEvent event, Player damaged, Player shooter) {
if (playerPerks == null){
return;
}
Set<String> perkSlots = playerPerks.getKeys(false);
Set<String> perks = new HashSet<>();
for (String perkSlot : perkSlots){
perks.add(playerPerks.getString(perkSlot));
}
Set<String> perks = getPerks(shooter);
for(String perk : perks){
switch(perk){
case "SNOWMAN":
damaged.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 60, 0));
if (event.getEntity() instanceof Snowball) {
damaged.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 60, 0));
}
break;
case "DISRUPTOR":
damaged.addPotionEffect(new PotionEffect(PotionEffectType.POISON, 80, 0));
if (event.getEntity() instanceof Egg) {
damaged.addPotionEffect(new PotionEffect(PotionEffectType.POISON, 80, 0));
}
break;
}
@@ -211,30 +249,29 @@ public class PerkFireHandler {
}
public static void fireEnderpearlPerks(Player player, PlayerLaunchProjectileEvent event) {
ConfigurationSection playerPerks = PerkData.get().getConfigurationSection(player.getName());
if (playerPerks == null){
return;
}
Set<String> perkSlots = playerPerks.getKeys(false);
Set<String> perks = new HashSet<>();
for (String perkSlot : perkSlots){
perks.add(playerPerks.getString(perkSlot));
}
Set<String> perks = getPerks(player);
for(String perk : perks){
switch(perk){
case "ENDERMAN":
Block lookingAt = event.getPlayer().getTargetBlock(50);
player.teleport(lookingAt.getLocation());
event.setCancelled(true);
int epAmount = player.getInventory().getItemInMainHand().getAmount();
ItemStack toBeGiven = player.getInventory().getItemInMainHand();
toBeGiven.setAmount(epAmount - 1);
player.getInventory().setItemInMainHand(toBeGiven);
new BukkitRunnable() {
@Override
public void run() {
for (Entity en : event.getPlayer().getNearbyEntities(2, 2, 2)) {
//This has to be here; event.getProjectile does not work; idk why https://www.spigotmc.org/threads/ride-enderpearl.263710/
if (en.getType() == EntityType.ENDER_PEARL) {
en.addPassenger(event.getPlayer());
}
}
}
}.runTaskLater(plugin, 1);
break;
@@ -245,4 +282,40 @@ public class PerkFireHandler {
}
public static void fireHealthPerks(Player player){
Set<String> perks = getPerks(player);
for(String perk : perks) {
switch (perk) {
case "ADRENALINE":
if (player.getHealth() >= 6){
player.setWalkSpeed(0.2f);
break;
}
player.setWalkSpeed(0.3f);
}
}
}
public static void fireEnderpearlDamagePerks(Player player, EntityDamageByEntityEvent event){
Set<String> perks = getPerks(player);
for(String perk : perks) {
switch (perk) {
case "ENDERMAN":
event.setCancelled(true); // Negates not only the damage but also the tick
break;
}
}
}
}
@@ -12,16 +12,19 @@ public class PerkLib {
public PerkLib(){
perks.put("JUGGERNAUT", "Gain regeneration 1 (5s) after every kill");
perks.put("BULLDOZER", "Gain strength 2 (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","10% chance of gaining a sharpness level on each kill\nSharpness will be added to the item held");
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", "Ender pearls behave differently, teleporting on\nclick, to the location you are looking at, max 50 blocks away\nThey do no damage");
perks.put("VAMPIRE", "On critical hits, gain 50% of the damage\nyou dealt as regeneration");
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");
perkIcons.put("JUGGERNAUT" , Material.DIAMOND_CHESTPLATE);
perkIcons.put("BULLDOZER" , Material.ANVIL);
@@ -34,5 +37,8 @@ public class PerkLib {
perkIcons.put("DISRUPTOR", Material.EGG);
perkIcons.put("ENDERMAN", Material.ENDER_EYE);
perkIcons.put("VAMPIRE", Material.REDSTONE);
perkIcons.put("MARKSMAN", Material.BOW);
perkIcons.put("APOLLO", Material.ARROW);
perkIcons.put("ADRENALINE", Material.GHAST_TEAR);
}
}
@@ -4,6 +4,7 @@ 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.inventory.meta.ItemMeta;
import java.util.ArrayList;
@@ -11,7 +12,7 @@ import java.util.List;
public class ComponentUtils {
public static ItemMeta setLore(ItemMeta itemMeta, String lore, int line){ //TODO: needs testing
public static ItemMeta setLore(ItemMeta itemMeta, String lore, int line){
List<Component> currentLore = null;
if (itemMeta.hasLore()){
currentLore = itemMeta.lore();
@@ -107,7 +108,7 @@ public class ComponentUtils {
}
textComponent = textComponent.append(Component.text(
toBeAdded.toString()).color(lastColor));
toBeAdded.toString()).color(lastColor)).decoration(TextDecoration.ITALIC, false);
return textComponent;
}
}
@@ -1,5 +1,8 @@
package me.lifelessnerd.purekitpvp.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
public class MyStringUtils {
public static String itemCamelCase(String string){
@@ -37,7 +40,8 @@ public class MyStringUtils {
String[] splitAgain = word.split(",");
String levelString = splitAgain[1];
int level = Integer.parseInt(String.valueOf(levelString.charAt(levelString.length() - 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(" ");
@@ -115,4 +119,24 @@ public class MyStringUtils {
return output;
}
public static String itemNameToCosmeticId(String input){
String processed = input.toLowerCase();
processed = processed.replace(' ', '_');
return processed;
}
// Opposite of function above
public static String cosmeticIdToItemName(String input){
// Input: blood_explosion -> Blood Explosion
return itemCamelCase(input).trim();
}
public static String componentToString(Component singleLineComponent){
PlainTextComponentSerializer serializer = PlainTextComponentSerializer.plainText();
String processed = serializer.serialize(singleLineComponent);
processed = processed.substring(1, processed.length() - 1);
return processed;
}
}
+33 -5
View File
@@ -1,21 +1,24 @@
# PureKitPvP by LifelessNerd
# Made to work with PureKits kit files
# 2022
# 2022 - 2023
# World in which the plugin should be active: i.e. kits, deaths, stats and such
world: pvp
#Quick kill when falling in void, only works when suicide-command is enabled
quick-voidkill: true
#If above true, Y level at which you should die in pvp, please provide double
#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
#respawn X, Y, Z in world
#respawn X, Y, Z in world, this is basically the spawn region
respawnX: 0.5
respawnY: 142.0
respawnZ: 0.5
#Whether people who get a killstreak will get glowing effect
# Spawn region radius; you won't get fall damage in this area (square area relative to respawnX and respawnZ)
spawn-radius: 6
#Whether people who get a kill streak will get glowing effect
killstreak-glowing: true
#If above true, the duration in seconds
killstreak-glowing-duration: 100
@@ -23,7 +26,32 @@ killstreak-glowing-duration: 100
#Suicide command from PureKitPvP, ensures death recaps work correctly
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
#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-maximum: -1
#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
#Default kill effect
default-kill-effect: "firework"
#Default projectile trail
default-projectile-trail: "none"
# 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
# Chicken prevention: kits with eggs might spawn chicken; when this is true they are prevented from spawning
chicken-prevention: true
+6 -3
View File
@@ -2,8 +2,8 @@ name: PureKitPvP
version: '${project.version}'
main: me.lifelessnerd.purekitpvp.PureKitPvP
api-version: 1.19
authors: [ LifelessNerd, PsionicPvP ]
description: KitPVP plugin, with kit functionality from PureKits (abandoned)
authors: [ LifelessNerd ]
description: KitPVP plugin, made to work with PureKits kits (abandoned)
commands:
getkit:
description: Gives you a kit.
@@ -22,7 +22,7 @@ commands:
- pvpstats
purekitpvp:
description: All admin commands. See documentation for help.
usage: /purekitpvp <createkit/deletekit/kitstats/setkillitem/setperk/getcustomitem/createloottable/reload>
usage: /purekitpvp <createkit/deletekit/kitstats/setkillitem/getcustomitem/createloottable/reload/help/info>
aliases:
- kitpvp
- pkpvp
@@ -37,6 +37,9 @@ commands:
usage: /perk
aliases:
- perk
cosmetics:
description: Open cosmetics menu
usage: /cosmetics