Adds some events that trigger when NPC actions start or end, and when sounds are played

This commit is contained in:
Kristian Knarvik 2024-07-28 17:12:26 +02:00
parent 81dda85405
commit 904adf46f0
20 changed files with 571 additions and 10 deletions

View File

@ -32,6 +32,7 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Event;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
@ -206,6 +207,15 @@ public class BlacksmithPlugin extends JavaPlugin {
}
}
/**
* Calls an event
*
* @param event <p>The event to call</p>
*/
public void callEvent(@NotNull Event event) {
this.getServer().getPluginManager().callEvent(event);
}
/**
* Initializes custom configuration and translation
*

View File

@ -241,7 +241,8 @@ public enum BlacksmithSetting implements Setting {
* The cost for repairing a damaged anvil
*/
ANVIL_DAMAGED_COST("damagedAnvilReforgingCost", SettingValueType.POSITIVE_DOUBLE, 20.0,
"The cost of fully repairing a damaged anvil", false, false);
"The cost of fully repairing a damaged anvil", false, false),
;
private final String path;
private final String childPath;
@ -262,7 +263,7 @@ public enum BlacksmithSetting implements Setting {
* @param isPerNPC <p>Whether this setting is per-NPC or global</p>
* @param isMessage <p>Whether this option is for an NPC message</p>
*/
BlacksmithSetting(@NotNull String key, @NotNull SettingValueType valueType, @NotNull Object value,
BlacksmithSetting(@NotNull String key, @NotNull SettingValueType valueType, @Nullable Object value,
@NotNull String description, boolean isPerNPC, boolean isMessage) {
if (isPerNPC) {
if (isMessage) {

View File

@ -302,7 +302,7 @@ public enum ScrapperSetting implements Setting {
* @param isPerNPC <p>Whether this setting is per-NPC or global</p>
* @param isMessage <p>Whether this option is for an NPC message</p>
*/
ScrapperSetting(@NotNull String key, @NotNull SettingValueType valueType, @NotNull Object value,
ScrapperSetting(@NotNull String key, @NotNull SettingValueType valueType, @Nullable Object value,
@NotNull String description, boolean isPerNPC, boolean isMessage) {
if (isPerNPC) {
if (isMessage) {

View File

@ -0,0 +1,40 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
/**
* The base class for all blacksmith plugin events
*/
@SuppressWarnings("unused")
public abstract class AbstractBlacksmithPluginEvent extends Event implements BlacksmithPluginEvent {
protected final NPC npc;
protected final Player player;
/**
* Instantiates a new blacksmith plugin event
*
* @param npc <p>The NPC involved in the event</p>
* @param player <p>The player involved in the event</p>
*/
public AbstractBlacksmithPluginEvent(@NotNull NPC npc, @NotNull Player player) {
this.npc = npc;
this.player = player;
}
@Override
@NotNull
public NPC getNpc() {
return this.npc;
}
@Override
@NotNull
public Player getPlayer() {
return this.player;
}
}

View File

@ -0,0 +1,18 @@
package net.knarcraft.blacksmith.event;
/**
* An event triggered when a blacksmith or scrapper starts reforging or salvaging an item
*/
@SuppressWarnings("unused")
public interface ActionStartEvent extends BlacksmithPluginEvent {
/**
* Gets the end time for this action
*
* <p>The end time is a millisecond time-stamp, basically the same format used by currentTimeMillis();.</p>
*
* @return <p>The end time</p>
*/
long getActionEndTime();
}

View File

@ -0,0 +1,29 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* An event triggered by the Blacksmith plugin
*/
@SuppressWarnings("unused")
public interface BlacksmithPluginEvent {
/**
* Gets the NPC involved in the event
*
* @return <p>The NPC</p>
*/
@NotNull
NPC getNpc();
/**
* Gets the player involved in the event
*
* @return <p>The player</p>
*/
@NotNull
Player getPlayer();
}

View File

@ -0,0 +1,41 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* The event triggered when a blacksmith reforging fails
*/
public class BlacksmithReforgeFailEvent extends AbstractBlacksmithPluginEvent implements ReforgeEndEvent {
private static final HandlerList handlers = new HandlerList();
/**
* Instantiates a new blacksmith reforge fail event
*
* @param npc <p>The NPC involved in the event</p>
*/
public BlacksmithReforgeFailEvent(@NotNull NPC npc, @NotNull Player player) {
super(npc, player);
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@NotNull
@SuppressWarnings("unused")
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,50 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* The event triggered when a blacksmith reforging starts
*/
public class BlacksmithReforgeStartEvent extends AbstractBlacksmithPluginEvent implements ActionStartEvent {
private static final HandlerList handlers = new HandlerList();
private final Long reforgeEndTime;
/**
* Instantiates a new blacksmith reforge start event
*
* @param npc <p>The NPC involved in the event</p>
* @param player <p>The player involved in the event</p>
* @param reforgeEndTime <p>The time at which this reforging ends</p>
*/
public BlacksmithReforgeStartEvent(@NotNull NPC npc, @NotNull Player player, long reforgeEndTime) {
super(npc, player);
this.reforgeEndTime = reforgeEndTime;
}
@Override
public long getActionEndTime() {
return reforgeEndTime;
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@NotNull
@SuppressWarnings("unused")
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,42 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* The event triggered when a blacksmith reforging succeeds
*/
public class BlacksmithReforgeSucceedEvent extends AbstractBlacksmithPluginEvent implements ReforgeEndEvent {
private static final HandlerList handlers = new HandlerList();
/**
* Instantiates a new blacksmith reforge succeed event
*
* @param npc <p>The NPC involved in the event</p>
* @param player <p>The player involved in the event</p>
*/
public BlacksmithReforgeSucceedEvent(@NotNull NPC npc, @NotNull Player player) {
super(npc, player);
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@SuppressWarnings("unused")
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,142 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* An event triggered when an NPC plays a sound indicating an action
*/
@SuppressWarnings("unused")
public class NPCSoundEvent extends AbstractBlacksmithPluginEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private float pitch;
private float volume;
private SoundCategory soundCategory;
private Sound sound;
/**
* Instantiates a new NPC sound event
*
* @param npc <p>The NPC playing the sound</p>
* @param player <p>The player whose interaction triggered the sound</p>
* @param soundCategory <p>The category the sound is to play in</p>
* @param sound <p>The sound to play</p>
* @param volume <p>The volume of the played sound</p>
* @param pitch <p>The pitch of the played sound</p>
*/
public NPCSoundEvent(@NotNull NPC npc, @NotNull Player player, @NotNull SoundCategory soundCategory,
@NotNull Sound sound, float volume, float pitch) {
super(npc, player);
this.soundCategory = soundCategory;
this.sound = sound;
this.volume = volume;
this.pitch = pitch;
}
/**
* Gets the pitch of the played sound
*
* @return <p>The pitch of the played sound</p>
*/
public float getPitch() {
return this.pitch;
}
/**
* Gets the volume of the played sound
*
* @return <p>The volume of the played sound</p>
*/
public float getVolume() {
return this.volume;
}
/**
* Gets the category the sound is played in
*
* @return <p>The sound category used</p>
*/
public @NotNull SoundCategory getSoundCategory() {
return this.soundCategory;
}
/**
* Gets the sound to play
*
* @return <p>The sound to play</p>
*/
public @NotNull Sound getSound() {
return this.sound;
}
/**
* Sets the pitch of the played sound
*
* @param pitch <p>The new pitch</p>
*/
public void setPitch(float pitch) {
this.pitch = pitch;
}
/**
* Sets the volume of the played sound
*
* @param volume <p>The new volume</p>
*/
public void setVolume(float volume) {
this.volume = volume;
}
/**
* Sets the sound to play
*
* @param sound <p>The new sound to play</p>
*/
public void setSound(@NotNull Sound sound) {
this.sound = sound;
}
/**
* Sets the category the sound is played in
*
* @param soundCategory <p>The new sound category</p>
*/
public void setSoundCategory(@NotNull SoundCategory soundCategory) {
this.soundCategory = soundCategory;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@NotNull
@SuppressWarnings("unused")
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,7 @@
package net.knarcraft.blacksmith.event;
/**
* An event triggered when a reforge finishes
*/
public interface ReforgeEndEvent extends BlacksmithPluginEvent {
}

View File

@ -0,0 +1,7 @@
package net.knarcraft.blacksmith.event;
/**
* An event triggered when a salvaging finishes
*/
public interface SalvageEndEvent extends BlacksmithPluginEvent {
}

View File

@ -0,0 +1,42 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* The event triggered when a scrapper salvaging fails
*/
public class ScrapperSalvageFailEvent extends AbstractBlacksmithPluginEvent implements SalvageEndEvent {
private static final HandlerList handlers = new HandlerList();
/**
* Instantiates a new scrapper salvage fail event
*
* @param npc <p>The NPC involved in the event</p>
* @param player <p>The player involved in the event</p>
*/
public ScrapperSalvageFailEvent(@NotNull NPC npc, @NotNull Player player) {
super(npc, player);
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@SuppressWarnings("unused")
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,51 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* The event triggered when a scrapper salvaging starts
*/
@SuppressWarnings("unused")
public class ScrapperSalvageStartEvent extends AbstractBlacksmithPluginEvent implements ActionStartEvent {
private static final HandlerList handlers = new HandlerList();
private final long salvageEndTime;
/**
* Instantiates a new scrapper salvage start event
*
* @param npc <p>The NPC involved in the event</p>
* @param player <p>The player involved in the event</p>
* @param salvageEndTime <p>The time at which this salvaging ends</p>
*/
public ScrapperSalvageStartEvent(@NotNull NPC npc, @NotNull Player player, long salvageEndTime) {
super(npc, player);
this.salvageEndTime = salvageEndTime;
}
@Override
public long getActionEndTime() {
return this.salvageEndTime;
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@SuppressWarnings("unused")
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,42 @@
package net.knarcraft.blacksmith.event;
import net.citizensnpcs.api.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* The event triggered when a scrapper salvaging succeeds
*/
public class ScrapperSalvageSucceedEvent extends AbstractBlacksmithPluginEvent implements SalvageEndEvent {
private static final HandlerList handlers = new HandlerList();
/**
* Instantiates a new scrapper salvage succeed event
*
* @param npc <p>The NPC involved in the event</p>
* @param player <p>The player involved in the event</p>
*/
public ScrapperSalvageSucceedEvent(@NotNull NPC npc, @NotNull Player player) {
super(npc, player);
}
/**
* Gets a handler-list containing all event handlers
*
* @return <p>A handler-list with all event handlers</p>
*/
@SuppressWarnings("unused")
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -21,6 +21,7 @@ import static net.knarcraft.blacksmith.formatting.BlacksmithStringFormatter.send
* The class representing the Blacksmith NPC trait
*/
public class BlacksmithTrait extends CustomTrait<BlacksmithSetting> {
private final BlacksmithNPCSettings config;
/**

View File

@ -3,6 +3,8 @@ package net.knarcraft.blacksmith.trait;
import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.knarcraft.blacksmith.config.blacksmith.BlacksmithNPCSettings;
import net.knarcraft.blacksmith.event.BlacksmithReforgeFailEvent;
import net.knarcraft.blacksmith.event.BlacksmithReforgeSucceedEvent;
import net.knarcraft.blacksmith.manager.EconomyManager;
import net.knarcraft.blacksmith.util.InputParsingHelper;
import net.knarcraft.blacksmith.util.ItemHelper;
@ -135,9 +137,11 @@ public class ReforgeSession extends Session implements Runnable {
private boolean reforgeItem() {
if (random.nextInt(100) < this.config.getFailChance()) {
failReforge();
BlacksmithPlugin.getInstance().callEvent(new BlacksmithReforgeFailEvent(this.npc, this.player));
return false;
} else {
succeedReforge();
BlacksmithPlugin.getInstance().callEvent(new BlacksmithReforgeSucceedEvent(this.npc, this.player));
return true;
}
}

View File

@ -1,8 +1,11 @@
package net.knarcraft.blacksmith.trait;
import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.knarcraft.blacksmith.config.SalvageMethod;
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
import net.knarcraft.blacksmith.event.ScrapperSalvageFailEvent;
import net.knarcraft.blacksmith.event.ScrapperSalvageSucceedEvent;
import net.knarcraft.blacksmith.manager.EconomyManager;
import net.knarcraft.blacksmith.util.ItemHelper;
import net.knarcraft.blacksmith.util.SalvageHelper;
@ -114,9 +117,11 @@ public class SalvageSession extends Session implements Runnable {
if (random.nextInt(100) < this.config.getFailChance()) {
playSound(Sound.ENTITY_VILLAGER_NO);
failSalvage();
BlacksmithPlugin.getInstance().callEvent(new ScrapperSalvageFailEvent(this.npc, this.player));
} else {
playSound(Sound.BLOCK_ANVIL_USE);
giveSalvage();
BlacksmithPlugin.getInstance().callEvent(new ScrapperSalvageSucceedEvent(this.npc, this.player));
sendNPCMessage(this.npc, this.player, this.config.getSuccessMessage());
}
}

View File

@ -2,10 +2,14 @@ package net.knarcraft.blacksmith.trait;
import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.knarcraft.blacksmith.event.BlacksmithReforgeStartEvent;
import net.knarcraft.blacksmith.event.NPCSoundEvent;
import net.knarcraft.blacksmith.event.ScrapperSalvageStartEvent;
import net.knarcraft.blacksmith.util.ItemHelper;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitScheduler;
@ -95,6 +99,13 @@ public abstract class Session implements Runnable {
BukkitScheduler scheduler = BlacksmithPlugin.getInstance().getServer().getScheduler();
int actionDelay = getActionDelay();
this.finishTime = System.currentTimeMillis() + (actionDelay * 1000L);
if (this instanceof ReforgeSession) {
BlacksmithPlugin.getInstance().callEvent(new BlacksmithReforgeStartEvent(npc, player, this.finishTime));
} else if (this instanceof SalvageSession) {
BlacksmithPlugin.getInstance().callEvent(new ScrapperSalvageStartEvent(npc, player, this.finishTime));
}
taskId = scheduler.scheduleSyncDelayedTask(BlacksmithPlugin.getInstance(), this, actionDelay * 20L);
int playWorkSound = scheduler.scheduleSyncRepeatingTask(BlacksmithPlugin.getInstance(),
this::playWorkSound, 20, 20);
@ -156,20 +167,37 @@ public abstract class Session implements Runnable {
* @param sound <p>The sound to play</p>
*/
protected void playSound(Sound sound) {
World world = this.npc.getEntity().getLocation().getWorld();
if (world != null) {
world.playSound(this.npc.getEntity(), sound, SoundCategory.AMBIENT, 0.5F, 1.0F);
}
playSound(this.npc.getEntity(), sound, 1.0F);
}
/**
* Plays the working NPC sound
*/
protected void playWorkSound() {
World world = this.npc.getEntity().getLocation().getWorld();
if (world != null) {
world.playSound(this.npc.getEntity(), Sound.BLOCK_PACKED_MUD_BREAK, SoundCategory.AMBIENT, 0.5F, (float) 0.5);
playSound(this.npc.getEntity(), Sound.ITEM_ARMOR_EQUIP_NETHERITE, 0.5f);
}
/**
* Plays a npc sound using a cancellable event
*
* @param entity <p>The entity that should play the sound</p>
* @param sound <p>The sound to play</p>
* @param pitch <p>The pitch to play the sound at</p>
*/
private void playSound(@NotNull Entity entity, @NotNull Sound sound, float pitch) {
World world = entity.getLocation().getWorld();
if (world == null) {
return;
}
NPCSoundEvent event = new NPCSoundEvent(this.npc, this.player, SoundCategory.AMBIENT, sound, 0.5f, pitch);
BlacksmithPlugin.getInstance().callEvent(event);
if (event.isCancelled()) {
return;
}
world.playSound(event.getNpc().getEntity(), event.getSound(), event.getSoundCategory(), event.getVolume(),
event.getPitch());
}
}

View File

@ -3,6 +3,7 @@ authors: [ EpicKnarvik97, aPunch, jrbudda, HurricanKai ]
version: '${project.version}'
main: net.knarcraft.blacksmith.BlacksmithPlugin
depend: [ Citizens, Vault ]
softdepend: [ ProtocolLib ]
prefix: "Blacksmith"
description: "A plugin that adds Blacksmith and Scrapper traits compatible with Citizens, allowing players to repair and salvage items"
website: "https://www.spigotmc.org/resources/blacksmith.105938/"