Cleanup EntityFeature code, account for Structure rotation in Features

This commit is contained in:
dfsek 2020-11-17 00:49:43 -07:00
parent 2750d46a98
commit 4c4c31db45
3 changed files with 44 additions and 70 deletions

View File

@ -69,7 +69,7 @@ public class StructurePopulator extends BlockPopulator {
Debug.stack(e); Debug.stack(e);
} }
} }
for(Feature f : conf.getFeatures()) f.apply(struc, spawn, chunk); // Apply features. for(Feature f : conf.getFeatures()) f.apply(struc, rotation, spawn, chunk); // Apply features.
break; break;
} }
} }

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.structure.features; package com.dfsek.terra.structure.features;
import com.dfsek.terra.Debug; import com.dfsek.terra.Debug;
import com.dfsek.terra.structure.Rotation;
import com.dfsek.terra.structure.Structure; import com.dfsek.terra.structure.Structure;
import com.dfsek.terra.structure.StructureInfo; import com.dfsek.terra.structure.StructureInfo;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -12,6 +13,8 @@ import org.bukkit.entity.EntityType;
import org.polydev.gaea.math.MathUtil; import org.polydev.gaea.math.MathUtil;
import org.polydev.gaea.math.Range; import org.polydev.gaea.math.Range;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -37,31 +40,35 @@ public class EntityFeature implements Feature {
return Math.floorDiv(l.getBlockX(), 16) == c.getX() && Math.floorDiv(l.getBlockZ(), 16) == c.getZ(); return Math.floorDiv(l.getBlockX(), 16) == c.getX() && Math.floorDiv(l.getBlockZ(), 16) == c.getZ();
} }
private static List<Location> getLocations(Structure structure, Rotation r, Location origin, Random random, int number) {
StructureInfo info = structure.getStructureInfo();
Range x = structure.getRange(Rotation.Axis.X, r);
Range y = structure.getRange(Rotation.Axis.Y, r);
Range z = structure.getRange(Rotation.Axis.Z, r);
int cx = info.getCenterX();
int cz = info.getCenterZ();
List<Location> locations = new ArrayList<>();
for(int i = 0; i < number; i++)
locations.add(origin.clone().add(x.get(random) - cx, y.get(random), z.get(random) - cz));
return locations;
}
@Override @Override
public void apply(Structure structure, Location l, Chunk chunk) { public void apply(Structure structure, Rotation r, Location l, Chunk chunk) {
Random random = new Random(MathUtil.getCarverChunkSeed(chunk.getX(), chunk.getZ(), chunk.getWorld().getSeed())); Random random = new Random(MathUtil.getCarverChunkSeed(chunk.getX(), chunk.getZ(), chunk.getWorld().getSeed()));
for(Location attempt : getLocations(structure, r, l, random, amount.get(random))) {
int amountSpawn = amount.get(random);
StructureInfo info = structure.getStructureInfo();
Range x = new Range(0, info.getSizeZ());
Range y = new Range(0, info.getSizeY());
Range z = new Range(0, info.getSizeZ());
int cx = info.getCenterX();
int cz = info.getCenterZ();
for(int i = 0; i < amountSpawn && i < attempts; i++) {
int yv = y.get(random);
Location attempt = l.clone().add(x.get(random) - cx, yv, z.get(random) - cz);
if(!isInChunk(chunk, attempt)) continue; // Don't attempt spawn if not in current chunk. if(!isInChunk(chunk, attempt)) continue; // Don't attempt spawn if not in current chunk.
attemptSpawn(attempt, l);
}
}
private void attemptSpawn(Location attempt, Location origin) {
boolean canSpawn = false; boolean canSpawn = false;
while(yv >= 0 && attempt.getBlockY() >= l.getBlockY()) { // Go down, see if valid spawns exist. while(attempt.getBlockY() >= origin.getBlockY()) { // Go down, see if valid spawns exist.
canSpawn = true; canSpawn = true;
Block on = attempt.getBlock(); Block on = attempt.getBlock();
attempt.subtract(0, 1, 0); attempt.subtract(0, 1, 0);
yv--;
if(!stand.contains(on.getType())) { if(!stand.contains(on.getType())) {
canSpawn = false; canSpawn = false;
@ -75,48 +82,14 @@ public class EntityFeature implements Feature {
} }
if(canSpawn) { if(canSpawn) {
Debug.info("Spawning entity at " + attempt); Debug.info("Spawning entity at " + attempt);
chunk.getWorld().spawnEntity(attempt.add(0.5, 2, 0.5), type); // Add 0.5 to X & Z so entity spawns in center of block. Objects.requireNonNull(attempt.getWorld()).spawnEntity(attempt.add(0.5, 2, 0.5), type); // Add 0.5 to X & Z so entity spawns in center of block.
}
} }
} }
@Override @Override
public void apply(Structure structure, Location l, Random random) { public void apply(Structure structure, Rotation r, Location l, Random random) {
int amountSpawn = amount.get(random); for(Location attempt : getLocations(structure, r, l, random, amount.get(random))) {
attemptSpawn(attempt, l);
StructureInfo info = structure.getStructureInfo();
Range x = new Range(0, info.getSizeZ());
Range y = new Range(0, info.getSizeY());
Range z = new Range(0, info.getSizeZ());
int cx = info.getCenterX();
int cz = info.getCenterZ();
for(int i = 0; i < amountSpawn && i < attempts; i++) {
int yv = y.get(random);
Location attempt = l.clone().add(x.get(random) - cx, yv, z.get(random) - cz);
boolean canSpawn = false;
while(yv >= 0 && attempt.getBlockY() >= l.getBlockY()) { // Go down, see if valid spawns exist.
canSpawn = true;
Block on = attempt.getBlock();
attempt.subtract(0, 1, 0);
yv--;
if(!stand.contains(on.getType())) {
canSpawn = false;
continue;
}
for(int j = 1; j < inSize + 1; j++)
if(!in.contains(on.getRelative(BlockFace.UP, j).getType())) canSpawn = false;
if(canSpawn) break;
}
if(canSpawn) {
Debug.info("Spawning entity at " + attempt);
Objects.requireNonNull(l.getWorld()).spawnEntity(attempt.add(0.5, 1, 0.5), type); // Add 0.5 to X & Z so entity spawns in center of block.
}
} }
} }
} }

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.structure.features; package com.dfsek.terra.structure.features;
import com.dfsek.terra.structure.Rotation;
import com.dfsek.terra.structure.Structure; import com.dfsek.terra.structure.Structure;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
@ -7,7 +8,7 @@ import org.bukkit.Location;
import java.util.Random; import java.util.Random;
public interface Feature { public interface Feature {
void apply(Structure structure, Location l, Chunk chunk); void apply(Structure structure, Rotation r, Location l, Chunk chunk);
void apply(Structure structure, Location l, Random random); void apply(Structure structure, Rotation r, Location l, Random random);
} }