Serpulo naval wave support
This commit is contained in:
@@ -265,10 +265,16 @@ public class Waves{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Seq<SpawnGroup> generate(float difficulty, Rand rand, boolean attack, boolean airOnly){
|
public static Seq<SpawnGroup> generate(float difficulty, Rand rand, boolean attack, boolean airOnly){
|
||||||
|
return generate(difficulty, rand, attack, airOnly, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Seq<SpawnGroup> generate(float difficulty, Rand rand, boolean attack, boolean airOnly, boolean naval){
|
||||||
UnitType[][] species = {
|
UnitType[][] species = {
|
||||||
{dagger, mace, fortress, scepter, reign},
|
{dagger, mace, fortress, scepter, reign},
|
||||||
{nova, pulsar, quasar, vela, corvus},
|
{nova, pulsar, quasar, vela, corvus},
|
||||||
{crawler, atrax, spiroct, arkyid, toxopid},
|
{crawler, atrax, spiroct, arkyid, toxopid},
|
||||||
|
{risso, minke, bryde, sei, omura},
|
||||||
|
{risso, oxynoe, cyerce, aegires, navanax}, //retusa intentionally left out as it cannot damage the core properly
|
||||||
{flare, horizon, zenith, rand.chance(0.5) ? quad : antumbra, rand.chance(0.1) ? quad : eclipse}
|
{flare, horizon, zenith, rand.chance(0.5) ? quad : antumbra, rand.chance(0.1) ? quad : eclipse}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -276,6 +282,12 @@ public class Waves{
|
|||||||
species = Structs.filter(UnitType[].class, species, v -> v[0].flying);
|
species = Structs.filter(UnitType[].class, species, v -> v[0].flying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(naval){
|
||||||
|
species = Structs.filter(UnitType[].class, species, v -> v[0].flying || v[0].naval);
|
||||||
|
}else{
|
||||||
|
species = Structs.filter(UnitType[].class, species, v -> v[0].flying && !v[0].naval);
|
||||||
|
}
|
||||||
|
|
||||||
UnitType[][] fspec = species;
|
UnitType[][] fspec = species;
|
||||||
|
|
||||||
//required progression:
|
//required progression:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import mindustry.graphics.g3d.PlanetGrid.*;
|
|||||||
import mindustry.maps.generators.*;
|
import mindustry.maps.generators.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.environment.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -165,14 +166,14 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
connected.add(this);
|
connected.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void con(int x1, int y1, int x2, int y2){
|
void join(int x1, int y1, int x2, int y2){
|
||||||
float nscl = rand.random(100f, 140f) * 6f;
|
float nscl = rand.random(100f, 140f) * 6f;
|
||||||
int stroke = rand.random(3, 9);
|
int stroke = rand.random(3, 9);
|
||||||
brush(pathfind(x1, y1, x2, y2, tile -> (tile.solid() ? 50f : 0f) + noise(tile.x, tile.y, 2, 0.4f, 1f / nscl) * 500, Astar.manhattan), stroke);
|
brush(pathfind(x1, y1, x2, y2, tile -> (tile.solid() ? 50f : 0f) + noise(tile.x, tile.y, 2, 0.4f, 1f / nscl) * 500, Astar.manhattan), stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(Room to){
|
void connect(Room to){
|
||||||
if(!connected.add(to)) return;
|
if(!connected.add(to) || to == this) return;
|
||||||
|
|
||||||
Vec2 midpoint = Tmp.v1.set(to.x, to.y).add(x, y).scl(0.5f);
|
Vec2 midpoint = Tmp.v1.set(to.x, to.y).add(x, y).scl(0.5f);
|
||||||
rand.nextFloat();
|
rand.nextFloat();
|
||||||
@@ -188,8 +189,52 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
|
|
||||||
int mx = (int)midpoint.x, my = (int)midpoint.y;
|
int mx = (int)midpoint.x, my = (int)midpoint.y;
|
||||||
|
|
||||||
con(x, y, mx, my);
|
join(x, y, mx, my);
|
||||||
con(mx, my, to.x, to.y);
|
join(mx, my, to.x, to.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void joinLiquid(int x1, int y1, int x2, int y2){
|
||||||
|
float nscl = rand.random(100f, 140f) * 6f;
|
||||||
|
int rad = rand.random(5, 10);
|
||||||
|
int avoid = 2 + rad;
|
||||||
|
var path = pathfind(x1, y1, x2, y2, tile -> (tile.solid() || !tile.floor().isLiquid ? 70f : 0f) + noise(tile.x, tile.y, 2, 0.4f, 1f / nscl) * 500, Astar.manhattan);
|
||||||
|
path.each(t -> {
|
||||||
|
//don't place liquid paths near the core
|
||||||
|
if(Mathf.dst2(t.x, t.y, x2, y2) <= avoid * avoid){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = -rad; x <= rad; x++){
|
||||||
|
for(int y = -rad; y <= rad; y++){
|
||||||
|
int wx = t.x + x, wy = t.y + y;
|
||||||
|
if(Structs.inBounds(wx, wy, width, height) && Mathf.within(x, y, rad)){
|
||||||
|
Tile other = tiles.getn(wx, wy);
|
||||||
|
other.setBlock(Blocks.air);
|
||||||
|
if(Mathf.within(x, y, rad - 1) && !other.floor().isLiquid){
|
||||||
|
Floor floor = other.floor();
|
||||||
|
//TODO does not respect tainted floors
|
||||||
|
other.setFloor((Floor)(floor == Blocks.sand || floor == Blocks.salt ? Blocks.sandWater : Blocks.darksandTaintedWater));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void connectLiquid(Room to){
|
||||||
|
if(to == this) return;
|
||||||
|
|
||||||
|
Vec2 midpoint = Tmp.v1.set(to.x, to.y).add(x, y).scl(0.5f);
|
||||||
|
rand.nextFloat();
|
||||||
|
|
||||||
|
//add randomized offset to avoid straight lines
|
||||||
|
midpoint.add(Tmp.v2.setToRandomDirection(rand).scl(Tmp.v1.dst(x, y)));
|
||||||
|
midpoint.sub(width/2f, height/2f).limit(width / 2f / Mathf.sqrt3).add(width/2f, height/2f);
|
||||||
|
|
||||||
|
int mx = (int)midpoint.x, my = (int)midpoint.y;
|
||||||
|
|
||||||
|
joinLiquid(x, y, mx, my);
|
||||||
|
joinLiquid(mx, my, to.x, to.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,10 +295,12 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//clear radius around each room
|
||||||
for(Room room : roomseq){
|
for(Room room : roomseq){
|
||||||
erase(room.x, room.y, room.radius);
|
erase(room.x, room.y, room.radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//randomly connect rooms together
|
||||||
int connections = rand.random(Math.max(rooms - 1, 1), rooms + 3);
|
int connections = rand.random(Math.max(rooms - 1, 1), rooms + 3);
|
||||||
for(int i = 0; i < connections; i++){
|
for(int i = 0; i < connections; i++){
|
||||||
roomseq.random(rand).connect(roomseq.random(rand));
|
roomseq.random(rand).connect(roomseq.random(rand));
|
||||||
@@ -267,30 +314,29 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
|
|
||||||
cells(1);
|
cells(1);
|
||||||
|
|
||||||
//shoreline setup
|
int tlen = tiles.width * tiles.height;
|
||||||
int deepRadius = 4;
|
int total = 0, waters = 0;
|
||||||
|
|
||||||
pass((x, y) -> {
|
for(int i = 0; i < tlen; i++){
|
||||||
if(floor.asFloor().isLiquid && !floor.asFloor().isDeep()){
|
Tile tile = tiles.geti(i);
|
||||||
|
if(tile.block() == Blocks.air){
|
||||||
for(int cx = -deepRadius; cx <= deepRadius; cx++){
|
total ++;
|
||||||
for(int cy = -deepRadius; cy <= deepRadius; cy++){
|
if(tile.floor().liquidDrop == Liquids.water){
|
||||||
|
waters ++;
|
||||||
if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){
|
|
||||||
int wx = cx + x, wy = cy + y;
|
|
||||||
|
|
||||||
Tile tile = tiles.get(wx, wy);
|
|
||||||
if(tile != null && (!tile.floor().isLiquid || tile.block() != Blocks.air)){
|
|
||||||
//found something solid, skip replacing anything
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
floor = floor == Blocks.darksandTaintedWater ? Blocks.taintedWater : Blocks.water;
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
boolean naval = (float)waters / total >= 0.28f;
|
||||||
|
|
||||||
|
Log.info(waters + " " + total );
|
||||||
|
|
||||||
|
//create water pathway if the map is flooded
|
||||||
|
if(naval){
|
||||||
|
for(Room room : enemies){
|
||||||
|
room.connectLiquid(spawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
distort(10f, 6f);
|
distort(10f, 6f);
|
||||||
|
|
||||||
@@ -318,6 +364,56 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//shoreline setup
|
||||||
|
pass((x, y) -> {
|
||||||
|
int deepRadius = 3;
|
||||||
|
|
||||||
|
if(floor.asFloor().isLiquid && floor.asFloor().shallow){
|
||||||
|
|
||||||
|
for(int cx = -deepRadius; cx <= deepRadius; cx++){
|
||||||
|
for(int cy = -deepRadius; cy <= deepRadius; cy++){
|
||||||
|
if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){
|
||||||
|
int wx = cx + x, wy = cy + y;
|
||||||
|
|
||||||
|
Tile tile = tiles.get(wx, wy);
|
||||||
|
if(tile != null && (!tile.floor().isLiquid || tile.block() != Blocks.air)){
|
||||||
|
//found something solid, skip replacing anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
floor = floor == Blocks.darksandTaintedWater ? Blocks.taintedWater : Blocks.water;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(naval){
|
||||||
|
int deepRadius = 2;
|
||||||
|
|
||||||
|
//TODO code is very similar, but annoying to extract into a separate function
|
||||||
|
pass((x, y) -> {
|
||||||
|
if(floor.asFloor().isLiquid && !floor.asFloor().isDeep() && !floor.asFloor().shallow){
|
||||||
|
|
||||||
|
for(int cx = -deepRadius; cx <= deepRadius; cx++){
|
||||||
|
for(int cy = -deepRadius; cy <= deepRadius; cy++){
|
||||||
|
if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){
|
||||||
|
int wx = cx + x, wy = cy + y;
|
||||||
|
|
||||||
|
Tile tile = tiles.get(wx, wy);
|
||||||
|
if(tile != null && (tile.floor().shallow || !tile.floor().isLiquid)){
|
||||||
|
//found something shallow, skip replacing anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
floor = floor == Blocks.water ? Blocks.deepwater : Blocks.deepTaintedWater;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Seq<Block> ores = Seq.with(Blocks.oreCopper, Blocks.oreLead);
|
Seq<Block> ores = Seq.with(Blocks.oreCopper, Blocks.oreLead);
|
||||||
float poles = Math.abs(sector.tile.v.y);
|
float poles = Math.abs(sector.tile.v.y);
|
||||||
float nmag = 0.5f;
|
float nmag = 0.5f;
|
||||||
@@ -555,7 +651,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
state.rules.enemyCoreBuildRadius = 600f;
|
state.rules.enemyCoreBuildRadius = 600f;
|
||||||
|
|
||||||
//spawn air only when spawn is blocked
|
//spawn air only when spawn is blocked
|
||||||
state.rules.spawns = Waves.generate(difficulty, new Rand(sector.id), state.rules.attackMode, state.rules.attackMode && spawner.countGroundSpawns() == 0);
|
state.rules.spawns = Waves.generate(difficulty, new Rand(sector.id), state.rules.attackMode, state.rules.attackMode && spawner.countGroundSpawns() == 0, naval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
/** This is a VERY ROUGH estimate of unit DPS. */
|
/** This is a VERY ROUGH estimate of unit DPS. */
|
||||||
public float dpsEstimate = -1;
|
public float dpsEstimate = -1;
|
||||||
public float clipSize = -1;
|
public float clipSize = -1;
|
||||||
public boolean canDrown = true;
|
public boolean canDrown = true, naval = false;
|
||||||
public float engineOffset = 5f, engineSize = 2.5f;
|
public float engineOffset = 5f, engineSize = 2.5f;
|
||||||
public float strafePenalty = 0.5f;
|
public float strafePenalty = 0.5f;
|
||||||
public float hitSize = 6f;
|
public float hitSize = 6f;
|
||||||
@@ -314,6 +314,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
//water preset
|
//water preset
|
||||||
if(example instanceof WaterMovec){
|
if(example instanceof WaterMovec){
|
||||||
|
naval = true;
|
||||||
canDrown = false;
|
canDrown = false;
|
||||||
omniMovement = false;
|
omniMovement = false;
|
||||||
immunities.add(StatusEffects.wet);
|
immunities.add(StatusEffects.wet);
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ public class Floor extends Block{
|
|||||||
public float liquidMultiplier = 1f;
|
public float liquidMultiplier = 1f;
|
||||||
/** whether this block is liquid. */
|
/** whether this block is liquid. */
|
||||||
public boolean isLiquid;
|
public boolean isLiquid;
|
||||||
|
/** shallow water flag used for generation */
|
||||||
|
public boolean shallow = false;
|
||||||
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
|
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
|
||||||
public boolean playerUnmineable = false;
|
public boolean playerUnmineable = false;
|
||||||
/** Group of blocks that this block does not draw edges on. */
|
/** Group of blocks that this block does not draw edges on. */
|
||||||
|
|||||||
@@ -24,5 +24,6 @@ public class ShallowLiquid extends Floor{
|
|||||||
status = liquidBase.status;
|
status = liquidBase.status;
|
||||||
liquidDrop = liquidBase.liquidDrop;
|
liquidDrop = liquidBase.liquidDrop;
|
||||||
cacheLayer = liquidBase.cacheLayer;
|
cacheLayer = liquidBase.cacheLayer;
|
||||||
|
shallow = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user