Spawners in objects closes

This commit is contained in:
Daniel Mills
2021-08-03 01:37:03 -04:00
parent 6e22d6687c
commit 51a056b3d7
22 changed files with 460 additions and 77 deletions

View File

@@ -38,10 +38,8 @@ public enum InferredType {
RIVER,
@Desc("Represents any lake biome type")
LAKE,
@Desc("Defers the type to whatever another biome type that already exists is.")
DEFER
}

View File

@@ -19,13 +19,20 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineFramework;
import com.volmit.iris.engine.modifier.IrisCaveModifier;
import com.volmit.iris.engine.modifier.IrisPostModifier;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.engine.object.common.IRare;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.RNG;
import lombok.AllArgsConstructor;
@@ -34,7 +41,14 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Slab;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
@Accessors(chain = true)
@NoArgsConstructor
@@ -65,19 +79,47 @@ public class IrisEntitySpawn implements IRare {
public boolean spawn(Engine gen, Chunk c, RNG rng) {
int spawns = minSpawns == maxSpawns ? minSpawns : rng.i(Math.min(minSpawns, maxSpawns), Math.max(minSpawns, maxSpawns));
int s = 0;
if (spawns > 0) {
for (int i = 0; i < spawns; i++) {
for (int id = 0; id < spawns; id++) {
int x = (c.getX() * 16) + rng.i(15);
int z = (c.getZ() * 16) + rng.i(15);
int h = c.getWorld().getHighestBlockYAt(x, z);
spawn100(gen, new Location(c.getWorld(), x, h, z));
}
int h = gen.getHeight(x, z, true);
int hf = gen.getHeight(x, z, false);
Location l = switch(getReferenceSpawner().getGroup())
{
case NORMAL -> new Location(c.getWorld(), x, hf+1, z);
case CAVE -> {
IrisComplex comp = gen.getFramework().getComplex();
EngineFramework frame = gen.getFramework();
IrisBiome cave = comp.getCaveBiomeStream().get(x, z);
KList<Location> r = new KList<>();
if (cave != null) {
for (CaveResult i : ((IrisCaveModifier) frame.getCaveModifier()).genCaves(x, z)) {
if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling()-2 <= i.getFloor()) {
continue;
}
return true;
r.add(new Location(c.getWorld(), x, i.getFloor(), z));
}
}
yield r.getRandom(rng);
}
case UNDERWATER, BEACH -> new Location(c.getWorld(), x, rng.i(h+1, hf), z);
};
if(l != null)
{
spawn100(gen, l);
s++;
}
}
}
return false;
return s>0;
}
public IrisEntity getRealEntity(Engine g) {

View File

@@ -98,8 +98,8 @@ public class IrisExpression extends IrisRegistrant {
}
g[m++] = x;
g[m++] = -1;
g[m] = z;
g[m++] = z;
g[m] = -1;
return expression().evaluate(g);
}

View File

@@ -23,6 +23,7 @@ import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.interpolation.InterpolationMethod;
import com.volmit.iris.engine.interpolation.IrisInterpolation;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -81,6 +82,11 @@ public class IrisFeature {
@Desc("Fracture the radius ring with additional noise")
private IrisGeneratorStyle fractureRadius = null;
@RegistryListResource(IrisSpawner.class)
@ArrayType(min = 1, type = String.class)
@Desc("Within this noise feature, use the following spawners")
private KList<String> entitySpawners = new KList<>();
private transient AtomicCache<Double> actualRadius = new AtomicCache<>();
public double getActualRadius() {

View File

@@ -210,10 +210,15 @@ public class IrisGenerator extends IrisRegistrant {
}
public double getHeight(double rx, double rz, long superSeed) {
return getHeight(rx, 0, rz, superSeed);
return getHeight(rx, 0, rz, superSeed, true);
}
public double getHeight(double rx, double ry, double rz, long superSeed) {
return getHeight(rx, ry, rz, superSeed, false);
}
public double getHeight(double rx, double ry, double rz, long superSeed, boolean no3d) {
if (composite.isEmpty()) {
Iris.warn("Useless Generator: Composite is empty in " + getLoadKey());
return 0;
@@ -235,7 +240,7 @@ public class IrisGenerator extends IrisRegistrant {
double v = multiplicitive ? h * opacity : (h / tp) * opacity;
if (Double.isNaN(v)) {
Iris.warn("Nan value on gen: " + getLoadKey() + ": H = " + h + " TP = " + tp + " OPACITY = " + opacity + " ZOOM = " + zoom);
v = 0;
}
v = hasCliffs() ? cliff(rx, rz, v, superSeed + 294596 + hc) : v;

View File

@@ -58,6 +58,10 @@ public class IrisObjectPlacement {
@Desc("Limit the max height or min height of placement.")
private IrisObjectLimit clamp = new IrisObjectLimit();
@ArrayType(min = 1, type = IrisFeaturePotential.class)
@Desc("Place additional noise features in the object's place location")
private KList<IrisFeaturePotential> addFeatures = new KList<>();
@MinNumber(0)
@MaxNumber(1)
@Desc("The maximum layer level of a snow filter overtop of this placement. Set to 0 to disable. Max of 1.")
@@ -161,6 +165,7 @@ public class IrisObjectPlacement {
p.setWarp(warp);
p.setBore(bore);
p.setMeld(meld);
p.setAddFeatures(addFeatures.copy());
p.setWaterloggable(waterloggable);
p.setOnwater(onwater);
p.setSmartBore(smartBore);
@@ -213,6 +218,11 @@ public class IrisObjectPlacement {
return getMode().equals(ObjectPlaceMode.VACUUM);
}
public boolean usesFeatures()
{
return isVacuum() || getAddFeatures().isNotEmpty();
}
private transient AtomicCache<TableCache> cache = new AtomicCache<>();
public boolean matches(IrisTreeSize size, TreeType type) {

View File

@@ -0,0 +1,36 @@
/*
* 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.object.annotations.Desc;
@Desc("Terrain modes are used to decide the generator type currently used")
public enum IrisSpawnGroup {
@Desc("Spawns on the terrain surface")
NORMAL,
@Desc("Spawns in cave-air and low light level areas")
CAVE,
@Desc("Spawns underwater")
UNDERWATER,
@Desc("Spawns in beaches")
BEACH
}

View File

@@ -26,6 +26,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Location;
import org.bukkit.World;
@EqualsAndHashCode(callSuper = true)
@@ -48,6 +49,29 @@ public class IrisSpawner extends IrisRegistrant {
@Desc("The maximum rate this spawner can fire")
private IrisRate maximumRate = new IrisRate();
@Desc("Where should these spawns be placed")
private IrisSpawnGroup group = IrisSpawnGroup.NORMAL;
public boolean isValid(IrisBiome biome)
{
return switch (group)
{
case NORMAL -> switch(biome.getInferredType()) {
case SHORE, SEA, CAVE, RIVER, LAKE, DEFER -> false;
case LAND -> true;
};
case CAVE -> true;
case UNDERWATER -> switch(biome.getInferredType()) {
case SHORE, LAND, CAVE, RIVER, LAKE, DEFER -> false;
case SEA -> true;
};
case BEACH -> switch(biome.getInferredType()) {
case SHORE -> true;
case LAND, CAVE, RIVER, LAKE, SEA, DEFER -> false;
};
};
}
public boolean isValid(World world) {
return timeBlock.isWithin(world) && weather.is(world);
}