Compare commits

...

3 Commits
master ... dev

Author SHA1 Message Date
f4fa9e99a5 Makes sure NPC movements are the same
All checks were successful
KnarCraft/BlacksmithVisuals/pipeline/head This commit looks good
2024-12-15 14:17:15 +01:00
b094d34c62 Adds debug output and a new working position
All checks were successful
KnarCraft/BlacksmithVisuals/pipeline/head This commit looks good
2024-11-27 12:20:01 +01:00
9b04dd042e Adds debug output 2024-10-27 21:56:51 +01:00
6 changed files with 88 additions and 14 deletions

View File

@ -24,6 +24,7 @@ public final class BlacksmithVisuals extends JavaPlugin {
private static BlacksmithVisuals instance; private static BlacksmithVisuals instance;
private ConfigurationManager configurationManager; private ConfigurationManager configurationManager;
private NPCDataManager npcDataManager; private NPCDataManager npcDataManager;
private boolean debug = false;
@Override @Override
public void onEnable() { public void onEnable() {
@ -35,6 +36,8 @@ public final class BlacksmithVisuals extends JavaPlugin {
this.reloadConfig(); this.reloadConfig();
this.saveConfig(); this.saveConfig();
this.debug = this.getConfig().getBoolean("debug", false);
try { try {
this.configurationManager = new ConfigurationManager(this.getConfig()); this.configurationManager = new ConfigurationManager(this.getConfig());
} catch (InvalidConfigurationException exception) { } catch (InvalidConfigurationException exception) {
@ -62,6 +65,20 @@ public final class BlacksmithVisuals extends JavaPlugin {
// Plugin shutdown logic // Plugin shutdown logic
} }
/**
* Logs a debug message
*
* @param message <p>The debug message to log</p>
*/
public static void debug(@NotNull String message) {
BlacksmithVisuals instance = getInstance();
if (instance.debug) {
instance.getLogger().log(Level.INFO, "[Debug] " + message);
} else {
instance.getLogger().log(Level.FINE, message);
}
}
/** /**
* Reloads the configuration file * Reloads the configuration file
*/ */

View File

@ -65,36 +65,43 @@ public class BlacksmithListener implements Listener {
@EventHandler @EventHandler
public void onDefaultSound(@NotNull NPCSoundEvent event) { public void onDefaultSound(@NotNull NPCSoundEvent event) {
BlacksmithVisuals.debug("Detected onDefaultSound event");
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler @EventHandler
public void onReforgeStart(@NotNull BlacksmithReforgeStartEvent event) { public void onReforgeStart(@NotNull BlacksmithReforgeStartEvent event) {
BlacksmithVisuals.debug("Detected onReforgeStart event");
runWorkingAnimation(event, SoundIdentifier.REFORGING_WORKING, this.configurationManager.getBlacksmithAnimationData()); runWorkingAnimation(event, SoundIdentifier.REFORGING_WORKING, this.configurationManager.getBlacksmithAnimationData());
} }
@EventHandler @EventHandler
public void onSalvageStart(@NotNull ScrapperSalvageStartEvent event) { public void onSalvageStart(@NotNull ScrapperSalvageStartEvent event) {
BlacksmithVisuals.debug("Detected onSalvageStart event");
runWorkingAnimation(event, SoundIdentifier.SALVAGING_WORKING, this.configurationManager.getScrapperAnimationData()); runWorkingAnimation(event, SoundIdentifier.SALVAGING_WORKING, this.configurationManager.getScrapperAnimationData());
} }
@EventHandler @EventHandler
public void onReforgeSuccess(@NotNull BlacksmithReforgeSucceedEvent event) { public void onReforgeSuccess(@NotNull BlacksmithReforgeSucceedEvent event) {
BlacksmithVisuals.debug("Detected onReforgeSuccess event");
SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.REFORGING_SUCCESS)); SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.REFORGING_SUCCESS));
} }
@EventHandler @EventHandler
public void onSalvageSuccess(@NotNull ScrapperSalvageSucceedEvent event) { public void onSalvageSuccess(@NotNull ScrapperSalvageSucceedEvent event) {
BlacksmithVisuals.debug("Detected onSalvageSuccess event");
SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.SALVAGING_SUCCESS)); SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.SALVAGING_SUCCESS));
} }
@EventHandler @EventHandler
public void onReforgeFail(@NotNull BlacksmithReforgeFailEvent event) { public void onReforgeFail(@NotNull BlacksmithReforgeFailEvent event) {
BlacksmithVisuals.debug("Detected onReforgeFail event");
SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.REFORGING_FAILURE)); SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.REFORGING_FAILURE));
} }
@EventHandler @EventHandler
public void onSalvageFail(@NotNull ScrapperSalvageFailEvent event) { public void onSalvageFail(@NotNull ScrapperSalvageFailEvent event) {
BlacksmithVisuals.debug("Detected onSalvageFail event");
SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.SALVAGING_FAILURE)); SoundHelper.playSound(event.getEntity(), this.configurationManager.getSoundData(SoundIdentifier.SALVAGING_FAILURE));
} }
@ -107,19 +114,25 @@ public class BlacksmithListener implements Listener {
*/ */
private void runWorkingAnimation(@NotNull ActionStartEvent event, @NotNull SoundIdentifier soundIdentifier, private void runWorkingAnimation(@NotNull ActionStartEvent event, @NotNull SoundIdentifier soundIdentifier,
@NotNull AnimationData animationData) { @NotNull AnimationData animationData) {
BlacksmithVisuals.debug("Preparing to run working animation");
BlacksmithVisuals instance = BlacksmithVisuals.getInstance(); BlacksmithVisuals instance = BlacksmithVisuals.getInstance();
BukkitScheduler scheduler = Bukkit.getScheduler(); BukkitScheduler scheduler = Bukkit.getScheduler();
NPC npc = event.getNpc(); NPC npc = event.getNpc();
NPCPosition npcPosition = NPCPosition.getFromMaterial(event.getCraftingStation()); NPCPosition npcPosition = NPCPosition.getFromMaterial(event.getCraftingStation());
BlacksmithVisuals.debug("Found NPC position: " + npcPosition);
long delay = moveToWorkingPosition(npc, event.getEntity(), npcPosition); long delay = moveToWorkingPosition(npc, event.getEntity(), npcPosition);
BlacksmithVisuals.debug("Calculated delay to: " + delay);
if (npc.hasTrait(LookClose.class)) { if (npc.hasTrait(LookClose.class)) {
BlacksmithVisuals.debug("Found LookClose trait");
LookClose trait = npc.getTraitNullable(LookClose.class); LookClose trait = npc.getTraitNullable(LookClose.class);
this.oldLookRanges.put(npc.getUniqueId(), trait.getRange()); this.oldLookRanges.put(npc.getUniqueId(), trait.getRange());
trait.setRange(0); trait.setRange(0);
BlacksmithVisuals.debug("Edited LookClose range");
} }
long finishTime = event.getActionDurationTicks() - (2 * delay); long finishTime = event.getActionDurationTicks() - (2 * delay);
BlacksmithVisuals.debug("Scheduling work animation and back movement");
scheduler.scheduleSyncDelayedTask(instance, () -> startWorkAnimation(event.getEntity(), scheduler.scheduleSyncDelayedTask(instance, () -> startWorkAnimation(event.getEntity(),
this.configurationManager.getSoundData(soundIdentifier), animationData, finishTime - 20, npcPosition), delay); this.configurationManager.getSoundData(soundIdentifier), animationData, finishTime - 20, npcPosition), delay);
scheduler.scheduleSyncDelayedTask(instance, () -> moveBack(event.getNpc(), event.getEntity()), finishTime); scheduler.scheduleSyncDelayedTask(instance, () -> moveBack(event.getNpc(), event.getEntity()), finishTime);
@ -133,11 +146,13 @@ public class BlacksmithListener implements Listener {
*/ */
private void moveBack(@NotNull NPC npc, @NotNull Entity entity) { private void moveBack(@NotNull NPC npc, @NotNull Entity entity) {
if (!npc.isSpawned()) { if (!npc.isSpawned()) {
BlacksmithVisuals.debug("NPC isn't spawned, and thus cannot be moved back");
return; return;
} }
NPCData npcData = BlacksmithVisuals.getInstance().getNpcDataManager().getData(npc.getUniqueId()); NPCData npcData = BlacksmithVisuals.getInstance().getNpcDataManager().getData(npc.getUniqueId());
if (npcData == null) { if (npcData == null) {
BlacksmithVisuals.debug("Unable to get NPC data for NPC");
return; return;
} }
@ -154,11 +169,10 @@ public class BlacksmithListener implements Listener {
if (oldRange != null) { if (oldRange != null) {
trait.setRange(oldRange); trait.setRange(oldRange);
} }
BlacksmithVisuals.debug("Restored LookCLose range");
} }
Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> moveNPC(npc, entity, targetLocation);
entity.teleport(targetLocation), getWalkTime(entity.getLocation(), targetLocation));
npc.getNavigator().setTarget(targetLocation);
} }
/** /**
@ -171,11 +185,13 @@ public class BlacksmithListener implements Listener {
*/ */
private long moveToWorkingPosition(@NotNull NPC npc, @NotNull Entity entity, @Nullable NPCPosition npcPosition) { private long moveToWorkingPosition(@NotNull NPC npc, @NotNull Entity entity, @Nullable NPCPosition npcPosition) {
if (!npc.isSpawned() || npcPosition == null) { if (!npc.isSpawned() || npcPosition == null) {
BlacksmithVisuals.debug("The NPC isn't spawned, or its working position doesn't exist");
return 0; return 0;
} }
NPCData npcData = BlacksmithVisuals.getInstance().getNpcDataManager().getData(npc.getUniqueId()); NPCData npcData = BlacksmithVisuals.getInstance().getNpcDataManager().getData(npc.getUniqueId());
if (npcData == null) { if (npcData == null) {
BlacksmithVisuals.debug("NPC sata could not be retrieved");
return 0; return 0;
} }
@ -184,6 +200,7 @@ public class BlacksmithListener implements Listener {
targetLocation = npcData.positions().get(NPCPosition.WORKING_REPAIRABLE); targetLocation = npcData.positions().get(NPCPosition.WORKING_REPAIRABLE);
} }
if (targetLocation == null) { if (targetLocation == null) {
BlacksmithVisuals.debug("Working location not set for WORKING_REPAIRABLE");
return 0; return 0;
} }
@ -192,18 +209,30 @@ public class BlacksmithListener implements Listener {
npc.getName() + " is unreachable!"); npc.getName() + " is unreachable!");
return 0; return 0;
} }
Location finalTargetLocation = targetLocation;
return moveNPC(npc, entity, targetLocation);
}
/**
* Moves an NPC to a different location
*
* @param npc <p>The NPC to be moved</p>
* @param entity <p>The NPC's entity</p>
* @param finalTargetLocation <p>The location the NPC should be moved to</p>
* @return <p>The assumed time it will take the NPC to get to the position</p>
*/
private long moveNPC(@NotNull NPC npc, @NotNull Entity entity, @NotNull Location finalTargetLocation) {
// Move NPC using Citizens path-finding // Move NPC using Citizens path-finding
BlacksmithVisuals.debug("Preparing rotation and walk to working location");
Location current = entity.getLocation().clone(); Location current = entity.getLocation().clone();
npc.teleport(current.setDirection(targetLocation.toVector().subtract(current.toVector())), PlayerTeleportEvent.TeleportCause.PLUGIN); npc.teleport(current.setDirection(finalTargetLocation.toVector().subtract(current.toVector())), PlayerTeleportEvent.TeleportCause.PLUGIN);
Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> npc.getNavigator().setTarget(finalTargetLocation), 2); Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> npc.getNavigator().setTarget(finalTargetLocation), 2);
// Teleport the NPC tp get it in the exact final location // Teleport the NPC tp get it in the exact final location
long walkTime = getWalkTime(entity.getLocation(), targetLocation); long walkTime = getWalkTime(entity.getLocation(), finalTargetLocation);
BlacksmithVisuals.debug("Queuing teleportation to working position");
Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () ->
entity.teleport(finalTargetLocation), walkTime); entity.teleport(finalTargetLocation, PlayerTeleportEvent.TeleportCause.PLUGIN), walkTime);
return walkTime; return walkTime;
} }
@ -219,12 +248,15 @@ public class BlacksmithListener implements Listener {
private void startWorkAnimation(@NotNull Entity entity, @NotNull SoundData soundData, private void startWorkAnimation(@NotNull Entity entity, @NotNull SoundData soundData,
@NotNull AnimationData animationData, long durationTicks, @NotNull AnimationData animationData, long durationTicks,
@Nullable NPCPosition npcPosition) { @Nullable NPCPosition npcPosition) {
BlacksmithVisuals.debug("Starting work animation");
BlacksmithVisuals instance = BlacksmithVisuals.getInstance(); BlacksmithVisuals instance = BlacksmithVisuals.getInstance();
BukkitScheduler scheduler = Bukkit.getScheduler(); BukkitScheduler scheduler = Bukkit.getScheduler();
BlacksmithVisuals.debug("Scheduling animation");
int playWorkSound = scheduler.scheduleSyncRepeatingTask(instance, int playWorkSound = scheduler.scheduleSyncRepeatingTask(instance,
() -> animateNPC(entity, soundData, animationData, npcPosition), 20, animationData.animationDelay()); () -> animateNPC(entity, soundData, animationData, npcPosition), 20, animationData.animationDelay());
scheduler.scheduleSyncDelayedTask(instance, () -> scheduler.cancelTask(playWorkSound), durationTicks); scheduler.scheduleSyncDelayedTask(instance, () -> scheduler.cancelTask(playWorkSound), durationTicks);
BlacksmithVisuals.debug("Stopped working animation");
} }
/** /**
@ -250,21 +282,26 @@ public class BlacksmithListener implements Listener {
*/ */
private void animateNPC(@NotNull Entity entity, @NotNull SoundData soundData, @NotNull AnimationData animationData, private void animateNPC(@NotNull Entity entity, @NotNull SoundData soundData, @NotNull AnimationData animationData,
@Nullable NPCPosition npcPosition) { @Nullable NPCPosition npcPosition) {
if (random.nextInt(100) >= animationData.animationChance()) {
return;
}
SoundHelper.playSound(entity, soundData);
// Don't play disabled animations // Don't play disabled animations
if (!animationData.animateOffHand()) { if (!animationData.animateOffHand()) {
BlacksmithVisuals.debug("Offhand animation is disabled");
return; return;
} }
if (random.nextInt(100) >= animationData.animationChance()) {
BlacksmithVisuals.debug("Animation skipped because of RNG");
return;
}
BlacksmithVisuals.debug("Playing work sound");
SoundHelper.playSound(entity, soundData);
if (soundData.offsetTicks() < 0) { if (soundData.offsetTicks() < 0) {
BlacksmithVisuals.debug("Delaying off-hand animation");
Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(),
() -> animateOffhand(entity), -soundData.offsetTicks()); () -> animateOffhand(entity), -soundData.offsetTicks());
} else { } else {
BlacksmithVisuals.debug("Animating off-hand");
animateOffhand(entity); animateOffhand(entity);
} }
@ -272,6 +309,7 @@ public class BlacksmithListener implements Listener {
npcPosition = NPCPosition.WORKING_REPAIRABLE; npcPosition = NPCPosition.WORKING_REPAIRABLE;
} }
for (int i = 0; i < random.nextInt(5) + 1; i++) { for (int i = 0; i < random.nextInt(5) + 1; i++) {
BlacksmithVisuals.debug("Spawning particle");
spawnSparkParticle(entity, npcPosition); spawnSparkParticle(entity, npcPosition);
} }
} }
@ -283,6 +321,7 @@ public class BlacksmithListener implements Listener {
* @param npcPosition <p>The npc potion to spawn a particle for</p> * @param npcPosition <p>The npc potion to spawn a particle for</p>
*/ */
private void spawnSparkParticle(@NotNull Entity entity, @NotNull NPCPosition npcPosition) { private void spawnSparkParticle(@NotNull Entity entity, @NotNull NPCPosition npcPosition) {
BlacksmithVisuals.debug("Preparing particle spawning");
double randomX = this.random.nextDouble(-1, 1); double randomX = this.random.nextDouble(-1, 1);
double randomY = this.random.nextDouble(0.1, 1); double randomY = this.random.nextDouble(0.1, 1);
double randomZ = this.random.nextDouble(-1, 1); double randomZ = this.random.nextDouble(-1, 1);
@ -293,8 +332,10 @@ public class BlacksmithListener implements Listener {
particle = Particle.FLAME; particle = Particle.FLAME;
} }
Location spawnLocation = entity.getLocation().clone().getBlock().getRelative(entity.getFacing()).getLocation().add(0.5, 0, 0.5); Location spawnLocation = entity.getLocation().clone().getBlock().getRelative(entity.getFacing()).getLocation().add(0.5, 0, 0.5);
BlacksmithVisuals.debug("Calculated particle location to " + spawnLocation);
ParticleConfig particleConfig = new ParticleConfig(ParticleMode.SINGLE, particle, 0, 0, 1.1, randomX, randomY, randomZ, 0.1); ParticleConfig particleConfig = new ParticleConfig(ParticleMode.SINGLE, particle, 0, 0, 1.1, randomX, randomY, randomZ, 0.1);
ParticleHelper.spawnParticle(entity.getWorld(), spawnLocation, particleConfig, 1); ParticleHelper.spawnParticle(entity.getWorld(), spawnLocation, particleConfig, 1);
BlacksmithVisuals.debug("Spawned particle");
} }
/** /**
@ -303,6 +344,7 @@ public class BlacksmithListener implements Listener {
* @param entity <p>The entity to animate</p> * @param entity <p>The entity to animate</p>
*/ */
private void animateOffhand(@NotNull Entity entity) { private void animateOffhand(@NotNull Entity entity) {
BlacksmithVisuals.debug("Preparing off-hand animation");
ProtocolManager manager = ProtocolLibrary.getProtocolManager(); ProtocolManager manager = ProtocolLibrary.getProtocolManager();
PacketContainer packet = manager.createPacket(PacketType.Play.Server.ANIMATION); PacketContainer packet = manager.createPacket(PacketType.Play.Server.ANIMATION);
packet.getIntegers().write(0, entity.getEntityId()); packet.getIntegers().write(0, entity.getEntityId());
@ -310,9 +352,11 @@ public class BlacksmithListener implements Listener {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getWorld().equals(entity.getWorld())) { if (player.getWorld().equals(entity.getWorld())) {
BlacksmithVisuals.debug("Sending animation packet to " + player);
manager.sendServerPacket(player, packet); manager.sendServerPacket(player, packet);
} }
} }
BlacksmithVisuals.debug("Finished sending animation packets");
} }

