mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-20 03:04:08 +00:00
Spawners
This commit is contained in:
parent
8cd94f976c
commit
16de60f82d
@ -40,6 +40,7 @@ public class IrisDataManager {
|
|||||||
private ResourceLoader<IrisJigsawPool> jigsawPoolLoader;
|
private ResourceLoader<IrisJigsawPool> jigsawPoolLoader;
|
||||||
private ResourceLoader<IrisJigsawStructure> jigsawStructureLoader;
|
private ResourceLoader<IrisJigsawStructure> jigsawStructureLoader;
|
||||||
private ResourceLoader<IrisEntity> entityLoader;
|
private ResourceLoader<IrisEntity> entityLoader;
|
||||||
|
private ResourceLoader<IrisSpawner> spawnerLoader;
|
||||||
private ResourceLoader<IrisMod> modLoader;
|
private ResourceLoader<IrisMod> modLoader;
|
||||||
private ResourceLoader<IrisBlockData> blockLoader;
|
private ResourceLoader<IrisBlockData> blockLoader;
|
||||||
private ObjectResourceLoader objectLoader;
|
private ObjectResourceLoader objectLoader;
|
||||||
@ -67,6 +68,7 @@ public class IrisDataManager {
|
|||||||
this.biomeLoader = null;
|
this.biomeLoader = null;
|
||||||
this.modLoader = null;
|
this.modLoader = null;
|
||||||
this.dimensionLoader = null;
|
this.dimensionLoader = null;
|
||||||
|
this.spawnerLoader = null;
|
||||||
this.jigsawPoolLoader = null;
|
this.jigsawPoolLoader = null;
|
||||||
this.jigsawPieceLoader = null;
|
this.jigsawPieceLoader = null;
|
||||||
this.generatorLoader = null;
|
this.generatorLoader = null;
|
||||||
@ -91,6 +93,7 @@ public class IrisDataManager {
|
|||||||
File packs = dataFolder;
|
File packs = dataFolder;
|
||||||
packs.mkdirs();
|
packs.mkdirs();
|
||||||
this.lootLoader = new ResourceLoader<>(packs, this, "loot", "Loot", IrisLootTable.class);
|
this.lootLoader = new ResourceLoader<>(packs, this, "loot", "Loot", IrisLootTable.class);
|
||||||
|
this.spawnerLoader = new ResourceLoader<>(packs, this, "spawners", "Spawner", IrisSpawner.class);
|
||||||
this.entityLoader = new ResourceLoader<>(packs, this, "entities", "Entity", IrisEntity.class);
|
this.entityLoader = new ResourceLoader<>(packs, this, "entities", "Entity", IrisEntity.class);
|
||||||
this.regionLoader = new ResourceLoader<>(packs, this, "regions", "Region", IrisRegion.class);
|
this.regionLoader = new ResourceLoader<>(packs, this, "regions", "Region", IrisRegion.class);
|
||||||
this.biomeLoader = new ResourceLoader<>(packs, this, "biomes", "Biome", IrisBiome.class);
|
this.biomeLoader = new ResourceLoader<>(packs, this, "biomes", "Biome", IrisBiome.class);
|
||||||
@ -112,6 +115,7 @@ public class IrisDataManager {
|
|||||||
blockLoader.clearCache();
|
blockLoader.clearCache();
|
||||||
lootLoader.clearCache();
|
lootLoader.clearCache();
|
||||||
objectLoader.clearCache();
|
objectLoader.clearCache();
|
||||||
|
spawnerLoader.clearCache();
|
||||||
jigsawPieceLoader.clearCache();
|
jigsawPieceLoader.clearCache();
|
||||||
jigsawPoolLoader.clearCache();
|
jigsawPoolLoader.clearCache();
|
||||||
modLoader.clearCache();
|
modLoader.clearCache();
|
||||||
@ -132,6 +136,7 @@ public class IrisDataManager {
|
|||||||
entityLoader.clearList();
|
entityLoader.clearList();
|
||||||
biomeLoader.clearList();
|
biomeLoader.clearList();
|
||||||
modLoader.clearList();
|
modLoader.clearList();
|
||||||
|
spawnerLoader.clearList();
|
||||||
regionLoader.clearList();
|
regionLoader.clearList();
|
||||||
dimensionLoader.clearList();
|
dimensionLoader.clearList();
|
||||||
generatorLoader.clearList();
|
generatorLoader.clearList();
|
||||||
@ -173,6 +178,10 @@ public class IrisDataManager {
|
|||||||
return loadAny(key, (dm) -> dm.getBlockLoader().load(key, false));
|
return loadAny(key, (dm) -> dm.getBlockLoader().load(key, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IrisSpawner loadAnySpaner(String key) {
|
||||||
|
return loadAny(key, (dm) -> dm.getSpawnerLoader().load(key, false));
|
||||||
|
}
|
||||||
|
|
||||||
public static IrisRegion loadAnyRegion(String key) {
|
public static IrisRegion loadAnyRegion(String key) {
|
||||||
return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false));
|
return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false));
|
||||||
}
|
}
|
||||||
|
@ -474,6 +474,7 @@ public class IrisProject {
|
|||||||
KSet<IrisRegion> regions = new KSet<>();
|
KSet<IrisRegion> regions = new KSet<>();
|
||||||
KSet<IrisBiome> biomes = new KSet<>();
|
KSet<IrisBiome> biomes = new KSet<>();
|
||||||
KSet<IrisEntity> entities = new KSet<>();
|
KSet<IrisEntity> entities = new KSet<>();
|
||||||
|
KSet<IrisSpawner> spawners = new KSet<>();
|
||||||
KSet<IrisGenerator> generators = new KSet<>();
|
KSet<IrisGenerator> generators = new KSet<>();
|
||||||
KSet<IrisLootTable> loot = new KSet<>();
|
KSet<IrisLootTable> loot = new KSet<>();
|
||||||
KSet<IrisBlockData> blocks = new KSet<>();
|
KSet<IrisBlockData> blocks = new KSet<>();
|
||||||
@ -503,13 +504,9 @@ public class IrisProject {
|
|||||||
});
|
});
|
||||||
dimension.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i)));
|
dimension.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i)));
|
||||||
regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null)));
|
regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null)));
|
||||||
biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator(null))));
|
|
||||||
regions.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i))));
|
regions.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i))));
|
||||||
biomes.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i))));
|
regions.forEach((r) -> r.getEntitySpawners().forEach((sp) -> spawners.add(dm.getSpawnerLoader().load(sp))));
|
||||||
biomes.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
|
dimension.getEntitySpawners().forEach((sp) -> spawners.add(dm.getSpawnerLoader().load(sp)));
|
||||||
regions.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
|
|
||||||
dimension.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())));
|
|
||||||
biomes.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
|
|
||||||
|
|
||||||
for (int f = 0; f < IrisSettings.get().getGenerator().getMaxBiomeChildDepth(); f++) {
|
for (int f = 0; f < IrisSettings.get().getGenerator().getMaxBiomeChildDepth(); f++) {
|
||||||
biomes.copy().forEach((r) -> {
|
biomes.copy().forEach((r) -> {
|
||||||
@ -521,8 +518,10 @@ public class IrisProject {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
regions.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
|
biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator(null))));
|
||||||
dimension.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())));
|
biomes.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i))));
|
||||||
|
biomes.forEach((r) -> r.getEntitySpawners().forEach((sp) -> spawners.add(dm.getSpawnerLoader().load(sp))));
|
||||||
|
spawners.forEach((i) -> i.getSpawns().forEach((j) -> entities.add(dm.getEntityLoader().load(j.getEntity()))));
|
||||||
KMap<String, String> renameObjects = new KMap<>();
|
KMap<String, String> renameObjects = new KMap<>();
|
||||||
String a;
|
String a;
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
|
@ -187,7 +187,21 @@ public class SchemaBuilder {
|
|||||||
fancyType = "Mythic Mob Type";
|
fancyType = "Mythic Mob Type";
|
||||||
prop.put("$ref", "#/definitions/" + key);
|
prop.put("$ref", "#/definitions/" + key);
|
||||||
description.add(SYMBOL_TYPE__N + " Must be a valid Mythic Mob Type (use ctrl+space for auto complete!) Define mythic mobs with the mythic mobs plugin configuration files.");
|
description.add(SYMBOL_TYPE__N + " Must be a valid Mythic Mob Type (use ctrl+space for auto complete!) Define mythic mobs with the mythic mobs plugin configuration files.");
|
||||||
} else if (k.isAnnotationPresent(RegistryListBlockType.class)) {
|
}
|
||||||
|
else if (k.isAnnotationPresent(RegistryListSpawner.class)) {
|
||||||
|
String key = "enum-reg-spawner";
|
||||||
|
|
||||||
|
if (!definitions.containsKey(key)) {
|
||||||
|
JSONObject j = new JSONObject();
|
||||||
|
j.put("enum", new JSONArray(data.getSpawnerLoader().getPossibleKeys()));
|
||||||
|
definitions.put(key, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
fancyType = "Iris Spawner";
|
||||||
|
prop.put("$ref", "#/definitions/" + key);
|
||||||
|
description.add(SYMBOL_TYPE__N + " Must be a valid Spawner (use ctrl+space for auto complete!)");
|
||||||
|
}
|
||||||
|
else if (k.isAnnotationPresent(RegistryListBlockType.class)) {
|
||||||
String key = "enum-block-type";
|
String key = "enum-block-type";
|
||||||
|
|
||||||
if (!definitions.containsKey(key)) {
|
if (!definitions.containsKey(key)) {
|
||||||
@ -463,7 +477,23 @@ public class SchemaBuilder {
|
|||||||
items.put("$ref", "#/definitions/" + key);
|
items.put("$ref", "#/definitions/" + key);
|
||||||
prop.put("items", items);
|
prop.put("items", items);
|
||||||
description.add(SYMBOL_TYPE__N + " Must be a valid Biome (use ctrl+space for auto complete!)");
|
description.add(SYMBOL_TYPE__N + " Must be a valid Biome (use ctrl+space for auto complete!)");
|
||||||
} else if (k.isAnnotationPresent(RegistryListMythical.class)) {
|
}
|
||||||
|
else if (k.isAnnotationPresent(RegistryListSpawner.class)) {
|
||||||
|
fancyType = "List of Iris Spawners";
|
||||||
|
String key = "enum-reg-spawner";
|
||||||
|
|
||||||
|
if (!definitions.containsKey(key)) {
|
||||||
|
JSONObject j = new JSONObject();
|
||||||
|
j.put("enum", new JSONArray(data.getSpawnerLoader().getPossibleKeys()));
|
||||||
|
definitions.put(key, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject items = new JSONObject();
|
||||||
|
items.put("$ref", "#/definitions/" + key);
|
||||||
|
prop.put("items", items);
|
||||||
|
description.add(SYMBOL_TYPE__N + " Must be a valid Spawner (use ctrl+space for auto complete!)");
|
||||||
|
}
|
||||||
|
else if (k.isAnnotationPresent(RegistryListMythical.class)) {
|
||||||
fancyType = "List of Mythic Mob Types";
|
fancyType = "List of Mythic Mob Types";
|
||||||
String key = "enum-reg-mythical";
|
String key = "enum-reg-mythical";
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
baseBiomeStream = focus != null ? ProceduralStream.of((x, z) -> focus,
|
baseBiomeStream = focus != null ? ProceduralStream.of((x, z) -> focus,
|
||||||
Interpolated.of(a -> 0D, a -> focus)) :
|
Interpolated.of(a -> 0D, a -> focus)) :
|
||||||
bridgeStream.convertAware2D((t, x, z) -> inferredStreams.get(t).get(x, z))
|
bridgeStream.convertAware2D((t, x, z) -> inferredStreams.get(t).get(x, z))
|
||||||
.cache2D(cacheSize);
|
.convertAware2D(this::implode).cache2D(cacheSize);
|
||||||
heightStream = ProceduralStream.of((x, z) -> {
|
heightStream = ProceduralStream.of((x, z) -> {
|
||||||
IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
|
IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
|
||||||
return getHeight(engine, b, x, z, engine.getWorld().seed(), true);
|
return getHeight(engine, b, x, z, engine.getWorld().seed(), true);
|
||||||
@ -470,4 +470,29 @@ public class IrisComplex implements DataProvider {
|
|||||||
|
|
||||||
generators.add(cachedGenerator);
|
generators.add(cachedGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IrisBiome implode(IrisBiome b, Double x, Double z) {
|
||||||
|
if (b.getChildren().isEmpty()) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(b, x, z, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IrisBiome implode(IrisBiome b, Double x, Double z, int max) {
|
||||||
|
if (max < 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.getChildren().isEmpty()) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNG childCell = b.getChildrenGenerator(rng, 123, b.getChildShrinkFactor());
|
||||||
|
KList<IrisBiome> chx = b.getRealChildren(this).copy();
|
||||||
|
chx.add(b);
|
||||||
|
IrisBiome biome = childCell.fitRarity(chx, x, z);
|
||||||
|
biome.setInferredType(b.getInferredType());
|
||||||
|
return implode(biome, x, z, max - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,6 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk c) {
|
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk c) {
|
||||||
getWorldManager().spawnInitialEntities(c);
|
|
||||||
updateChunk(c);
|
updateChunk(c);
|
||||||
placeTiles(c);
|
placeTiles(c);
|
||||||
}
|
}
|
||||||
|
@ -19,28 +19,129 @@
|
|||||||
package com.volmit.iris.engine;
|
package com.volmit.iris.engine;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.engine.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.framework.EngineAssignedWorldManager;
|
import com.volmit.iris.engine.framework.EngineAssignedWorldManager;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class IrisWorldManager extends EngineAssignedWorldManager {
|
public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||||
private boolean spawnable;
|
private boolean spawnable;
|
||||||
|
private final int art;
|
||||||
|
private final KMap<UUID, Long> spawnCooldowns;
|
||||||
|
|
||||||
public IrisWorldManager(Engine engine) {
|
public IrisWorldManager(Engine engine) {
|
||||||
super(engine);
|
super(engine);
|
||||||
|
spawnCooldowns = new KMap<>();
|
||||||
spawnable = true;
|
spawnable = true;
|
||||||
|
art = J.ar(this::onAsyncTick, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAsyncTick() {
|
||||||
|
int biomeBaseCooldownMinutes = 2;
|
||||||
|
int biomeSpawnedCooldownMinutes = 3;
|
||||||
|
int biomeNotSpawnedCooldownMinutes = 5;
|
||||||
|
|
||||||
|
for(UUID i : spawnCooldowns.k())
|
||||||
|
{
|
||||||
|
if(M.ms() - spawnCooldowns.get(i) > TimeUnit.MINUTES.toMillis(biomeBaseCooldownMinutes))
|
||||||
|
{
|
||||||
|
spawnCooldowns.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KMap<UUID, KList<Chunk>> data = new KMap<>();
|
||||||
|
int spawnBuffer = 8;
|
||||||
|
|
||||||
|
for(UUID i : data.k().shuffleCopy(RNG.r))
|
||||||
|
{
|
||||||
|
if(spawnCooldowns.containsKey(i))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(spawnBuffer-- < 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnCooldowns.put(i, spawnIn(data.get(i).getRandom(), i) ?
|
||||||
|
(M.ms() + TimeUnit.MINUTES.toMillis(biomeSpawnedCooldownMinutes)) :
|
||||||
|
(M.ms() + TimeUnit.MINUTES.toMillis(biomeNotSpawnedCooldownMinutes)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean spawnIn(Chunk c, UUID id) {
|
||||||
|
if(c.getEntities().length > 16)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new KList<Supplier<Boolean>>(() -> {
|
||||||
|
IrisBiome biome = getEngine().getSurfaceBiome(c.getX() << 4, c.getZ() << 4);
|
||||||
|
|
||||||
|
for(IrisSpawner i : getData().getSpawnerLoader().loadAll(biome.getEntitySpawners()).shuffleCopy(RNG.r))
|
||||||
|
{
|
||||||
|
if(i.spawnInChunk(getEngine(), c))
|
||||||
|
{
|
||||||
|
Iris.debug("Spawning Biome Entities in Chunk " + c.getX() + "," + c.getZ() + " Biome ID: " + id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}, () -> {
|
||||||
|
IrisRegion region = getEngine().getRegion(c.getX() << 4, c.getZ() << 4);
|
||||||
|
|
||||||
|
for(IrisSpawner i : getData().getSpawnerLoader().loadAll(region.getEntitySpawners()).shuffleCopy(RNG.r))
|
||||||
|
{
|
||||||
|
if(i.spawnInChunk(getEngine(), c))
|
||||||
|
{
|
||||||
|
Iris.debug("Spawning Region Entities in Chunk " + c.getX() + "," + c.getZ() + " Biome ID: " + id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}, () -> {
|
||||||
|
for(IrisSpawner i : getData().getSpawnerLoader().loadAll(getDimension().getEntitySpawners()).shuffleCopy(RNG.r))
|
||||||
|
{
|
||||||
|
if(i.spawnInChunk(getEngine(), c))
|
||||||
|
{
|
||||||
|
Iris.debug("Spawning Dimension Entities in Chunk " + c.getX() + "," + c.getZ() + " Biome ID: " + id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}).getRandom().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KMap<UUID, KList<Chunk>> mapChunkBiomes()
|
||||||
|
{
|
||||||
|
KMap<UUID, KList<Chunk>> data = new KMap<>();
|
||||||
|
|
||||||
|
for(Chunk i : getEngine().getWorld().realWorld().getLoadedChunks())
|
||||||
|
{
|
||||||
|
data.compute(getEngine().getBiomeID(i.getX() << 4, i.getZ() << 4),
|
||||||
|
(k,v) -> v != null ? v : new KList<>()).add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -53,87 +154,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
getEngine().getParallax().saveAll();
|
getEngine().getParallax().saveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public void spawnInitialEntities(Chunk c) {
|
|
||||||
RNG rng = new RNG(Cache.key(c));
|
|
||||||
|
|
||||||
getEngine().getParallaxAccess().getEntitiesR(c.getX(), c.getZ()).iterateSync((x, y, z, e) -> {
|
|
||||||
if (e != null) {
|
|
||||||
IrisEntity en = getData().getEntityLoader().load(e);
|
|
||||||
|
|
||||||
if (en != null) {
|
|
||||||
en.spawn(getEngine(), new Location(c.getWorld(), x + (c.getX() << 4), y, z + (c.getZ() << 4)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
int x = (c.getX() * 16) + rng.nextInt(15);
|
|
||||||
int z = (c.getZ() * 16) + rng.nextInt(15);
|
|
||||||
int y = getEngine().getHeight(x, z) + 1;
|
|
||||||
IrisDimension dim = getDimension();
|
|
||||||
IrisRegion region = getEngine().getRegion(x, z);
|
|
||||||
IrisBiome above = getEngine().getSurfaceBiome(x, z);
|
|
||||||
trySpawn(above.getEntityInitialSpawns(), c, rng);
|
|
||||||
trySpawn(region.getEntityInitialSpawns(), c, rng);
|
|
||||||
trySpawn(dim.getEntityInitialSpawns(), c, rng);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEntitySpawn(EntitySpawnEvent e) {
|
|
||||||
if (getTarget().getWorld() == null || !e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!IrisSettings.get().getGenerator().isSystemEntitySpawnOverrides()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = e.getEntity().getLocation().getBlockX();
|
|
||||||
int y = e.getEntity().getLocation().getBlockY();
|
|
||||||
int z = e.getEntity().getLocation().getBlockZ();
|
|
||||||
|
|
||||||
J.a(() ->
|
|
||||||
{
|
|
||||||
if (spawnable) {
|
|
||||||
IrisDimension dim = getDimension();
|
|
||||||
IrisRegion region = getEngine().getRegion(x, z);
|
|
||||||
IrisBiome above = getEngine().getSurfaceBiome(x, z);
|
|
||||||
IrisBiome bbelow = getEngine().getBiome(x, y, z);
|
|
||||||
if (above.getLoadKey().equals(bbelow.getLoadKey())) {
|
|
||||||
bbelow = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisBiome below = bbelow;
|
|
||||||
|
|
||||||
J.s(() ->
|
|
||||||
{
|
|
||||||
if (below != null) {
|
|
||||||
if (trySpawn(below.getEntitySpawnOverrides(), e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trySpawn(above.getEntitySpawnOverrides(), e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trySpawn(region.getEntitySpawnOverrides(), e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trySpawn(dim.getEntitySpawnOverrides(), e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Throwable ee) {
|
|
||||||
Iris.reportError(ee);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean trySpawn(KList<IrisEntitySpawnOverride> s, EntitySpawnEvent e) {
|
private boolean trySpawn(KList<IrisEntitySpawnOverride> s, EntitySpawnEvent e) {
|
||||||
for (IrisEntitySpawnOverride i : s) {
|
for (IrisEntitySpawnOverride i : s) {
|
||||||
spawnable = false;
|
spawnable = false;
|
||||||
@ -151,8 +171,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
private void trySpawn(KList<IrisEntityInitialSpawn> s, Chunk c, RNG rng) {
|
private void trySpawn(KList<IrisEntitySpawn> s, Chunk c, RNG rng) {
|
||||||
for (IrisEntityInitialSpawn i : s) {
|
for (IrisEntitySpawn i : s) {
|
||||||
i.spawn(getEngine(), c, rng);
|
i.spawn(getEngine(), c, rng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,4 +250,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
public void onBlockPlace(BlockPlaceEvent e) {
|
public void onBlockPlace(BlockPlaceEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
super.close();
|
||||||
|
J.car(art);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable {
|
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable {
|
||||||
void close();
|
void close();
|
||||||
@ -65,6 +66,11 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
|
|
||||||
void setParallelism(int parallelism);
|
void setParallelism(int parallelism);
|
||||||
|
|
||||||
|
default UUID getBiomeID(int x, int z)
|
||||||
|
{
|
||||||
|
return getFramework().getComplex().getBaseBiomeIDStream().get(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
int getParallelism();
|
int getParallelism();
|
||||||
|
|
||||||
EngineTarget getTarget();
|
EngineTarget getTarget();
|
||||||
|
@ -51,13 +51,6 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void on(EntitySpawnEvent e) {
|
|
||||||
if (e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) {
|
|
||||||
onEntitySpawn(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void on(BlockBreakEvent e) {
|
public void on(BlockBreakEvent e) {
|
||||||
if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) {
|
if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) {
|
||||||
|
@ -18,23 +18,17 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.framework;
|
package com.volmit.iris.engine.framework;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
|
||||||
|
|
||||||
@SuppressWarnings("EmptyMethod")
|
@SuppressWarnings("EmptyMethod")
|
||||||
public interface EngineWorldManager {
|
public interface EngineWorldManager {
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void onEntitySpawn(EntitySpawnEvent e);
|
|
||||||
|
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
void onSave();
|
void onSave();
|
||||||
|
|
||||||
void spawnInitialEntities(Chunk chunk);
|
|
||||||
|
|
||||||
void onBlockBreak(BlockBreakEvent e);
|
void onBlockBreak(BlockBreakEvent e);
|
||||||
|
|
||||||
void onBlockPlace(BlockPlaceEvent e);
|
void onBlockPlace(BlockPlaceEvent e);
|
||||||
|
@ -26,6 +26,8 @@ import com.volmit.iris.engine.object.IrisObjectPlacement;
|
|||||||
import com.volmit.iris.engine.object.IrisRegion;
|
import com.volmit.iris.engine.object.IrisRegion;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface GeneratorAccess extends DataProvider, Renderer {
|
public interface GeneratorAccess extends DataProvider, Renderer {
|
||||||
IrisRegion getRegion(int x, int z);
|
IrisRegion getRegion(int x, int z);
|
||||||
|
|
||||||
|
@ -64,17 +64,15 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
@Desc("If the biome type custom is defined, specify this")
|
@Desc("If the biome type custom is defined, specify this")
|
||||||
private KList<IrisBiomeCustom> customDerivitives;
|
private KList<IrisBiomeCustom> customDerivitives;
|
||||||
|
|
||||||
@Desc("Entity spawns to override or add to this biome. Anytime an entity spawns, it has a chance to be replaced as one of these overrides.")
|
@Desc("Spawn Entities in this area over time. Iris will continually replenish these mobs just like vanilla does.")
|
||||||
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
|
@ArrayType(min = 1, type = String.class)
|
||||||
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
|
@RegistryListSpawner
|
||||||
|
private KList<String> entitySpawners = new KList<>();
|
||||||
|
|
||||||
@Desc("Add random chances for terrain features")
|
@Desc("Add random chances for terrain features")
|
||||||
@ArrayType(min = 1, type = IrisFeaturePotential.class)
|
@ArrayType(min = 1, type = IrisFeaturePotential.class)
|
||||||
private KList<IrisFeaturePotential> features = new KList<>();
|
private KList<IrisFeaturePotential> features = new KList<>();
|
||||||
|
|
||||||
@Desc("Entity spawns during generation")
|
|
||||||
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
|
|
||||||
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
|
|
||||||
|
|
||||||
@ArrayType(min = 1, type = IrisEffect.class)
|
@ArrayType(min = 1, type = IrisEffect.class)
|
||||||
@Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play around the player even if where the effect was played is no longer in the biome the player is in.")
|
@Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play around the player even if where the effect was played is no longer in the biome the player is in.")
|
||||||
|
@ -80,18 +80,15 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
@Desc("Upon joining this world, Iris will send a resource pack request to the client. If they have previously selected yes, it will auto-switch depending on which dimension they go to.")
|
@Desc("Upon joining this world, Iris will send a resource pack request to the client. If they have previously selected yes, it will auto-switch depending on which dimension they go to.")
|
||||||
private String resourcePack = "";
|
private String resourcePack = "";
|
||||||
|
|
||||||
@Desc("Entity spawns to override or add to this dimension")
|
@Desc("Spawn Entities in this dimension over time. Iris will continually replenish these mobs just like vanilla does.")
|
||||||
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
|
@ArrayType(min = 1, type = String.class)
|
||||||
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
|
@RegistryListSpawner
|
||||||
|
private KList<String> entitySpawners = new KList<>();
|
||||||
|
|
||||||
@Desc("Add specific features in exact positions")
|
@Desc("Add specific features in exact positions")
|
||||||
@ArrayType(min = 1, type = IrisFeaturePositional.class)
|
@ArrayType(min = 1, type = IrisFeaturePositional.class)
|
||||||
private KList<IrisFeaturePositional> specificFeatures = new KList<>();
|
private KList<IrisFeaturePositional> specificFeatures = new KList<>();
|
||||||
|
|
||||||
@Desc("Entity spawns during generation")
|
|
||||||
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
|
|
||||||
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
|
|
||||||
|
|
||||||
@Desc("Add random chances for terrain features")
|
@Desc("Add random chances for terrain features")
|
||||||
@ArrayType(min = 1, type = IrisFeaturePotential.class)
|
@ArrayType(min = 1, type = IrisFeaturePotential.class)
|
||||||
private KList<IrisFeaturePotential> features = new KList<>();
|
private KList<IrisFeaturePotential> features = new KList<>();
|
||||||
|
@ -39,7 +39,7 @@ import org.bukkit.entity.Entity;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Desc("Represents an entity spawn during initial chunk generation")
|
@Desc("Represents an entity spawn during initial chunk generation")
|
||||||
@Data
|
@Data
|
||||||
public class IrisEntityInitialSpawn {
|
public class IrisEntitySpawn {
|
||||||
@RegistryListEntity
|
@RegistryListEntity
|
||||||
@Required
|
@Required
|
||||||
@Desc("The entity")
|
@Desc("The entity")
|
||||||
@ -60,7 +60,7 @@ public class IrisEntityInitialSpawn {
|
|||||||
private final transient AtomicCache<RNG> rng = new AtomicCache<>();
|
private final transient AtomicCache<RNG> rng = new AtomicCache<>();
|
||||||
private final transient AtomicCache<IrisEntity> ent = new AtomicCache<>();
|
private final transient AtomicCache<IrisEntity> ent = new AtomicCache<>();
|
||||||
|
|
||||||
public void spawn(Engine gen, Chunk c, RNG rng) {
|
public boolean spawn(Engine gen, Chunk c, RNG rng) {
|
||||||
int spawns = rng.i(1, rarity) == 1 ? rng.i(minSpawns, maxSpawns) : 0;
|
int spawns = rng.i(1, rarity) == 1 ? rng.i(minSpawns, maxSpawns) : 0;
|
||||||
|
|
||||||
if (spawns > 0) {
|
if (spawns > 0) {
|
||||||
@ -70,7 +70,11 @@ public class IrisEntityInitialSpawn {
|
|||||||
int h = gen.getHeight(x, z) + gen.getMinHeight();
|
int h = gen.getHeight(x, z) + gen.getMinHeight();
|
||||||
spawn100(gen, new Location(c.getWorld(), x, h, z));
|
spawn100(gen, new Location(c.getWorld(), x, h, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IrisEntity getRealEntity(Engine g) {
|
public IrisEntity getRealEntity(Engine g) {
|
||||||
@ -91,10 +95,12 @@ public class IrisEntityInitialSpawn {
|
|||||||
|
|
||||||
private Entity spawn100(Engine g, Location at) {
|
private Entity spawn100(Engine g, Location at) {
|
||||||
try {
|
try {
|
||||||
return getRealEntity(g).spawn(g, at.clone().add(0.5, 1, 0.5), rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)));
|
Location l = at.clone().add(0.5, 1, 0.5);
|
||||||
|
Iris.debug(" Spawned " + "Entity<" + getEntity() + "> at " + l.getBlockX() + "," + l.getBlockY() + "," + l.getBlockZ());
|
||||||
|
return getRealEntity(g).spawn(g, l, rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
Iris.debug("Failed to retrieve real entity @ " + at);
|
Iris.error("Failed to retrieve real entity @ " + at);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -67,13 +67,10 @@ public class IrisRegion extends IrisRegistrant implements IRare {
|
|||||||
@Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.")
|
@Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.")
|
||||||
private KList<IrisEffect> effects = new KList<>();
|
private KList<IrisEffect> effects = new KList<>();
|
||||||
|
|
||||||
@Desc("Entity spawns to override or add to this region")
|
@Desc("Spawn Entities in this region over time. Iris will continually replenish these mobs just like vanilla does.")
|
||||||
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
|
@ArrayType(min = 1, type = String.class)
|
||||||
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
|
@RegistryListSpawner
|
||||||
|
private KList<String> entitySpawners = new KList<>();
|
||||||
@Desc("Entity spawns during generation")
|
|
||||||
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
|
|
||||||
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
|
|
||||||
|
|
||||||
@MinNumber(1)
|
@MinNumber(1)
|
||||||
@MaxNumber(128)
|
@MaxNumber(128)
|
||||||
|
51
src/main/java/com/volmit/iris/engine/object/IrisSpawner.java
Normal file
51
src/main/java/com/volmit/iris/engine/object/IrisSpawner.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.engine.object;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Desc("Represents an entity spawn during initial chunk generation")
|
||||||
|
@Data
|
||||||
|
public class IrisSpawner extends IrisRegistrant {
|
||||||
|
@ArrayType(min = 1, type = IrisEntitySpawn.class)
|
||||||
|
@Desc("The entity spawns to add")
|
||||||
|
private KList<IrisEntitySpawn> spawns = new KList<>();
|
||||||
|
|
||||||
|
public boolean spawnInChunk(Engine engine, Chunk c) {
|
||||||
|
if(spawns.isEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return spawns.getRandom().spawn(engine, c, RNG.r);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.engine.object.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.*;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Target({PARAMETER, TYPE, FIELD})
|
||||||
|
public @interface RegistryListSpawner {
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user