mirror of
https://github.com/TotalFreedomMC/PlayerParticles.git
synced 2025-02-11 03:29:53 +00:00
Add some quality of life changes
This commit is contained in:
parent
e5f5760fb1
commit
f306062bfa
25 changed files with 442 additions and 88 deletions
|
@ -1,5 +1,17 @@
|
|||
== UPDATING WILL DELETE YOUR CONFIG.YML ==
|
||||
* Create a backup of your config.yml if you wish to import all your old settings!
|
||||
=== v6.3 (Implemented so far) ===
|
||||
+ Added the ability to remove particles by id/effect/style using '/pp remove <id>|<effect>|<style>'
|
||||
+ The "Save New Group" button in the GUI now actually saves a new group and prompts for a name in chat (15 second timeout)
|
||||
+ Added a click sound to the GUI for button clicks (Can be disabled in the config.yml)
|
||||
* Reduced the number of particles that spawn for the styles 'blockbreak', 'blockplace', and 'swords'
|
||||
* Fix GUI borders showing up as glass panes instead of stained glass panes on servers running 1.12.2 or earlier
|
||||
* Fix a console error that occurs when trying to remove a group that doesn't exist
|
||||
* Fix "[PlayerParticles] An error occurred retrieving an SQLite database connection: [SQLITE_BUSY] The database file is locked (database is locked)"
|
||||
=== v6.2 ===
|
||||
+ Added command '/ppo' which allows executing a /pp command as another player.
|
||||
* Fix not being able to change the lore of the player skull in the GUI
|
||||
* Fix the 'saved groups' count on the player skull in the GUI being one higher than it was supposed to be
|
||||
=== v6.1 ===
|
||||
* Fix a bug where sometimes the GUI was unable to be opened due to an error
|
||||
* You can now use \n on the GUI lore lines in the *.lang file to break them into multiple lines
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -2,7 +2,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.esophose.playerparticles</groupId>
|
||||
<artifactId>PlayerParticles</artifactId>
|
||||
<version>6.2</version>
|
||||
<version>6.3</version>
|
||||
<name>PlayerParticles</name>
|
||||
<url>https://github.com/Esophose/PlayerParticles</url>
|
||||
<description>Display particles around your player using customized styles and data!</description>
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
/*
|
||||
* TODO: v6.4+
|
||||
* + Add new style(s) 'wings_<type>', multiple new wing types: fairy, demon
|
||||
* + Add ability to create/manage fixed effects from the GUI (may get implemented later)
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: v6.3
|
||||
* + Add new style 'tornado'
|
||||
* + Add new style 'doubleorbit'
|
||||
* + Add new style(s) 'wings_<type>', multiple new wing types: fairy, demon
|
||||
* + Add named colors to the color data
|
||||
* * Display effects/styles in the GUI formatted to be more readable
|
||||
* + Possibly add a couple new styles (tornado, doubleorbit)
|
||||
*/
|
||||
|
||||
package com.esophose.playerparticles;
|
||||
|
@ -12,6 +18,7 @@ import java.io.File;
|
|||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
@ -21,6 +28,7 @@ import com.esophose.playerparticles.database.DatabaseConnector;
|
|||
import com.esophose.playerparticles.database.MySqlDatabaseConnector;
|
||||
import com.esophose.playerparticles.database.SqliteDatabaseConnector;
|
||||
import com.esophose.playerparticles.gui.GuiHandler;
|
||||
import com.esophose.playerparticles.gui.hook.PlayerChatHook;
|
||||
import com.esophose.playerparticles.manager.LangManager;
|
||||
import com.esophose.playerparticles.manager.ParticleManager;
|
||||
import com.esophose.playerparticles.manager.SettingManager;
|
||||
|
@ -59,10 +67,12 @@ public class PlayerParticles extends JavaPlugin {
|
|||
|
||||
this.registerCommands();
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new ParticleManager(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new PluginUpdateListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new GuiHandler(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new PPlayerMovementListener(), this);
|
||||
PluginManager pm = Bukkit.getPluginManager();
|
||||
pm.registerEvents(new ParticleManager(), this);
|
||||
pm.registerEvents(new PluginUpdateListener(), this);
|
||||
pm.registerEvents(new GuiHandler(), this);
|
||||
pm.registerEvents(new PPlayerMovementListener(), this);
|
||||
pm.registerEvents(new PlayerChatHook(), this);
|
||||
|
||||
saveDefaultConfig();
|
||||
double configVersion = PSetting.VERSION.getDouble();
|
||||
|
@ -153,6 +163,7 @@ public class PlayerParticles extends JavaPlugin {
|
|||
ParticleGroup.reload();
|
||||
|
||||
GuiHandler.setup();
|
||||
PlayerChatHook.setup();
|
||||
|
||||
ParticleManager.refreshData();
|
||||
startParticleTask();
|
||||
|
|
|
@ -176,8 +176,8 @@ public class GroupCommandModule implements CommandModule {
|
|||
group = ParticleGroup.getPresetGroup(groupName);
|
||||
if (group != null) {
|
||||
LangManager.sendMessage(pplayer, Lang.GROUP_REMOVE_PRESET);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the group and notify player
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package com.esophose.playerparticles.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import com.esophose.playerparticles.manager.DataManager;
|
||||
import com.esophose.playerparticles.manager.LangManager;
|
||||
import com.esophose.playerparticles.manager.LangManager.Lang;
|
||||
import com.esophose.playerparticles.particles.PPlayer;
|
||||
import com.esophose.playerparticles.particles.ParticleEffect;
|
||||
import com.esophose.playerparticles.particles.ParticleGroup;
|
||||
import com.esophose.playerparticles.particles.ParticlePair;
|
||||
import com.esophose.playerparticles.styles.api.ParticleStyle;
|
||||
|
||||
public class RemoveCommandModule implements CommandModule {
|
||||
|
||||
|
@ -20,48 +25,92 @@ public class RemoveCommandModule implements CommandModule {
|
|||
return;
|
||||
}
|
||||
|
||||
int id = -1;
|
||||
try {
|
||||
id = Integer.parseInt(args[0]);
|
||||
} catch (Exception ex) {
|
||||
LangManager.sendMessage(pplayer, Lang.ID_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id <= 0) {
|
||||
LangManager.sendMessage(pplayer, Lang.ID_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean removed = false;
|
||||
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
|
||||
for (ParticlePair particle : activeGroup.getParticles()) {
|
||||
if (particle.getId() == id) {
|
||||
activeGroup.getParticles().remove(particle);
|
||||
removed = true;
|
||||
break;
|
||||
if (StringUtils.isNumeric(args[0])) { // Removing by ID
|
||||
int id = -1;
|
||||
try {
|
||||
id = Integer.parseInt(args[0]);
|
||||
} catch (Exception ex) {
|
||||
LangManager.sendMessage(pplayer, Lang.ID_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id <= 0) {
|
||||
LangManager.sendMessage(pplayer, Lang.ID_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean removed = false;
|
||||
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
|
||||
for (ParticlePair particle : activeGroup.getParticles()) {
|
||||
if (particle.getId() == id) {
|
||||
activeGroup.getParticles().remove(particle);
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removed) {
|
||||
LangManager.sendMessage(pplayer, Lang.ID_UNKNOWN, id);
|
||||
return;
|
||||
}
|
||||
|
||||
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_ID_SUCCESS, id);
|
||||
} else { // Removing by effect/style name
|
||||
ParticleEffect effect = ParticleEffect.fromName(args[0]);
|
||||
ParticleStyle style = ParticleStyle.fromName(args[0]);
|
||||
|
||||
if (effect != null) {
|
||||
int removedCount = 0;
|
||||
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
|
||||
for (int i = activeGroup.getParticles().size() - 1; i >= 0; i--) {
|
||||
if (activeGroup.getParticles().get(i).getEffect() == effect) {
|
||||
activeGroup.getParticles().remove(i);
|
||||
removedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (removedCount > 0) {
|
||||
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_EFFECT_SUCCESS, removedCount, effect.getName());
|
||||
} else {
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_EFFECT_NONE, effect.getName());
|
||||
}
|
||||
} else if (style != null) {
|
||||
int removedCount = 0;
|
||||
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
|
||||
for (int i = activeGroup.getParticles().size() - 1; i >= 0; i--) {
|
||||
if (activeGroup.getParticles().get(i).getStyle() == style) {
|
||||
activeGroup.getParticles().remove(i);
|
||||
removedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (removedCount > 0) {
|
||||
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_STYLE_SUCCESS, removedCount, style.getName());
|
||||
} else {
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_STYLE_NONE, style.getName());
|
||||
}
|
||||
} else {
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_UNKNOWN, args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!removed) {
|
||||
LangManager.sendMessage(pplayer, Lang.ID_UNKNOWN, id);
|
||||
return;
|
||||
}
|
||||
|
||||
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
|
||||
LangManager.sendMessage(pplayer, Lang.REMOVE_SUCCESS, id);
|
||||
}
|
||||
|
||||
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
|
||||
List<String> matches = new ArrayList<String>();
|
||||
List<String> ids = new ArrayList<String>();
|
||||
|
||||
for (ParticlePair particles : pplayer.getActiveParticles())
|
||||
ids.add(String.valueOf(particles.getId()));
|
||||
|
||||
if (args.length == 0) return ids;
|
||||
|
||||
StringUtil.copyPartialMatches(args[0], ids, matches);
|
||||
Set<String> removeBy = new HashSet<String>();
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticles()) {
|
||||
removeBy.add(String.valueOf(particle.getId()));
|
||||
removeBy.add(particle.getEffect().getName());
|
||||
removeBy.add(particle.getStyle().getName());
|
||||
}
|
||||
|
||||
if (args.length == 0) return new ArrayList<String>(removeBy);
|
||||
|
||||
StringUtil.copyPartialMatches(args[0], removeBy, matches);
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.esophose.playerparticles.PlayerParticles;
|
|||
public class SqliteDatabaseConnector implements DatabaseConnector {
|
||||
|
||||
private final String connectionString;
|
||||
private Connection connection;
|
||||
|
||||
public SqliteDatabaseConnector(String directory) {
|
||||
this.connectionString = "jdbc:sqlite:" + directory + File.separator + "playerparticles.db";
|
||||
|
@ -20,14 +21,28 @@ public class SqliteDatabaseConnector implements DatabaseConnector {
|
|||
}
|
||||
|
||||
public void closeConnection() {
|
||||
// Nothing to do
|
||||
try {
|
||||
if (this.connection != null) {
|
||||
this.connection.close();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
PlayerParticles.getPlugin().getLogger().severe("An error occurred closing the SQLite database connection: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void connect(ConnectionCallback callback) {
|
||||
try (Connection connection = DriverManager.getConnection(this.connectionString)) {
|
||||
callback.execute(connection);
|
||||
if (this.connection == null) {
|
||||
try {
|
||||
this.connection = DriverManager.getConnection(this.connectionString);
|
||||
} catch (SQLException ex) {
|
||||
PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving the SQLite database connection: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
callback.execute(this.connection);
|
||||
} catch (SQLException ex) {
|
||||
PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving an SQLite database connection: " + ex.getMessage());
|
||||
PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving the SQLite database connection: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,15 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
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 com.esophose.playerparticles.manager.SettingManager.PSetting;
|
||||
import com.esophose.playerparticles.particles.PPlayer;
|
||||
import com.esophose.playerparticles.util.ParticleUtils;
|
||||
|
||||
|
@ -36,7 +39,7 @@ public abstract class GuiInventory {
|
|||
if (this.material != null) { // Use 1.13 materials
|
||||
borderIcon = new ItemStack(this.material, 1);
|
||||
} else { // Use < 1.13 data values
|
||||
borderIcon = new ItemStack(ParticleUtils.closestMatch("THIN_GLASS"), 1, this.data);
|
||||
borderIcon = new ItemStack(ParticleUtils.closestMatch("STAINED_GLASS_PANE"), 1, this.data);
|
||||
}
|
||||
|
||||
ItemMeta meta = borderIcon.getItemMeta();
|
||||
|
@ -137,6 +140,12 @@ public abstract class GuiInventory {
|
|||
for (GuiActionButton button : this.actionButtons) {
|
||||
if (button.getSlot() == slot) {
|
||||
button.handleClick(button, isShiftClick);
|
||||
if (PSetting.GUI_BUTTON_SOUND.getBoolean()) {
|
||||
if (event.getWhoClicked() instanceof Player) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
|
|||
import com.esophose.playerparticles.particles.PPlayer;
|
||||
import com.esophose.playerparticles.particles.ParticleEffect;
|
||||
import com.esophose.playerparticles.particles.ParticlePair;
|
||||
import com.esophose.playerparticles.util.ParticleUtils;
|
||||
|
||||
public class GuiInventoryEditEffect extends GuiInventory {
|
||||
|
||||
|
@ -23,8 +24,8 @@ public class GuiInventoryEditEffect extends GuiInventory {
|
|||
ParticleEffect effect = effectsUserHasPermissionFor.get(i);
|
||||
GuiActionButton selectButton = new GuiActionButton(i,
|
||||
GuiIcon.EFFECT.get(effect.getName()),
|
||||
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + effect.getName(),
|
||||
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, effect.getName()) },
|
||||
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ParticleUtils.formatName(effect.getName()),
|
||||
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, ParticleUtils.formatName(effect.getName())) },
|
||||
(button, isShiftClick) -> {
|
||||
editingParticle.setEffect(effect);
|
||||
callbackList.get(callbackListPosition + 1).execute();
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
|
|||
import com.esophose.playerparticles.particles.PPlayer;
|
||||
import com.esophose.playerparticles.particles.ParticlePair;
|
||||
import com.esophose.playerparticles.styles.api.ParticleStyle;
|
||||
import com.esophose.playerparticles.util.ParticleUtils;
|
||||
|
||||
public class GuiInventoryEditStyle extends GuiInventory {
|
||||
|
||||
|
@ -23,8 +24,8 @@ public class GuiInventoryEditStyle extends GuiInventory {
|
|||
ParticleStyle style = stylesUserHasPermissionFor.get(i);
|
||||
GuiActionButton selectButton = new GuiActionButton(i,
|
||||
GuiIcon.STYLE.get(style.getName()),
|
||||
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + style.getName(),
|
||||
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, style.getName()) },
|
||||
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ParticleUtils.formatName(style.getName()),
|
||||
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, ParticleUtils.formatName(style.getName())) },
|
||||
(button, isShiftClick) -> {
|
||||
editingParticle.setStyle(style);
|
||||
callbackList.get(callbackListPosition + 1).execute();
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
|
|||
import com.esophose.playerparticles.particles.PPlayer;
|
||||
import com.esophose.playerparticles.particles.ParticleGroup;
|
||||
import com.esophose.playerparticles.particles.ParticlePair;
|
||||
import com.esophose.playerparticles.util.ParticleUtils;
|
||||
|
||||
public class GuiInventoryLoadPresetGroups extends GuiInventory {
|
||||
|
||||
|
@ -36,7 +37,7 @@ public class GuiInventoryLoadPresetGroups extends GuiInventory {
|
|||
lore[0] = LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_LOAD, particles.size());
|
||||
int i = 1;
|
||||
for (ParticlePair particle : particles) {
|
||||
lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), particle.getEffect().getName(), particle.getStyle().getName(), particle.getDataString());
|
||||
lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), ParticleUtils.formatName(particle.getEffect().getName()), ParticleUtils.formatName(particle.getStyle().getName()), particle.getDataString());
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package com.esophose.playerparticles.gui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import com.esophose.playerparticles.gui.hook.PlayerChatHook;
|
||||
import com.esophose.playerparticles.gui.hook.PlayerChatHookData;
|
||||
import com.esophose.playerparticles.manager.DataManager;
|
||||
import com.esophose.playerparticles.manager.LangManager;
|
||||
import com.esophose.playerparticles.manager.PermissionManager;
|
||||
import com.esophose.playerparticles.manager.LangManager.Lang;
|
||||
import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
|
||||
import com.esophose.playerparticles.particles.PPlayer;
|
||||
import com.esophose.playerparticles.particles.ParticleGroup;
|
||||
import com.esophose.playerparticles.particles.ParticlePair;
|
||||
import com.esophose.playerparticles.util.ParticleUtils;
|
||||
|
||||
public class GuiInventoryManageGroups extends GuiInventory {
|
||||
|
||||
|
@ -36,7 +41,7 @@ public class GuiInventoryManageGroups extends GuiInventory {
|
|||
lore[0] = LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_LOAD, particles.size());
|
||||
int i = 1;
|
||||
for (ParticlePair particle : particles) {
|
||||
lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), particle.getEffect().getName(), particle.getStyle().getName(), particle.getDataString());
|
||||
lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), ParticleUtils.formatName(particle.getEffect().getName()), ParticleUtils.formatName(particle.getStyle().getName()), particle.getDataString());
|
||||
i++;
|
||||
}
|
||||
lore[i] = LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SHIFT_CLICK_TO_DELETE);
|
||||
|
@ -68,15 +73,67 @@ public class GuiInventoryManageGroups extends GuiInventory {
|
|||
if (index > maxIndex) break; // Overflowed the available space
|
||||
}
|
||||
|
||||
boolean canSaveGroup = !PermissionManager.hasPlayerReachedMaxGroups(pplayer);
|
||||
String[] lore;
|
||||
if (canSaveGroup) {
|
||||
lore = new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION) };
|
||||
} else {
|
||||
lore = new String[] {
|
||||
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION),
|
||||
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SAVE_GROUP_FULL)
|
||||
};
|
||||
}
|
||||
|
||||
// Save Group Button
|
||||
GuiActionButton saveGroupButton = new GuiActionButton(40,
|
||||
GuiIcon.CREATE.get(),
|
||||
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SAVE_GROUP),
|
||||
new String[] {
|
||||
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION),
|
||||
LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION_2),
|
||||
},
|
||||
(button, isShiftClick) -> {}); // Does nothing on click
|
||||
lore,
|
||||
(button, isShiftClick) -> {
|
||||
if (!canSaveGroup) return;
|
||||
|
||||
PlayerChatHook.addHook(new PlayerChatHookData(pplayer.getUniqueId(), 15, (textEntered) -> {
|
||||
if (textEntered == null || textEntered.equalsIgnoreCase("cancel")) {
|
||||
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
|
||||
} else {
|
||||
String groupName = textEntered.split(" ")[0];
|
||||
|
||||
// Check that the groupName isn't the reserved name
|
||||
if (groupName.equalsIgnoreCase(ParticleGroup.DEFAULT_NAME)) {
|
||||
LangManager.sendMessage(pplayer, Lang.GROUP_RESERVED);
|
||||
return;
|
||||
}
|
||||
|
||||
// The database column can only hold up to 100 characters, cut it off there
|
||||
if (groupName.length() >= 100) {
|
||||
groupName = groupName.substring(0, 100);
|
||||
}
|
||||
|
||||
// Use the existing group if available, otherwise create a new one
|
||||
ParticleGroup group = pplayer.getParticleGroupByName(groupName);
|
||||
boolean groupUpdated = false;
|
||||
if (group == null) {
|
||||
List<ParticlePair> particles = new ArrayList<ParticlePair>();
|
||||
for (ParticlePair particle : pplayer.getActiveParticles())
|
||||
particles.add(particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group
|
||||
group = new ParticleGroup(groupName, particles);
|
||||
} else {
|
||||
groupUpdated = true;
|
||||
}
|
||||
|
||||
// Apply changes and notify player
|
||||
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
|
||||
if (groupUpdated) {
|
||||
LangManager.sendMessage(pplayer, Lang.GROUP_SAVE_SUCCESS_OVERWRITE, groupName);
|
||||
} else {
|
||||
LangManager.sendMessage(pplayer, Lang.GROUP_SAVE_SUCCESS, groupName);
|
||||
}
|
||||
|
||||
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
|
||||
}
|
||||
}));
|
||||
pplayer.getPlayer().closeInventory();
|
||||
});
|
||||
this.actionButtons.add(saveGroupButton);
|
||||
|
||||
// Back Button
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.esophose.playerparticles.particles.PPlayer;
|
|||
import com.esophose.playerparticles.particles.ParticleGroup;
|
||||
import com.esophose.playerparticles.particles.ParticlePair;
|
||||
import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty;
|
||||
import com.esophose.playerparticles.util.ParticleUtils;
|
||||
|
||||
public class GuiInventoryManageParticles extends GuiInventory {
|
||||
|
||||
|
@ -36,7 +37,7 @@ public class GuiInventoryManageParticles extends GuiInventory {
|
|||
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_PARTICLE_NAME, particle.getId()),
|
||||
new String[] {
|
||||
LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_EDIT_PARTICLE, particles.size()),
|
||||
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), particle.getEffect().getName(), particle.getStyle().getName(), particle.getDataString()),
|
||||
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), ParticleUtils.formatName(particle.getEffect().getName()), ParticleUtils.formatName(particle.getStyle().getName()), particle.getDataString()),
|
||||
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SHIFT_CLICK_TO_DELETE)
|
||||
},
|
||||
(button, isShiftClick) -> {
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package com.esophose.playerparticles.gui.hook;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import com.esophose.playerparticles.PlayerParticles;
|
||||
import com.esophose.playerparticles.manager.LangManager;
|
||||
import com.esophose.playerparticles.manager.LangManager.Lang;
|
||||
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
|
||||
public class PlayerChatHook extends BukkitRunnable implements Listener {
|
||||
|
||||
private static Set<PlayerChatHookData> hooks;
|
||||
private static BukkitTask hookTask = null;
|
||||
|
||||
/**
|
||||
* Initializes all the static values for this class
|
||||
*/
|
||||
public static void setup() {
|
||||
hooks = new HashSet<PlayerChatHookData>();
|
||||
if (hookTask != null)
|
||||
hookTask.cancel();
|
||||
hookTask = new PlayerChatHook().runTaskTimer(PlayerParticles.getPlugin(), 0, 20);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when a player sends a message in chat
|
||||
*
|
||||
* @param event The AsyncPlayerChatEvent
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
for (PlayerChatHookData hook : hooks) {
|
||||
if (hook.getPlayerUUID().equals(event.getPlayer().getUniqueId())) {
|
||||
event.setCancelled(true);
|
||||
hook.triggerCallback(event.getMessage());
|
||||
hooks.remove(hook);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ticked every second to decrease the seconds remaining on each hook
|
||||
*/
|
||||
public void run() {
|
||||
Set<PlayerChatHookData> hooksToRemove = new HashSet<PlayerChatHookData>();
|
||||
|
||||
for (PlayerChatHookData hook : hooks) {
|
||||
hook.decrementHookLength();
|
||||
if (hook.timedOut()) {
|
||||
hook.triggerCallback(null);
|
||||
hooksToRemove.add(hook);
|
||||
continue;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(hook.getPlayerUUID());
|
||||
if (player == null) {
|
||||
hooksToRemove.remove(hook);
|
||||
} else {
|
||||
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining())));
|
||||
}
|
||||
}
|
||||
|
||||
for (PlayerChatHookData hookToRemove : hooksToRemove)
|
||||
hooks.remove(hookToRemove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a player chat hook
|
||||
*
|
||||
* @param newHook The new hook to add
|
||||
*/
|
||||
public static void addHook(PlayerChatHookData newHook) {
|
||||
for (PlayerChatHookData hook : hooks) {
|
||||
if (hook.getPlayerUUID().equals(hook.getPlayerUUID())) {
|
||||
hooks.remove(hook);
|
||||
break;
|
||||
}
|
||||
}
|
||||
hooks.add(newHook);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.esophose.playerparticles.gui.hook;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerChatHookData {
|
||||
|
||||
private UUID playerUUID;
|
||||
private int hookLength;
|
||||
private PlayerChatHookCallback hookCallback;
|
||||
|
||||
public PlayerChatHookData(UUID playerUUID, int hookLength, PlayerChatHookCallback hookCallback) {
|
||||
this.playerUUID = playerUUID;
|
||||
this.hookLength = hookLength;
|
||||
this.hookCallback = hookCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owning player of this hook
|
||||
*
|
||||
* @return The player's UUID
|
||||
*/
|
||||
public UUID getPlayerUUID() {
|
||||
return this.playerUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the time remaining on this hook by 1 second
|
||||
*/
|
||||
public void decrementHookLength() {
|
||||
this.hookLength--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this hook has timed out
|
||||
*
|
||||
* @return If this hook has timed out
|
||||
*/
|
||||
public boolean timedOut() {
|
||||
return this.hookLength <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets how much time is remaining on the hook
|
||||
*
|
||||
* @return The amount of time remaining on the hook
|
||||
*/
|
||||
public int getTimeRemaining() {
|
||||
return this.hookLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the callback function
|
||||
*
|
||||
* @param textEntered The text that was entered by the player
|
||||
*/
|
||||
public void triggerCallback(String textEntered) {
|
||||
this.hookCallback.onPlayerChat(textEntered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows simple hooking into the player chat for a specific time interval
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public static interface PlayerChatHookCallback {
|
||||
public void onPlayerChat(String textEntered);
|
||||
}
|
||||
|
||||
}
|
|
@ -112,7 +112,12 @@ public class LangManager {
|
|||
|
||||
// Remove Command
|
||||
REMOVE_NO_ARGS,
|
||||
REMOVE_SUCCESS,
|
||||
REMOVE_ID_SUCCESS,
|
||||
REMOVE_EFFECT_SUCCESS,
|
||||
REMOVE_EFFECT_NONE,
|
||||
REMOVE_STYLE_SUCCESS,
|
||||
REMOVE_STYLE_NONE,
|
||||
REMOVE_UNKNOWN,
|
||||
|
||||
// List Command
|
||||
LIST_NONE,
|
||||
|
@ -213,6 +218,9 @@ public class LangManager {
|
|||
FIXED_MAX_REACHED,
|
||||
FIXED_INVALID_COMMAND,
|
||||
|
||||
// Update Available
|
||||
UPDATE_AVAILABLE,
|
||||
|
||||
// GUI
|
||||
GUI_DISABLED,
|
||||
GUI_COLOR_ICON_NAME,
|
||||
|
@ -245,7 +253,8 @@ public class LangManager {
|
|||
GUI_LOAD_A_PRESET_GROUP_DESCRIPTION,
|
||||
GUI_SAVE_GROUP,
|
||||
GUI_SAVE_GROUP_DESCRIPTION,
|
||||
GUI_SAVE_GROUP_DESCRIPTION_2,
|
||||
GUI_SAVE_GROUP_FULL,
|
||||
GUI_SAVE_GROUP_HOTBAR_MESSAGE,
|
||||
GUI_RESET_PARTICLES,
|
||||
GUI_RESET_PARTICLES_DESCRIPTION,
|
||||
GUI_PARTICLE_NAME,
|
||||
|
@ -288,12 +297,7 @@ public class LangManager {
|
|||
GUI_EDIT_DATA_COLOR_BLACK,
|
||||
GUI_EDIT_DATA_COLOR_GRAY,
|
||||
GUI_EDIT_DATA_COLOR_LIGHT_GRAY,
|
||||
GUI_EDIT_DATA_COLOR_WHITE,
|
||||
|
||||
// Update Available
|
||||
UPDATE_AVAILABLE;
|
||||
|
||||
// @formatter:on
|
||||
GUI_EDIT_DATA_COLOR_WHITE; // @formatter:on
|
||||
|
||||
private String message;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ public class SettingManager {
|
|||
TICKS_PER_PARTICLE(PSettingType.LONG),
|
||||
CHECK_UPDATES(PSettingType.BOOLEAN),
|
||||
GUI_ENABLED(PSettingType.BOOLEAN),
|
||||
GUI_BUTTON_SOUND(PSettingType.BOOLEAN),
|
||||
TOGGLE_ON_MOVE(PSettingType.BOOLEAN),
|
||||
|
||||
PARTICLE_RENDER_RANGE_PLAYER(PSettingType.INTEGER),
|
||||
|
|
|
@ -24,7 +24,7 @@ public class ParticleStyleBlockBreak implements ParticleStyle, Listener {
|
|||
|
||||
location.add(0.5, 0.5, 0.5); // Center around the block
|
||||
|
||||
for (int i = 0; i < 15; i++)
|
||||
for (int i = 0; i < 10; i++)
|
||||
particles.add(new PParticle(location, 0.5F, 0.5F, 0.5F, 0.05F));
|
||||
|
||||
return particles;
|
||||
|
|
|
@ -24,7 +24,7 @@ public class ParticleStyleBlockPlace implements ParticleStyle, Listener {
|
|||
|
||||
location.add(0.5, 0.5, 0.5); // Center around the block
|
||||
|
||||
for (int i = 0; i < 15; i++)
|
||||
for (int i = 0; i < 10; i++)
|
||||
particles.add(new PParticle(location, 0.75F, 0.75F, 0.75F, 0.05F));
|
||||
|
||||
return particles;
|
||||
|
|
|
@ -29,9 +29,9 @@ public class ParticleStyleSwords implements ParticleStyle, Listener {
|
|||
}
|
||||
|
||||
public List<PParticle> getParticles(ParticlePair particle, Location location) {
|
||||
List<PParticle> baseParticles = DefaultStyles.THICK.getParticles(particle, location);
|
||||
List<PParticle> baseParticles = DefaultStyles.NORMAL.getParticles(particle, location);
|
||||
|
||||
int multiplyingFactor = 3; // Uses the same logic as ParticleStyleThick except multiplies the resulting particles by 3x
|
||||
int multiplyingFactor = 15; // Uses the same logic as ParticleStyleNormal except multiplies the resulting particles by 3x
|
||||
List<PParticle> particles = new ArrayList<PParticle>();
|
||||
for (int i = 0; i < baseParticles.size() * multiplyingFactor; i++) {
|
||||
particles.add(baseParticles.get(i % baseParticles.size()));
|
||||
|
|
|
@ -53,12 +53,13 @@ public interface ParticleStyle {
|
|||
/**
|
||||
* Gets the ParticleStyle with the name given, returns null if not found
|
||||
*
|
||||
* @param styleName The string of the style to search for
|
||||
* @return The ParticleStyle with the name requested
|
||||
* @param styleName The name of the style to search for
|
||||
* @return The ParticleStyle with a matching name
|
||||
*/
|
||||
public static ParticleStyle fromName(String styleName) {
|
||||
for (ParticleStyle style : ParticleStyleManager.getStyles())
|
||||
if (style.getName().equals(styleName)) return style;
|
||||
if (style.getName().equalsIgnoreCase(styleName))
|
||||
return style;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ public class ParticleUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ParticleUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a block/item as a material from a string
|
||||
|
@ -76,6 +80,20 @@ public class ParticleUtils {
|
|||
public static List<String> getAllItemMaterials() {
|
||||
return itemMaterials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a string from the format "word_word" to "Word Word"
|
||||
*
|
||||
* @param string The input string
|
||||
* @return The input string but formatted with each word capitalized
|
||||
*/
|
||||
public static String formatName(String string) {
|
||||
String[] words = string.split("_");
|
||||
String result = "";
|
||||
for (String word : words)
|
||||
result += Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase() + " ";
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the smallest positive integer from an array
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# This value is the version of the plugin that last modified the config file
|
||||
# Changing this value manually will likely result in data loss and errors!
|
||||
# Do not change this manually unless specifically told to by the plugin author
|
||||
version: 6.2
|
||||
version: 6.3
|
||||
|
||||
# Check for new versions of the plugin
|
||||
# Default: true
|
||||
|
@ -41,6 +41,10 @@ message-prefix: '&7[&3PlayerParticles&7]'
|
|||
# Default: true
|
||||
gui-enabled: true
|
||||
|
||||
# If clicking a GUI button should make a noise
|
||||
# Default: true
|
||||
gui-button-sound: true
|
||||
|
||||
# If true, styles will not display while the player is moving
|
||||
# They will instead have the effect displayed at their feet
|
||||
# Note: Not all styles abide by this rule, but most will
|
||||
|
|
|
@ -44,4 +44,4 @@ angel:
|
|||
2:
|
||||
effect: 'dust'
|
||||
style: 'halo'
|
||||
data: '255 255 0'
|
||||
data: '255 255 0'
|
||||
|
|
|
@ -99,7 +99,12 @@ reload-no-permission: '&cYou do not have permission to reload the plugin setting
|
|||
|
||||
# Remove Command
|
||||
remove-no-args: '&cYou did not specify an ID to remove! &b/pp remove <ID>'
|
||||
remove-success: '&aYour particle with the ID &b{0} &ahas been removed!'
|
||||
remove-id-success: '&aYour particle with the ID &b{0} &ahas been removed!'
|
||||
remove-effect-success: '&aRemoved &b{0} &aof your particles with the effect of &b{1}&a!'
|
||||
remove-effect-none: '&cYou do not have any particles applied with the effect &b{0}&c!'
|
||||
remove-style-success: '&aRemoved &b{0} &aof your particles with the style of &b{1}&a!'
|
||||
remove-style-none: '&cYou do not have any particles applied with the style &b{0}&c!'
|
||||
remove-unknown: '&cAn effect or style with the name of &b{0} &cdoes not exist!'
|
||||
|
||||
# List Command
|
||||
list-none: '&eYou do not have any active particles!'
|
||||
|
@ -111,10 +116,10 @@ toggle-on: '&eParticles have been toggled &aON&e!'
|
|||
toggle-off: '&eParticles have been toggled &cOFF&e!'
|
||||
|
||||
# Rainbow
|
||||
rainbow: '&cr&6a&ei&an&bb&9o&dw'
|
||||
rainbow: '&cR&6a&ei&an&bb&9o&dw'
|
||||
|
||||
# Random
|
||||
random: 'random'
|
||||
random: 'Random'
|
||||
|
||||
# Effects
|
||||
effect-no-permission: '&cYou do not have permission to use the effect &b{0} &c!'
|
||||
|
@ -200,6 +205,9 @@ fixed-no-permission: '&cYou do not have permission to use fixed effects!'
|
|||
fixed-max-reached: '&cYou have reached the maximum allowed fixed effects!'
|
||||
fixed-invalid-command: '&cInvalid sub-command for &b/pp fixed&c!'
|
||||
|
||||
# Update Available
|
||||
update-available: '&eAn update (&b{0}&e) is available! You are running &bv{1}&e. https://www.spigotmc.org/resources/playerparticles.40261/'
|
||||
|
||||
# GUI
|
||||
gui-disabled: '&cThe server administrator has disabled the GUI!'
|
||||
gui-color-icon-name: '&a'
|
||||
|
@ -231,8 +239,9 @@ gui-manage-your-groups-description: 'Create, delete, and load your particle grou
|
|||
gui-load-a-preset-group: 'Load A Preset Group'
|
||||
gui-load-a-preset-group-description: 'Load a premade particle group'
|
||||
gui-save-group: 'Save New Group'
|
||||
gui-save-group-description: 'You can save a new group using the following command:'
|
||||
gui-save-group-description-2: '/pp group save <groupName>'
|
||||
gui-save-group-description: 'Click to save a new group. You will be prompted\nto enter the new group name in chat.'
|
||||
gui-save-group-full: 'You have reached the max number of groups'
|
||||
gui-save-group-hotbar-message: '&eType &b1 &eword in chat for the new group name. Type "&ccancel&e" to cancel. (&b{0}&es left)'
|
||||
gui-reset-particles: 'Reset Your Particles'
|
||||
gui-reset-particles-description: 'Deletes all your active particles'
|
||||
gui-particle-name: 'Particle #{0}'
|
||||
|
@ -276,6 +285,3 @@ gui-edit-data-color-black: '&8black'
|
|||
gui-edit-data-color-gray: '&8gray'
|
||||
gui-edit-data-color-light-gray: '&7light gray'
|
||||
gui-edit-data-color-white: '&fwhite'
|
||||
|
||||
# Update Available
|
||||
update-available: '&eAn update (&b{0}&e) is available! You are running &bv{1}&e. https://www.spigotmc.org/resources/playerparticles.40261/'
|
|
@ -1,6 +1,6 @@
|
|||
name: PlayerParticles
|
||||
main: com.esophose.playerparticles.PlayerParticles
|
||||
version: 6.2
|
||||
version: 6.3
|
||||
api-version: 1.13
|
||||
description: Display particles around your player using customized styles and data!
|
||||
author: Esophose
|
||||
|
|
Loading…
Reference in a new issue