View File

@ -77,6 +77,7 @@ public class NPCDataManager {
npcSection.set("workingPositionNetherite", entry.getValue().positions().get(NPCPosition.WORKING_NETHERITE)); npcSection.set("workingPositionNetherite", entry.getValue().positions().get(NPCPosition.WORKING_NETHERITE));
npcSection.set("workingPositionCrafting", entry.getValue().positions().get(NPCPosition.WORKING_CRAFTING)); npcSection.set("workingPositionCrafting", entry.getValue().positions().get(NPCPosition.WORKING_CRAFTING));
npcSection.set("workingPositionRepairable", entry.getValue().positions().get(NPCPosition.WORKING_REPAIRABLE)); npcSection.set("workingPositionRepairable", entry.getValue().positions().get(NPCPosition.WORKING_REPAIRABLE));
npcSection.set("workingPositionEnchantedBook", entry.getValue().positions().get(NPCPosition.WORKING_SPLITTING));
npcSection.set("idlePosition", entry.getValue().positions().get(NPCPosition.IDLE)); npcSection.set("idlePosition", entry.getValue().positions().get(NPCPosition.IDLE));
} }
configuration.save(configurationFile); configuration.save(configurationFile);
@ -106,6 +107,7 @@ public class NPCDataManager {
locationMap.put(NPCPosition.WORKING_NETHERITE, section.getLocation("workingPositionNetherite")); locationMap.put(NPCPosition.WORKING_NETHERITE, section.getLocation("workingPositionNetherite"));
locationMap.put(NPCPosition.WORKING_CRAFTING, section.getLocation("workingPositionCrafting")); locationMap.put(NPCPosition.WORKING_CRAFTING, section.getLocation("workingPositionCrafting"));
locationMap.put(NPCPosition.WORKING_REPAIRABLE, section.getLocation("workingPositionRepairable")); locationMap.put(NPCPosition.WORKING_REPAIRABLE, section.getLocation("workingPositionRepairable"));
locationMap.put(NPCPosition.WORKING_SPLITTING, section.getLocation("workingPositionEnchantedBook"));
locationMap.put(NPCPosition.IDLE, section.getLocation("idlePosition")); locationMap.put(NPCPosition.IDLE, section.getLocation("idlePosition"));
npcDataMap.put(UUID.fromString(configurationSectionKey), new NPCData(locationMap)); npcDataMap.put(UUID.fromString(configurationSectionKey), new NPCData(locationMap));
} }

