mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-01 23:47:21 +00:00
fix updater and mob spawning instantly failing
This commit is contained in:
parent
35b879f0df
commit
e461c1e199
@ -188,9 +188,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
|
||||
int r = 1;
|
||||
|
||||
int cX = i.getLocation().getBlockX() >> 4;
|
||||
int cZ = i.getLocation().getBlockZ() >> 4;
|
||||
for (int x = -r; x <= r; x++) {
|
||||
for (int z = -r; z <= r; z++) {
|
||||
mantle.getChunk(i.getLocation().getChunk()).flag(MantleFlag.DISCOVERED, true);
|
||||
mantle.getChunk(cX + x, cZ + z).flag(MantleFlag.DISCOVERED, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,20 +202,22 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
|
||||
int r = 1;
|
||||
|
||||
Chunk c = i.getLocation().getChunk();
|
||||
for (int x = -r; x <= r; x++) {
|
||||
for (int z = -r; z <= r; z++) {
|
||||
if (c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z) && Chunks.isSafe(getEngine().getWorld().realWorld(), c.getX() + x, c.getZ() + z)) {
|
||||
Iris.scheduler.entity(i).run(() -> {
|
||||
Chunk c = i.getLocation().getChunk();
|
||||
for (int x = -r; x <= r; x++) {
|
||||
for (int z = -r; z <= r; z++) {
|
||||
int cX = c.getX() + x;
|
||||
int cZ = c.getZ() + z;
|
||||
if (!c.getWorld().isChunkLoaded(cX, cZ) || !Chunks.isSafe(getEngine().getWorld().realWorld(), cX, cZ))
|
||||
continue;
|
||||
|
||||
if (IrisSettings.get().getWorld().isPostLoadBlockUpdates()) {
|
||||
getEngine().updateChunk(c.getWorld().getChunkAt(c.getX() + x, c.getZ() + z));
|
||||
getEngine().updateChunk(c.getWorld().getChunkAt(cX, cZ));
|
||||
}
|
||||
|
||||
if (IrisSettings.get().getWorld().isMarkerEntitySpawningSystem()) {
|
||||
Chunk cx = getEngine().getWorld().realWorld().getChunkAt(c.getX() + x, c.getZ() + z);
|
||||
int finalX = c.getX() + x;
|
||||
int finalZ = c.getZ() + z;
|
||||
J.a(() -> getMantle().raiseFlag(finalX, finalZ, MantleFlag.INITIAL_SPAWNED_MARKER,
|
||||
Chunk cx = getEngine().getWorld().realWorld().getChunkAt(cX, cZ);
|
||||
J.a(() -> getMantle().raiseFlag(cX, cZ, MantleFlag.INITIAL_SPAWNED_MARKER,
|
||||
() -> {
|
||||
J.a(() -> spawnIn(cx, true), RNG.r.i(5, 200));
|
||||
getSpawnersFromMarkers(cx).forEach((blockf, spawners) -> {
|
||||
@ -229,7 +233,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,19 +536,17 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
IrisPosition pos = new IrisPosition((c.getX() << 4) + x, y, (c.getZ() << 4) + z);
|
||||
|
||||
if (mark.isEmptyAbove()) {
|
||||
AtomicBoolean remove = new AtomicBoolean(false);
|
||||
Boolean remove = Iris.scheduler.region()
|
||||
.run(c.getWorld(), c.getX(), c.getZ(), () -> c.getBlock(x, y + 1, z).getType().isSolid() || c.getBlock(x, y + 2, z).getType().isSolid())
|
||||
.result()
|
||||
.exceptionally(e -> {
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
})
|
||||
.join();
|
||||
|
||||
try {
|
||||
J.sfut(() -> {
|
||||
if (c.getBlock(x, y + 1, z).getBlockData().getMaterial().isSolid() || c.getBlock(x, y + 2, z).getBlockData().getMaterial().isSolid()) {
|
||||
remove.set(true);
|
||||
}
|
||||
}).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (remove.get()) {
|
||||
if (remove == Boolean.TRUE) {
|
||||
b.add(pos);
|
||||
return;
|
||||
}
|
||||
|
@ -293,20 +293,21 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
try {
|
||||
Semaphore semaphore = new Semaphore(3);
|
||||
chunk.raiseFlag(MantleFlag.ETCHED, () -> {
|
||||
chunk.raiseFlag(MantleFlag.TILE, run(semaphore, () -> J.s(() -> {
|
||||
var region = Iris.scheduler.region();
|
||||
chunk.raiseFlag(MantleFlag.TILE, run(semaphore, () -> region.run(c.getWorld(), c.getX(), c.getZ(), () -> {
|
||||
mantle.iterateChunk(c.getX(), c.getZ(), TileWrapper.class, (x, y, z, v) -> {
|
||||
int betterY = y + getWorld().minHeight();
|
||||
if (!TileData.setTileState(c.getBlock(x, betterY, z), v.getData()))
|
||||
Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", x, betterY, z, c.getBlock(x, betterY, z).getBlockData().getMaterial().getKey(), v.getData().getMaterial().name());
|
||||
});
|
||||
})));
|
||||
chunk.raiseFlag(MantleFlag.CUSTOM, run(semaphore, () -> J.s(() -> {
|
||||
chunk.raiseFlag(MantleFlag.CUSTOM, run(semaphore, () -> region.run(c.getWorld(), c.getX(), c.getZ(), () -> {
|
||||
mantle.iterateChunk(c.getX(), c.getZ(), Identifier.class, (x, y, z, v) -> {
|
||||
Iris.service(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v);
|
||||
});
|
||||
})));
|
||||
|
||||
chunk.raiseFlag(MantleFlag.UPDATE, run(semaphore, () -> J.s(() -> {
|
||||
chunk.raiseFlag(MantleFlag.UPDATE, run(semaphore, () -> region.runDelayed(c.getWorld(), c.getX(), c.getZ(), () -> {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
KMap<Long, Integer> updates = new KMap<>();
|
||||
RNG r = new RNG(Cache.key(c.getX(), c.getZ()));
|
||||
@ -353,7 +354,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
});
|
||||
mantle.deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class);
|
||||
getMetrics().getUpdates().put(p.getMilliseconds());
|
||||
}, RNG.r.i(0, 20))));
|
||||
}, RNG.r.i(1, 20))));
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -31,8 +31,6 @@ import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.plugin.Chunks;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -48,13 +46,11 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.loot.LootContext;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.volmit.iris.util.data.registry.Particles.ITEM;
|
||||
|
||||
@ -181,37 +177,33 @@ public class IrisEntity extends IrisRegistrant {
|
||||
return spawn(gen, at, new RNG(at.hashCode()));
|
||||
}
|
||||
|
||||
public Entity spawn(Engine gen, Location at, RNG rng) {
|
||||
public Entity spawn(Engine gen, final Location at, RNG rng) {
|
||||
if (!Iris.scheduler.isOwnedByCurrentRegion(at)) {
|
||||
try {
|
||||
final Location finalAt = at;
|
||||
return Iris.scheduler.region().run(at, () -> spawn(gen, finalAt, rng))
|
||||
.result()
|
||||
.get(500, TimeUnit.MILLISECONDS);
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Chunks.isSafe(at)) {
|
||||
return null;
|
||||
}
|
||||
if (isSpawnEffectRiseOutOfGround()) {
|
||||
AtomicReference<Location> f = new AtomicReference<>(at);
|
||||
try {
|
||||
J.sfut(() -> {
|
||||
if (Chunks.hasPlayersNearby(f.get())) {
|
||||
Location b = f.get().clone();
|
||||
Location start = new Location(b.getWorld(), b.getX(), b.getY() - 5, b.getZ());
|
||||
f.set(start);
|
||||
}
|
||||
}).get();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
at = f.get();
|
||||
if (isSpawnEffectRiseOutOfGround() && Chunks.hasPlayersNearby(at)) {
|
||||
at.add(0, -5, 0);
|
||||
}
|
||||
|
||||
Entity ee = doSpawn(at);
|
||||
|
||||
if (ee == null && !Chunks.isSafe(at)) {
|
||||
if (ee == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!spawnerScript.isEmpty() && ee == null) {
|
||||
synchronized (this) {
|
||||
gen.getExecution().getAPI().setLocation(at);
|
||||
gen.getExecution().getAPI().setLocation(at.clone());
|
||||
try {
|
||||
ee = (Entity) gen.getExecution().evaluate(spawnerScript);
|
||||
} catch (Throwable ex) {
|
||||
@ -240,109 +232,96 @@ public class IrisEntity extends IrisRegistrant {
|
||||
|
||||
int gg = 0;
|
||||
for (IrisEntity i : passengers) {
|
||||
Entity passenger = i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++));
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
J.s(() -> e.addPassenger(passenger));
|
||||
}
|
||||
e.addPassenger(i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++)));
|
||||
}
|
||||
|
||||
if (e instanceof Attributable) {
|
||||
Attributable a = (Attributable) e;
|
||||
|
||||
if (e instanceof Attributable attributable) {
|
||||
for (IrisAttributeModifier i : getAttributes()) {
|
||||
i.apply(rng, a);
|
||||
i.apply(rng, attributable);
|
||||
}
|
||||
}
|
||||
|
||||
if (e instanceof Lootable) {
|
||||
Lootable l = (Lootable) e;
|
||||
if (e instanceof Lootable lootable && getLoot().getTables().isNotEmpty()) {
|
||||
lootable.setLootTable(new LootTable() {
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode());
|
||||
}
|
||||
|
||||
if (getLoot().getTables().isNotEmpty()) {
|
||||
Location finalAt = at;
|
||||
l.setLootTable(new LootTable() {
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode());
|
||||
@Override
|
||||
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
|
||||
KList<ItemStack> items = new KList<>();
|
||||
|
||||
for (String fi : getLoot().getTables()) {
|
||||
IrisLootTable i = gen.getData().getLootLoader().load(fi);
|
||||
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, at.getWorld(), at.getBlockX(), at.getBlockY(), at.getBlockZ()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
|
||||
KList<ItemStack> items = new KList<>();
|
||||
return items;
|
||||
}
|
||||
|
||||
for (String fi : getLoot().getTables()) {
|
||||
IrisLootTable i = gen.getData().getLootLoader().load(fi);
|
||||
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getWorld(), finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ()));
|
||||
}
|
||||
|
||||
return items;
|
||||
@Override
|
||||
public void fillInventory(Inventory inventory, Random random, LootContext context) {
|
||||
for (ItemStack i : populateLoot(random, context)) {
|
||||
inventory.addItem(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInventory(Inventory inventory, Random random, LootContext context) {
|
||||
for (ItemStack i : populateLoot(random, context)) {
|
||||
inventory.addItem(i);
|
||||
}
|
||||
|
||||
gen.scramble(inventory, rng);
|
||||
}
|
||||
});
|
||||
}
|
||||
gen.scramble(inventory, rng);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (e instanceof LivingEntity) {
|
||||
LivingEntity l = (LivingEntity) e;
|
||||
l.setAI(isAi());
|
||||
l.setCanPickupItems(isPickupItems());
|
||||
if (e instanceof LivingEntity living) {
|
||||
living.setAI(isAi());
|
||||
living.setCanPickupItems(isPickupItems());
|
||||
|
||||
if (getLeashHolder() != null) {
|
||||
l.setLeashHolder(getLeashHolder().spawn(gen, at, rng.nextParallelRNG(234548)));
|
||||
living.setLeashHolder(getLeashHolder().spawn(gen, at, rng.nextParallelRNG(234548)));
|
||||
}
|
||||
|
||||
l.setRemoveWhenFarAway(isRemovable());
|
||||
living.setRemoveWhenFarAway(isRemovable());
|
||||
|
||||
if (getHelmet() != null && rng.i(1, getHelmet().getRarity()) == 1) {
|
||||
l.getEquipment().setHelmet(getHelmet().get(gen.isStudio(), rng));
|
||||
living.getEquipment().setHelmet(getHelmet().get(gen.isStudio(), rng));
|
||||
}
|
||||
|
||||
if (getChestplate() != null && rng.i(1, getChestplate().getRarity()) == 1) {
|
||||
l.getEquipment().setChestplate(getChestplate().get(gen.isStudio(), rng));
|
||||
living.getEquipment().setChestplate(getChestplate().get(gen.isStudio(), rng));
|
||||
}
|
||||
|
||||
if (getLeggings() != null && rng.i(1, getLeggings().getRarity()) == 1) {
|
||||
l.getEquipment().setLeggings(getLeggings().get(gen.isStudio(), rng));
|
||||
living.getEquipment().setLeggings(getLeggings().get(gen.isStudio(), rng));
|
||||
}
|
||||
|
||||
if (getBoots() != null && rng.i(1, getBoots().getRarity()) == 1) {
|
||||
l.getEquipment().setBoots(getBoots().get(gen.isStudio(), rng));
|
||||
living.getEquipment().setBoots(getBoots().get(gen.isStudio(), rng));
|
||||
}
|
||||
|
||||
if (getMainHand() != null && rng.i(1, getMainHand().getRarity()) == 1) {
|
||||
l.getEquipment().setItemInMainHand(getMainHand().get(gen.isStudio(), rng));
|
||||
living.getEquipment().setItemInMainHand(getMainHand().get(gen.isStudio(), rng));
|
||||
}
|
||||
|
||||
if (getOffHand() != null && rng.i(1, getOffHand().getRarity()) == 1) {
|
||||
l.getEquipment().setItemInOffHand(getOffHand().get(gen.isStudio(), rng));
|
||||
living.getEquipment().setItemInOffHand(getOffHand().get(gen.isStudio(), rng));
|
||||
}
|
||||
}
|
||||
|
||||
if (e instanceof Ageable && isBaby()) {
|
||||
((Ageable) e).setBaby();
|
||||
if (e instanceof Ageable ageable && isBaby()) {
|
||||
ageable.setBaby();
|
||||
}
|
||||
|
||||
if (e instanceof Panda) {
|
||||
((Panda) e).setMainGene(getPandaMainGene());
|
||||
((Panda) e).setMainGene(getPandaHiddenGene());
|
||||
if (e instanceof Panda panda) {
|
||||
panda.setMainGene(getPandaMainGene());
|
||||
panda.setMainGene(getPandaHiddenGene());
|
||||
}
|
||||
|
||||
if (e instanceof Villager) {
|
||||
Villager villager = (Villager) e;
|
||||
if (e instanceof Villager villager) {
|
||||
villager.setRemoveWhenFarAway(false);
|
||||
Iris.scheduler.entity(villager).run(() -> villager.setPersistent(true), null);
|
||||
villager.setPersistent(true);
|
||||
}
|
||||
|
||||
if (e instanceof Mob) {
|
||||
Mob m = (Mob) e;
|
||||
m.setAware(isAware());
|
||||
if (e instanceof Mob mob) {
|
||||
mob.setAware(isAware());
|
||||
}
|
||||
|
||||
if (spawnEffect != null) {
|
||||
@ -365,40 +344,35 @@ public class IrisEntity extends IrisRegistrant {
|
||||
rawCommands.forEach(r -> r.run(fat));
|
||||
}
|
||||
|
||||
Location finalAt1 = at;
|
||||
if (isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity living && Chunks.hasPlayersNearby(at)) {
|
||||
e.setInvulnerable(true);
|
||||
living.setAI(false);
|
||||
living.setCollidable(false);
|
||||
living.setNoDamageTicks(100000);
|
||||
AtomicInteger t = new AtomicInteger(0);
|
||||
Iris.scheduler.region().runAtFixedRate(at, task -> {
|
||||
if (t.get() > 100) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
J.s(() -> {
|
||||
if (isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity && Chunks.hasPlayersNearby(finalAt1)) {
|
||||
Location start = finalAt1.clone();
|
||||
e.setInvulnerable(true);
|
||||
((LivingEntity) e).setAI(false);
|
||||
((LivingEntity) e).setCollidable(false);
|
||||
((LivingEntity) e).setNoDamageTicks(100000);
|
||||
AtomicInteger t = new AtomicInteger(0);
|
||||
Iris.scheduler.global().runAtFixedRate(task -> {
|
||||
if (t.get() > 100) {
|
||||
task.cancel();
|
||||
return;
|
||||
t.incrementAndGet();
|
||||
if (e.getLocation().getBlock().getType().isSolid() || living.getEyeLocation().getBlock().getType().isSolid()) {
|
||||
Iris.scheduler.teleportAsync(e, at.add(0, 0.1, 0));
|
||||
ItemStack itemCrackData = new ItemStack(living.getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
|
||||
e.getWorld().spawnParticle(ITEM, living.getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
|
||||
if (M.r(0.2)) {
|
||||
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
|
||||
}
|
||||
|
||||
t.incrementAndGet();
|
||||
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
|
||||
e.teleport(start.add(new Vector(0, 0.1, 0)));
|
||||
ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
|
||||
e.getWorld().spawnParticle(ITEM, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
|
||||
if (M.r(0.2)) {
|
||||
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
|
||||
}
|
||||
} else {
|
||||
task.cancel();
|
||||
((LivingEntity) e).setNoDamageTicks(0);
|
||||
((LivingEntity) e).setCollidable(true);
|
||||
((LivingEntity) e).setAI(true);
|
||||
e.setInvulnerable(false);
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
task.cancel();
|
||||
living.setNoDamageTicks(0);
|
||||
living.setCollidable(true);
|
||||
living.setAI(true);
|
||||
e.setInvulnerable(false);
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
return e;
|
||||
@ -428,29 +402,6 @@ public class IrisEntity extends IrisRegistrant {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
// Someone called spawn (worldedit maybe?) on a non server thread
|
||||
// Due to the structure of iris, we will call it sync and busy wait until it's done.
|
||||
AtomicReference<Entity> ae = new AtomicReference<>();
|
||||
|
||||
try {
|
||||
J.s(() -> ae.set(doSpawn(at)));
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
|
||||
while (ae.get() == null) {
|
||||
J.sleep(25);
|
||||
|
||||
if (p.getMilliseconds() > 500) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return ae.get();
|
||||
}
|
||||
|
||||
if (isSpecialType()) {
|
||||
if (specialType.toLowerCase().startsWith("mythicmobs:")) {
|
||||
return Iris.linkMythicMobs.spawnMob(specialType.substring(11), at);
|
||||
|
@ -36,8 +36,14 @@ import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static com.volmit.iris.Iris.scheduler;
|
||||
|
||||
@Snippet("entity-spawn")
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@ -164,8 +170,15 @@ public class IrisEntitySpawn implements IRare {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ignoreSurfaces && !irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock())) {
|
||||
return null;
|
||||
if (!ignoreSurfaces) {
|
||||
Location block = at.clone().subtract(0, 1, 0);
|
||||
BlockData data = scheduler.region()
|
||||
.run(block, () -> block.getBlock().getBlockData())
|
||||
.result()
|
||||
.join();
|
||||
if (!irisEntity.getSurface().matches(data)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3d boundingBox = INMS.get().getBoundingbox(irisEntity.getType());
|
||||
@ -199,15 +212,22 @@ public class IrisEntitySpawn implements IRare {
|
||||
int startZ = center.getBlockZ() - (int) (boundingBox.z / 2);
|
||||
int endZ = center.getBlockZ() + (int) (boundingBox.z / 2);
|
||||
|
||||
var region = scheduler.region();
|
||||
var lock = new Semaphore(Integer.MAX_VALUE, true);
|
||||
var bool = new AtomicBoolean(true);
|
||||
for (int x = startX; x <= endX; x++) {
|
||||
for (int y = startY; y <= endY; y++) {
|
||||
for (int z = startZ; z <= endZ; z++) {
|
||||
if (world.getBlockAt(x, y, z).getType() != Material.AIR) {
|
||||
return false;
|
||||
}
|
||||
Location l = new Location(world, x, y, z);
|
||||
lock.acquireUninterruptibly();
|
||||
region.run(l, () -> {
|
||||
if (!bool.get()) return false;
|
||||
return bool.compareAndSet(true, l.getBlock().getType() == Material.AIR);
|
||||
}).result().exceptionally(f -> false).thenRun(lock::release);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
lock.acquireUninterruptibly(Integer.MAX_VALUE);
|
||||
return bool.get();
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.engine.object.annotations.Desc;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
|
||||
@Desc("The type of surface entities should spawn on")
|
||||
@ -47,8 +47,8 @@ public enum IrisSurface {
|
||||
* @param state The blockstate
|
||||
* @return True if it matches
|
||||
*/
|
||||
public boolean matches(Block state) {
|
||||
Material type = state.getType();
|
||||
public boolean matches(BlockData state) {
|
||||
Material type = state.getMaterial();
|
||||
if (type.isSolid()) {
|
||||
return this == LAND || this == OVERWORLD || (this == ANIMAL
|
||||
&& (type == Material.GRASS_BLOCK || type == Material.DIRT
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.container.Pair;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
@ -80,7 +80,7 @@ public class LegacyTileData extends TileData {
|
||||
|
||||
@Override
|
||||
public void toBukkit(Block block) {
|
||||
J.s(() -> handler.toBukkit(block));
|
||||
Iris.scheduler.region().run(block.getLocation(), () -> handler.toBukkit(block));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user