mirror of
https://github.com/FancyInnovations/FancyPlugins.git
synced 2025-12-06 07:43:36 +00:00
fancynpcs: add turn_to_player_distance and center commands
Co-authored-by: Sadat Sahib <58975768+ssquadteam@users.noreply.github.com>
This commit is contained in:
@@ -20,6 +20,14 @@ public interface FancyNpcsConfig {
|
||||
int getNpcUpdateVisibilityInterval();
|
||||
|
||||
int getTurnToPlayerDistance();
|
||||
|
||||
/**
|
||||
* Sets the distance at which NPCs turn to the player.
|
||||
*
|
||||
* @param distance The new distance value
|
||||
* @return true if the distance was updated successfully, false otherwise
|
||||
*/
|
||||
boolean setTurnToPlayerDistance(int distance);
|
||||
|
||||
boolean isTurnToPlayerResetToInitialDirection();
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ public class NpcData {
|
||||
private Consumer<Player> onClick;
|
||||
private Map<ActionTrigger, List<NpcAction.NpcActionData>> actions;
|
||||
private boolean turnToPlayer;
|
||||
private int turnToPlayerDistance = -1; // -1 means use the default from config
|
||||
private float interactionCooldown;
|
||||
private float scale;
|
||||
private int visibilityDistance;
|
||||
@@ -57,6 +58,7 @@ public class NpcData {
|
||||
EntityType type,
|
||||
Map<NpcEquipmentSlot, ItemStack> equipment,
|
||||
boolean turnToPlayer,
|
||||
int turnToPlayerDistance,
|
||||
Consumer<Player> onClick,
|
||||
Map<ActionTrigger, List<NpcAction.NpcActionData>> actions,
|
||||
float interactionCooldown,
|
||||
@@ -81,6 +83,7 @@ public class NpcData {
|
||||
this.onClick = onClick;
|
||||
this.actions = actions;
|
||||
this.turnToPlayer = turnToPlayer;
|
||||
this.turnToPlayerDistance = turnToPlayerDistance;
|
||||
this.interactionCooldown = interactionCooldown;
|
||||
this.scale = scale;
|
||||
this.visibilityDistance = visibilityDistance;
|
||||
@@ -108,6 +111,7 @@ public class NpcData {
|
||||
};
|
||||
this.actions = new ConcurrentHashMap<>();
|
||||
this.turnToPlayer = false;
|
||||
this.turnToPlayerDistance = -1; // Use default from config
|
||||
this.interactionCooldown = 0;
|
||||
this.scale = 1;
|
||||
this.visibilityDistance = -1;
|
||||
@@ -321,6 +325,27 @@ public class NpcData {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the turn-to-player distance for this NPC.
|
||||
*
|
||||
* @return the custom distance value, or -1 if using the default from config
|
||||
*/
|
||||
public int getTurnToPlayerDistance() {
|
||||
return turnToPlayerDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the turn-to-player distance for this NPC.
|
||||
*
|
||||
* @param distance the custom distance value, or -1 to use the default from config
|
||||
* @return this NpcData instance for method chaining
|
||||
*/
|
||||
public NpcData setTurnToPlayerDistance(int distance) {
|
||||
this.turnToPlayerDistance = distance;
|
||||
isDirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getInteractionCooldown() {
|
||||
return interactionCooldown;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ public class NpcModifyEvent extends Event implements Cancellable {
|
||||
SHOW_IN_TAB,
|
||||
SKIN,
|
||||
TURN_TO_PLAYER,
|
||||
TURN_TO_PLAYER_DISTANCE,
|
||||
TYPE,
|
||||
// Messages.
|
||||
MESSAGE_ADD,
|
||||
|
||||
@@ -205,6 +205,24 @@ public class FancyNpcsConfigImpl implements FancyNpcsConfig {
|
||||
return turnToPlayerDistance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTurnToPlayerDistance(int distance) {
|
||||
// Validate the input - ensure the distance is positive or -1 for default
|
||||
if (distance <= 0 && distance != -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the config value in memory
|
||||
this.turnToPlayerDistance = distance;
|
||||
|
||||
// Persist to config file
|
||||
FileConfiguration config = FancyNpcs.getInstance().getConfig();
|
||||
config.set("turn_to_player_distance", distance);
|
||||
FancyNpcs.getInstance().saveConfig();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getVisibilityDistance() {
|
||||
return visibilityDistance;
|
||||
}
|
||||
|
||||
@@ -393,6 +393,8 @@ public class NpcManagerImpl implements NpcManager {
|
||||
}
|
||||
}
|
||||
|
||||
int turnToPlayerDistance = (int) npcConfig.getDouble("npcs." + id + ".turnToPlayerDistance", 0);
|
||||
|
||||
NpcData data = new NpcData(
|
||||
id,
|
||||
name,
|
||||
@@ -408,6 +410,7 @@ public class NpcManagerImpl implements NpcManager {
|
||||
type,
|
||||
new HashMap<>(),
|
||||
turnToPlayer,
|
||||
turnToPlayerDistance,
|
||||
null,
|
||||
actions,
|
||||
interactionCooldown,
|
||||
@@ -472,4 +475,4 @@ public class NpcManagerImpl implements NpcManager {
|
||||
logger.error("Could not save backup file for NPCs");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,6 +167,7 @@ public final class CloudCommandManager {
|
||||
*/
|
||||
public @NotNull CloudCommandManager registerCommands() {
|
||||
annotationParser.parse(AttributeCMD.INSTANCE);
|
||||
annotationParser.parse(CenterCMD.INSTANCE);
|
||||
annotationParser.parse(CollidableCMD.INSTANCE);
|
||||
annotationParser.parse(CopyCMD.INSTANCE);
|
||||
annotationParser.parse(CreateCMD.INSTANCE);
|
||||
@@ -187,6 +188,7 @@ public final class CloudCommandManager {
|
||||
annotationParser.parse(SkinCMD.INSTANCE);
|
||||
annotationParser.parse(TeleportCMD.INSTANCE);
|
||||
annotationParser.parse(TurnToPlayerCMD.INSTANCE);
|
||||
annotationParser.parse(TurnToPlayerDistanceCMD.INSTANCE);
|
||||
annotationParser.parse(TypeCMD.INSTANCE);
|
||||
annotationParser.parse(ActionCMD.INSTANCE);
|
||||
annotationParser.parse(VisibilityDistanceCMD.INSTANCE);
|
||||
|
||||
@@ -50,6 +50,7 @@ public enum CopyCMD {
|
||||
npc.getData().getType(),
|
||||
new ConcurrentHashMap<>(npc.getData().getEquipment()),
|
||||
npc.getData().isTurnToPlayer(),
|
||||
npc.getData().getTurnToPlayerDistance(),
|
||||
npc.getData().getOnClick(),
|
||||
new ConcurrentHashMap<>(npc.getData().getActions()),
|
||||
npc.getData().getInteractionCooldown(),
|
||||
|
||||
@@ -7,7 +7,6 @@ import de.oliver.fancynpcs.api.events.NpcModifyEvent;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.annotations.Command;
|
||||
import org.incendo.cloud.annotations.Permission;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -23,14 +22,21 @@ public enum TurnToPlayerCMD {
|
||||
final @NotNull Npc npc,
|
||||
final @Nullable Boolean state
|
||||
) {
|
||||
final boolean finalState = (state == null) ? !npc.getData().isTurnToPlayer() : state;
|
||||
// Calling the event and updating the state if not cancelled.
|
||||
if (new NpcModifyEvent(npc, NpcModifyEvent.NpcModification.TURN_TO_PLAYER, finalState, sender).callEvent()) {
|
||||
npc.getData().setTurnToPlayer(finalState);
|
||||
translator.translate(finalState ? "npc_turn_to_player_set_true" : "npc_turn_to_player_set_false").replace("npc", npc.getData().getName()).send(sender);
|
||||
return;
|
||||
if (state != null && npc.getData().isTurnToPlayer() != state) {
|
||||
if (new NpcModifyEvent(npc, NpcModifyEvent.NpcModification.TURN_TO_PLAYER, state, sender).callEvent()) {
|
||||
npc.getData().setTurnToPlayer(state);
|
||||
translator.translate(state ? "npc_turn_to_player_set_true" : "npc_turn_to_player_set_false")
|
||||
.replace("npc", npc.getData().getName())
|
||||
.send(sender);
|
||||
} else {
|
||||
translator.translate("command_npc_modification_cancelled").send(sender);
|
||||
}
|
||||
} else if (state == null) {
|
||||
// If no state provided, just display current state
|
||||
boolean currentState = npc.getData().isTurnToPlayer();
|
||||
translator.translate(currentState ? "npc_turn_to_player_status_true" : "npc_turn_to_player_status_false")
|
||||
.replace("npc", npc.getData().getName())
|
||||
.send(sender);
|
||||
}
|
||||
translator.translate("command_npc_modification_cancelled").send(sender);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public class TurnToPlayerTracker implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<Npc> npcs = FancyNpcs.getInstance().getNpcManagerImpl().getAllNpcs();
|
||||
int turnToPlayerDistance = FancyNpcs.getInstance().getFancyNpcConfig().getTurnToPlayerDistance();
|
||||
int defaultTurnToPlayerDistance = FancyNpcs.getInstance().getFancyNpcConfig().getTurnToPlayerDistance();
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
Location playerLocation = player.getLocation();
|
||||
@@ -33,8 +33,12 @@ public class TurnToPlayerTracker implements Runnable {
|
||||
if (Double.isNaN(distance)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get NPC-specific turn distance or fall back to default
|
||||
int npcTurnDistance = npcData.getTurnToPlayerDistance();
|
||||
int effectiveTurnDistance = (npcTurnDistance == -1) ? defaultTurnToPlayerDistance : npcTurnDistance;
|
||||
|
||||
if (npcData.isTurnToPlayer() && distance < turnToPlayerDistance) {
|
||||
if (npcData.isTurnToPlayer() && distance < effectiveTurnDistance) {
|
||||
Location newLoc = playerLocation.clone();
|
||||
newLoc.setDirection(newLoc.subtract(npcLocation).toVector());
|
||||
npc.lookAt(player, newLoc);
|
||||
|
||||
@@ -107,6 +107,7 @@ messages:
|
||||
npc_action_set: "<dark_gray>› <gray>Syntax: {primaryColor}/npc action {secondaryColor}(npc) (trigger) {primaryColor}set {secondaryColor}(index) (type) [value]"
|
||||
npc_attribute: "<dark_gray>› <gray>Syntax: {primaryColor}/npc attribute {secondaryColor}(npc) {primaryColor}(set | list)"
|
||||
npc_attribute_set: "<dark_gray>› <gray>Syntax: {primaryColor}/npc attribute {secondaryColor}(npc) {primaryColor}set {secondaryColor}(attribute) (value)"
|
||||
npc_center: "<dark_gray>› <gray>Syntax: {primaryColor}/npc center {secondaryColor}(npc)"
|
||||
npc_collidable: "<dark_gray>› <gray>Syntax: {primaryColor}/npc collidable {secondaryColor}(npc) (state)"
|
||||
npc_copy: "<dark_gray>› <gray>Syntax: {primaryColor}/npc copy {secondaryColor}(npc) (new_name)"
|
||||
npc_create: "<dark_gray>› <gray>Syntax: {primaryColor}/npc create {secondaryColor}(npc) [--type] [--position] [--world]"
|
||||
@@ -125,7 +126,7 @@ messages:
|
||||
npc_show_in_tab: "<dark_gray>› <gray>Syntax: {primaryColor}/npc show_in_tab {secondaryColor}(npc) (state)"
|
||||
npc_skin: "<dark_gray>› <gray>Syntax: {primaryColor}/npc skin {secondaryColor}(npc) (@none | @mirror | name | uuid | placeholder | url | file name) [--slim]"
|
||||
npc_teleport: "<dark_gray>› <gray>Syntax: {primaryColor}/npc teleport {secondaryColor}(npc)"
|
||||
npc_turn_to_player: "<dark_gray>› <gray>Syntax: {primaryColor}/npc turn_to_player {secondaryColor}(npc) (state)"
|
||||
npc_turn_to_player: "<dark_gray>› <gray>Syntax: {primaryColor}/npc turn_to_player {secondaryColor}(npc) (state) [distance]"
|
||||
npc_type: "<dark_gray>› <gray>Syntax: {primaryColor}/npc type {secondaryColor}(npc) (type)"
|
||||
npc_visibility_distance: "<dark_gray>› <gray>Syntax: {primaryColor}/npc visibility_distance {secondaryColor}(npc) (always_visible | default | not_visible | distance)"
|
||||
|
||||
@@ -158,6 +159,7 @@ messages:
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Lists all modified attributes of the NPC.'>{primaryColor}/npc attribute {secondaryColor}(npc) {primaryColor}list"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes whether the NPC can collide with other entities.'>{primaryColor}/npc collidable {secondaryColor}(npc) [state]"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Copies (duplicates) specified NPC.'>{primaryColor}/npc copy {secondaryColor}(npc) (new_name)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Centers the NPC on its current block location.'>{primaryColor}/npc center {secondaryColor}(npc)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Creates a new NPC. Can be customized with flags.'>{primaryColor}/npc create {secondaryColor}(npc) [--type] [--location] [--world]"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes displayname of the NPC. Supports MiniMessage, PlaceholderAPI and MiniPlaceholders.'>{primaryColor}/npc displayname {secondaryColor}(npc) (name)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Sets equipment slot of the NPC to item currently held in main hand, none or a specific item type.'>{primaryColor}/npc equipment {secondaryColor}(npc) {primaryColor}set {secondaryColor}(slot) (@hand | @none | item)"
|
||||
@@ -175,7 +177,7 @@ messages:
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes whether the NPC is shown in the player-list. This works only on NPCs of PLAYER type.<newline><newline>{errorColor}Re-connecting to the server might be required for changes to take effect.'>{primaryColor}/npc show_in_tab {secondaryColor}(npc) (state)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes skin of the NPC.<newline><gray>Supports PlaceholderAPI and MiniPlaceholders.<newline><newline>{warningColor}@none <dark_gray>- <gray>removes the skin<newline>{warningColor}@mirror <dark_gray>- <gray>mirrors player skin<newline>{warningColor}(name) <dark_gray>- <gray>name of any player<newline>{warningColor}(url) <dark_gray>- <gray>url of the skin texture'>{primaryColor}/npc skin {secondaryColor}(npc) (@none | @mirror | name | url) [--slim]"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Teleports you to the specified NPC.'>{primaryColor}/npc teleport {secondaryColor}(npc)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes whether the NPC should turn to the player when in range.'>{primaryColor}/npc turn_to_player {secondaryColor}(npc) (state)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes whether the NPC should turn to the player when in range. Optionally specify a custom turn distance.'>{primaryColor}/npc turn_to_player {secondaryColor}(npc) (state) [distance]"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes the type of the NPC.'>{primaryColor}/npc type {secondaryColor}(npc) (type)"
|
||||
- "<dark_gray>› <hover:show_text:'<gray>Changes the visibility distance of the NPC.'>{primaryColor}/npc visibility_distance {secondaryColor}(npc) (default | distance | ...)"
|
||||
|
||||
@@ -322,6 +324,18 @@ messages:
|
||||
# Commands (npc turn_to_player)
|
||||
npc_turn_to_player_set_true: "<dark_gray>› <gray>NPC {warningColor}{npc}<gray> is now turning to player."
|
||||
npc_turn_to_player_set_false: "<dark_gray>› <gray>NPC {warningColor}{npc}<gray> is no longer turning to player."
|
||||
npc_turn_to_player_distance_set: "<dark_gray>› <gray>NPC {warningColor}{npc}<gray> will now turn to players within {warningColor}{distance}<gray> blocks."
|
||||
npc_turn_to_player_distance_default: "<dark_gray>› <gray>NPC {warningColor}{npc}<gray> will now use the default distance of {warningColor}{distance}<gray> blocks."
|
||||
npc_turn_to_player_distance_invalid: "<dark_gray>› {errorColor}Invalid distance value. Distance must be -1 (for default) or a positive number."
|
||||
|
||||
# Commands (npc type)
|
||||
npc_type_success: "<dark_gray>› <gray>NPC {warningColor}{npc}<gray> type has been changed to {warningColor}{type}<gray>."
|
||||
|
||||
# Commands (npc turn_to_player_distance)
|
||||
turn_to_player_distance_current: "<dark_gray>› <gray>Current turn-to-player distance is: {warningColor}{distance} blocks"
|
||||
turn_to_player_distance_updated: "<dark_gray>› {successColor}Turn-to-player distance has been updated to {warningColor}{distance} blocks"
|
||||
turn_to_player_distance_failed: "<dark_gray>› {errorColor}Failed to update turn-to-player distance."
|
||||
|
||||
# Commands (npc center)
|
||||
npc_center_success: "<dark_gray>› <gray>NPC {warningColor}{npc}<gray> has been centered to {warningColor}{x}<gray>, {warningColor}{y}<gray>, {warningColor}{z}<gray>."
|
||||
npc_center_failure_no_location: "<dark_gray>› {errorColor}NPC {warningColor}{npc}{errorColor} has no valid location."
|
||||
|
||||
Reference in New Issue
Block a user