From e24ddee666ac20e0b6e157dc0d5951e33410ce4e Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 8 Apr 2026 13:13:33 -0700 Subject: [PATCH] Make MythicMobsHook.spawnMythicMob delay configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing spawnMythicMob overloads hard-coded a 40-tick (2-second) delay before the actual spawn — added for blueprint-paste callers so NMS-pasted blocks settle before mobs land on them. Synchronous callers (e.g. AOneBlock's MythicMobCustomBlock) that replace a single block via the Bukkit API have nothing to wait for, so that delay is pure dead time in their path. Add a 4-arg spawnMythicMob(record, location, Consumer, long) overload that takes an explicit delayTicks parameter. delayTicks <= 0 runs the spawn inline on the current tick; positive values still go through runTaskLater. The existing 3-arg overload now delegates with 40L so blueprint-paste behaviour is unchanged, and the 2-arg overload keeps its existing chain. This lets AOneBlock bosses appear on the same tick as the magic-block break without affecting any other caller. Co-Authored-By: Claude Opus 4.6 --- .../bentobox/hooks/MythicMobsHook.java | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java b/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java index 40273c9ac..0cff041d7 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java @@ -63,11 +63,9 @@ public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation) { /** * Spawn a MythicMob and run a callback once the entity has actually been spawned. *

- * Spawning is delayed by 40 ticks inside this hook (to give NMS-pasted blocks time - * to settle), which means the caller cannot act on the spawned entity synchronously. - * This overload accepts a {@link Consumer} that will be invoked with the live Bukkit - * {@link Entity} once the mob has been spawned, so that addons (e.g. AOneBlock) can - * perform follow-up work such as clearing space for large hitboxes. + * Delegates to {@link #spawnMythicMob(MythicMobRecord, Location, Consumer, long)} + * with a 40-tick delay — the historical behaviour, required by blueprint-paste + * callers so blocks settle before mobs land on them. * * @param mmr MythicMobRecord * @param spawnLocation location @@ -76,13 +74,32 @@ public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation) { * @since 3.14.0 */ public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation, Consumer onSpawn) { + return spawnMythicMob(mmr, spawnLocation, onSpawn, 40L); + } + + /** + * Spawn a MythicMob with an explicit scheduler delay. + *

+ * Blueprint-paste callers need a short delay so NMS-pasted blocks settle + * before mobs land on them; synchronous callers (e.g. AOneBlock's + * {@code MythicMobCustomBlock}) can pass {@code 0} to spawn immediately on + * the current tick. When {@code delayTicks <= 0} the spawn runs inline and + * the {@code onSpawn} callback is invoked synchronously. + * + * @param mmr MythicMobRecord + * @param spawnLocation location + * @param onSpawn callback invoked with the spawned Bukkit entity; may be {@code null} + * @param delayTicks ticks to wait before spawning; {@code <= 0} = spawn immediately + * @return true if the mob type exists and a spawn was scheduled (or ran) + * @since 3.15.0 + */ + public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation, + Consumer onSpawn, long delayTicks) { if (!this.isPluginAvailable()) { return false; } return MythicBukkit.inst().getMobManager().getMythicMob(mmr.type()).map(mob -> { - // A delay is required before spawning, I assume because the blocks are pasted using NMS - Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { - // spawns mob + Runnable spawn = () -> { ActiveMob activeMob = mob.spawn(BukkitAdapter.adapt(spawnLocation), mmr.level()); activeMob.setDisplayName(mmr.displayName()); activeMob.setPower(mmr.power()); @@ -93,7 +110,12 @@ public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation, Consu onSpawn.accept(bukkitEntity); } } - }, 40L); + }; + if (delayTicks <= 0L) { + spawn.run(); + } else { + Bukkit.getScheduler().runTaskLater(getPlugin(), spawn, delayTicks); + } return true; }).orElse(false); }