From 55b7460b9a689c7099abaa89baf79af24ffb5409 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Tue, 14 Jul 2026 11:44:00 -0400 Subject: [PATCH] s --- .../arcane/iris/core/edit/BlockSignal.java | 2 +- .../iris/core/service/EntityRiseSVC.java | 82 +++++++++++++++++++ .../arcane/iris/engine/object/IrisEntity.java | 22 +++-- .../arcane/iris/util/common/scheduling/J.java | 23 ++++++ 4 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 core/src/main/java/art/arcane/iris/core/service/EntityRiseSVC.java diff --git a/core/src/main/java/art/arcane/iris/core/edit/BlockSignal.java b/core/src/main/java/art/arcane/iris/core/edit/BlockSignal.java index bc1958ec2..d1ec0b86b 100644 --- a/core/src/main/java/art/arcane/iris/core/edit/BlockSignal.java +++ b/core/src/main/java/art/arcane/iris/core/edit/BlockSignal.java @@ -117,7 +117,7 @@ public class BlockSignal { e.setTicksLived(1); e.teleport(tg.clone()); e.setVelocity(new Vector(0, 0, 0)); - })) { + }, 0, this::cancel)) { cancel(); } } diff --git a/core/src/main/java/art/arcane/iris/core/service/EntityRiseSVC.java b/core/src/main/java/art/arcane/iris/core/service/EntityRiseSVC.java new file mode 100644 index 000000000..79dd598fc --- /dev/null +++ b/core/src/main/java/art/arcane/iris/core/service/EntityRiseSVC.java @@ -0,0 +1,82 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2022 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package art.arcane.iris.core.service; + +import art.arcane.iris.util.common.plugin.IrisService; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.world.EntitiesLoadEvent; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public class EntityRiseSVC implements IrisService { + private static final NamespacedKey RISE_STAMP = new NamespacedKey("iris", "rise_restore"); + + @Override + public void onEnable() { + } + + @Override + public void onDisable() { + } + + public static void stamp(Entity entity, boolean invulnerable, boolean ai, boolean collidable) { + byte flags = 0; + if (invulnerable) { + flags |= 1; + } + if (ai) { + flags |= 2; + } + if (collidable) { + flags |= 4; + } + entity.getPersistentDataContainer().set(RISE_STAMP, PersistentDataType.BYTE, flags); + } + + public static void clearStamp(Entity entity) { + entity.getPersistentDataContainer().remove(RISE_STAMP); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void on(EntitiesLoadEvent e) { + for (Entity entity : e.getEntities()) { + restoreStranded(entity); + } + } + + private static void restoreStranded(Entity entity) { + PersistentDataContainer container = entity.getPersistentDataContainer(); + Byte flags = container.get(RISE_STAMP, PersistentDataType.BYTE); + if (flags == null) { + return; + } + + container.remove(RISE_STAMP); + entity.setInvulnerable((flags & 1) != 0); + if (entity instanceof LivingEntity living) { + living.setAI((flags & 2) != 0); + living.setCollidable((flags & 4) != 0); + living.setNoDamageTicks(0); + } + } +} diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java b/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java index 21ba56ed7..8b3126d6d 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisEntity.java @@ -22,6 +22,7 @@ import art.arcane.iris.spi.IrisServices; import art.arcane.iris.core.IrisSettings; import art.arcane.iris.core.link.Identifier; import art.arcane.iris.core.loader.IrisRegistrant; +import art.arcane.iris.core.service.EntityRiseSVC; import art.arcane.iris.core.service.ExternalDataSVC; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.platform.EngineBukkitOps; @@ -389,16 +390,18 @@ public class IrisEntity extends IrisRegistrant { boolean originalAi = living.hasAI(); boolean originalCollidable = living.isCollidable(); int originalNoDamageTicks = living.getNoDamageTicks(); + EntityRiseSVC.stamp(e, originalInvulnerable, originalAi, originalCollidable); e.setInvulnerable(true); living.setAI(false); living.setCollidable(false); living.setNoDamageTicks(100000); + Runnable restore = () -> restoreRiseState(e, living, originalInvulnerable, originalAi, + originalCollidable, originalNoDamageTicks); AtomicInteger t = new AtomicInteger(0); Runnable[] loop = new Runnable[1]; loop[0] = () -> { if (t.get() > 100 || e.isDead()) { - restoreRiseState(e, living, originalInvulnerable, originalAi, - originalCollidable, originalNoDamageTicks); + restore.run(); return; } @@ -410,16 +413,16 @@ public class IrisEntity extends IrisRegistrant { if (M.r(0.2)) { e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f); } - if (!J.runEntity(e, loop[0], 1)) { - restoreRiseState(e, living, originalInvulnerable, originalAi, - originalCollidable, originalNoDamageTicks); + if (!J.runEntity(e, loop[0], 1, restore)) { + restore.run(); } } else { - restoreRiseState(e, living, originalInvulnerable, originalAi, - originalCollidable, originalNoDamageTicks); + restore.run(); } }; - J.runEntity(e, loop[0]); + if (!J.runEntity(e, loop[0], 0, restore)) { + restore.run(); + } } }); @@ -433,6 +436,7 @@ public class IrisEntity extends IrisRegistrant { living.setCollidable(collidable); living.setAI(ai); entity.setInvulnerable(invulnerable); + EntityRiseSVC.clearStamp(entity); } private int surfaceY(Location l) { @@ -498,7 +502,7 @@ public class IrisEntity extends IrisRegistrant { private static final class BukkitOps { private static void persistVillager(Villager villager) { - J.runEntity(villager, () -> villager.setPersistent(true), 1); + villager.setPersistent(true); } private static void bindLoot(IrisEntity entity, Engine gen, Lootable l, Location finalAt, RNG rng) { diff --git a/core/src/main/java/art/arcane/iris/util/common/scheduling/J.java b/core/src/main/java/art/arcane/iris/util/common/scheduling/J.java index 3363635d7..9bcc834d3 100644 --- a/core/src/main/java/art/arcane/iris/util/common/scheduling/J.java +++ b/core/src/main/java/art/arcane/iris/util/common/scheduling/J.java @@ -258,6 +258,29 @@ public class J { return true; } + public static boolean runEntity(Entity entity, Runnable runnable, int delayTicks, Runnable retired) { + if (retired == null) { + return runEntity(entity, runnable, delayTicks); + } + + if (entity == null || runnable == null) { + return false; + } + + if (isFolia()) { + return FoliaScheduler.runEntity(BukkitPlatform.plugin(), entity, runnable, Math.max(0, delayTicks), retired); + } + + Runnable guarded = () -> { + if (entity.isValid()) { + runnable.run(); + } else { + retired.run(); + } + }; + return runEntity(entity, guarded, delayTicks); + } + public static boolean runRegion(World world, int chunkX, int chunkZ, Runnable runnable) { if (world == null || runnable == null) { return false;