View File

@ -33,6 +33,11 @@ public enum NPCPosition {
* The position the NPC should be in while un-crafting items * The position the NPC should be in while un-crafting items
*/ */
WORKING_CRAFTING("crafting-workstation", List.of(ScrapperTrait.class)), WORKING_CRAFTING("crafting-workstation", List.of(ScrapperTrait.class)),
/**
* The position the NPC should be in while salvaging an enchanted book
*/
WORKING_SPLITTING("enchanted-book-workstation", List.of(ScrapperTrait.class)),
; ;
private final String positionName; private final String positionName;
@ -71,6 +76,7 @@ public enum NPCPosition {
case CRAFTING_TABLE -> NPCPosition.WORKING_CRAFTING; case CRAFTING_TABLE -> NPCPosition.WORKING_CRAFTING;
case ANVIL -> NPCPosition.WORKING_REPAIRABLE; case ANVIL -> NPCPosition.WORKING_REPAIRABLE;
case SMITHING_TABLE -> NPCPosition.WORKING_NETHERITE; case SMITHING_TABLE -> NPCPosition.WORKING_NETHERITE;
case ENCHANTING_TABLE -> NPCPosition.WORKING_SPLITTING;
default -> null; default -> null;
}; };
} }

View File

@ -25,15 +25,18 @@ public final class SoundHelper {
public static void playSound(@NotNull Entity entity, @NotNull SoundData soundData) { public static void playSound(@NotNull Entity entity, @NotNull SoundData soundData) {
// Don't play disabled sounds // Don't play disabled sounds
if (!soundData.enabled()) { if (!soundData.enabled()) {
BlacksmithVisuals.debug("Skipping sound " + soundData.sound() + " as it's disabled");
return; return;
} }
World world = entity.getLocation().getWorld(); World world = entity.getLocation().getWorld();
if (world == null) { if (world == null) {
BlacksmithVisuals.debug("Could not play sound, as world is null");
return; return;
} }
int delay = Math.max(soundData.offsetTicks(), 0); int delay = Math.max(soundData.offsetTicks(), 0);
BlacksmithVisuals.debug("Playing sound " + soundData.sound() + " after " + delay + " ticks");
Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () ->
world.playSound(entity, soundData.sound(), soundData.soundCategory(), world.playSound(entity, soundData.sound(), soundData.soundCategory(),
soundData.volume(), soundData.pitch()), delay); soundData.volume(), soundData.pitch()), delay);

View File

@ -1,3 +1,5 @@
# Show debug messages in the console
debug: false
blacksmith: blacksmith:
animation: animation:
# Whether to simulate hitting an anvil or similar by animating the blacksmith's off-hand # Whether to simulate hitting an anvil or similar by animating the blacksmith's off-hand