Merge branches '6.0' and 'splinterface-impl' of https://github.com/Anuken/Mindustry into splinterface-impl
# Conflicts: # core/assets/sprites/block_colors.png # core/assets/sprites/sprites.atlas # core/assets/sprites/sprites.png # core/assets/sprites/sprites3.png # core/assets/sprites/sprites5.png # core/src/mindustry/Vars.java # core/src/mindustry/entities/traits/SaveTrait.java # core/src/mindustry/maps/generators/MapGenerator.java # core/src/mindustry/ui/dialogs/DeployDialog.java # core/src/mindustry/world/blocks/Floor.java # desktop/src/mindustry/desktop/DesktopLauncher.java # gradle.properties
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -42,6 +42,7 @@ changelog
|
|||||||
*.gif
|
*.gif
|
||||||
/core/assets/saves/
|
/core/assets/saves/
|
||||||
/out/
|
/out/
|
||||||
|
/core/assets-raw/fontgen/out/
|
||||||
|
|
||||||
version.properties
|
version.properties
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
|
|
||||||
}, new AndroidApplicationConfiguration(){{
|
}, new AndroidApplicationConfiguration(){{
|
||||||
useImmersiveMode = true;
|
useImmersiveMode = true;
|
||||||
depth = 0;
|
|
||||||
hideStatusBar = true;
|
hideStatusBar = true;
|
||||||
errorHandler = CrashSender::log;
|
errorHandler = CrashSender::log;
|
||||||
}});
|
}});
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ project(":core"){
|
|||||||
compile "org.lz4:lz4-java:1.4.1"
|
compile "org.lz4:lz4-java:1.4.1"
|
||||||
compile arcModule("arc-core")
|
compile arcModule("arc-core")
|
||||||
compile arcModule("extensions:freetype")
|
compile arcModule("extensions:freetype")
|
||||||
|
compile arcModule("extensions:g3d")
|
||||||
compile arcModule("extensions:arcnet")
|
compile arcModule("extensions:arcnet")
|
||||||
compile "org.mozilla:rhino:1.7.11"
|
compile "org.mozilla:rhino:1.7.11"
|
||||||
if(localArc() && debugged()) compile arcModule("extensions:recorder")
|
if(localArc() && debugged()) compile arcModule("extensions:recorder")
|
||||||
|
|||||||
BIN
core/assets-raw/sprites/blocks/environment/slag.png
Normal file
BIN
core/assets-raw/sprites/blocks/environment/slag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -394,6 +394,8 @@ toolmode.drawteams.description = Draw teams instead of blocks.
|
|||||||
filters.empty = [lightgray]No filters! Add one with the button below.
|
filters.empty = [lightgray]No filters! Add one with the button below.
|
||||||
filter.distort = Distort
|
filter.distort = Distort
|
||||||
filter.noise = Noise
|
filter.noise = Noise
|
||||||
|
filter.enemyspawn = Enemy Spawn Select
|
||||||
|
filter.corespawn = Core Select
|
||||||
filter.median = Median
|
filter.median = Median
|
||||||
filter.oremedian = Ore Median
|
filter.oremedian = Ore Median
|
||||||
filter.blend = Blend
|
filter.blend = Blend
|
||||||
@@ -413,6 +415,7 @@ filter.option.circle-scale = Circle Scale
|
|||||||
filter.option.octaves = Octaves
|
filter.option.octaves = Octaves
|
||||||
filter.option.falloff = Falloff
|
filter.option.falloff = Falloff
|
||||||
filter.option.angle = Angle
|
filter.option.angle = Angle
|
||||||
|
filter.option.amount = Amount
|
||||||
filter.option.block = Block
|
filter.option.block = Block
|
||||||
filter.option.floor = Floor
|
filter.option.floor = Floor
|
||||||
filter.option.flooronto = Target Floor
|
filter.option.flooronto = Target Floor
|
||||||
@@ -850,6 +853,7 @@ liquid.temperature = [lightgray]Temperature: {0}
|
|||||||
|
|
||||||
block.sand-boulder.name = Sand Boulder
|
block.sand-boulder.name = Sand Boulder
|
||||||
block.grass.name = Grass
|
block.grass.name = Grass
|
||||||
|
block.slag.name = Slag
|
||||||
block.salt.name = Salt
|
block.salt.name = Salt
|
||||||
block.saltrocks.name = Salt Rocks
|
block.saltrocks.name = Salt Rocks
|
||||||
block.pebbles.name = Pebbles
|
block.pebbles.name = Pebbles
|
||||||
|
|||||||
BIN
core/assets/planets/colors.png
Normal file
BIN
core/assets/planets/colors.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
9
core/assets/shaders/planet.fragment.glsl
Executable file
9
core/assets/shaders/planet.fragment.glsl
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec4 v_col;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
gl_FragColor = v_col;
|
||||||
|
}
|
||||||
18
core/assets/shaders/planet.vertex.glsl
Executable file
18
core/assets/shaders/planet.vertex.glsl
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
attribute vec4 a_position;
|
||||||
|
attribute vec3 a_normal;
|
||||||
|
attribute vec4 a_color;
|
||||||
|
uniform mat4 u_projModelView;
|
||||||
|
varying vec4 v_col;
|
||||||
|
|
||||||
|
const vec3 ambientColor = vec3(1.0);
|
||||||
|
const vec3 ambientDir = normalize(vec3(1.0, 1.0, 1.0));
|
||||||
|
const vec3 diffuse = vec3(0.5);
|
||||||
|
const vec3 v1 = vec3(1.0, 0.0, 1.0);
|
||||||
|
const vec3 v2 = vec3(1.0, 0.5, 0.0);
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec3 norc = ambientColor * clamp((dot(a_normal, ambientDir) + 1.0) / 2.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
v_col = a_color * vec4(norc, 1.0);
|
||||||
|
gl_Position = u_projModelView * a_position;
|
||||||
|
}
|
||||||
86
core/assets/shaders/slag.fragment.glsl
Executable file
86
core/assets/shaders/slag.fragment.glsl
Executable file
@@ -0,0 +1,86 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
precision highp float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//shade 1 + 2
|
||||||
|
#define s2 vec3(100.0, 93.0, 49.0) / 100.0
|
||||||
|
#define s1 vec3(100.0, 60.0, 25.0) / 100.0
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
uniform vec2 camerapos;
|
||||||
|
uniform vec2 screensize;
|
||||||
|
uniform float time;
|
||||||
|
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
|
vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
|
||||||
|
|
||||||
|
float snoise(vec2 v){
|
||||||
|
const vec4 C = vec4(0.211324865405187, 0.366025403784439,
|
||||||
|
-0.577350269189626, 0.024390243902439);
|
||||||
|
vec2 i = floor(v + dot(v, C.yy) );
|
||||||
|
vec2 x0 = v - i + dot(i, C.xx);
|
||||||
|
vec2 i1;
|
||||||
|
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
||||||
|
vec4 x12 = x0.xyxy + C.xxzz;
|
||||||
|
x12.xy -= i1;
|
||||||
|
i = mod(i, 289.0);
|
||||||
|
vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
|
||||||
|
+ i.x + vec3(0.0, i1.x, 1.0 ));
|
||||||
|
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
|
||||||
|
dot(x12.zw,x12.zw)), 0.0);
|
||||||
|
m = m*m ;
|
||||||
|
m = m*m ;
|
||||||
|
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
||||||
|
vec3 h = abs(x) - 0.5;
|
||||||
|
vec3 ox = floor(x + 0.5);
|
||||||
|
vec3 a0 = x - ox;
|
||||||
|
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
|
||||||
|
vec3 g;
|
||||||
|
g.x = a0.x * x0.x + h.x * x0.y;
|
||||||
|
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
||||||
|
return 130.0 * dot(m, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
vec2 c = v_texCoord.xy;
|
||||||
|
vec4 color = texture2D(u_texture, c);
|
||||||
|
|
||||||
|
vec2 v = vec2(1.0/screensize.x, 1.0/screensize.y);
|
||||||
|
vec2 coords = c / v + camerapos;
|
||||||
|
|
||||||
|
float stime = time / 5.0;
|
||||||
|
|
||||||
|
float mscl = 30.0;
|
||||||
|
float mth = 5.0;
|
||||||
|
|
||||||
|
//if there's something actually there
|
||||||
|
if(color.r > 0.01){
|
||||||
|
vec4 old = color;
|
||||||
|
color = texture2D(u_texture, c + vec2(sin(stime/3.0 + coords.y/0.75) * v.x, 0.0)) * vec4(0.9, 0.9, 1, 1.0);
|
||||||
|
|
||||||
|
if(color.r < 0.01){
|
||||||
|
color = old;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float bs = 1.1;
|
||||||
|
|
||||||
|
float n1 = snoise(coords / (30.0 * bs) + vec2(time) / 280.0);
|
||||||
|
float n2 = snoise((coords + vec2(632.0)) / (14.0 * bs) + vec2(0.0, -time) / 290.0);
|
||||||
|
float n3 = snoise((coords + vec2(2233.0)) / (25.0 * bs) + vec2(time, 0.0) / 380.0);
|
||||||
|
|
||||||
|
float r = (n1 + n2 + n3) / 3.0;
|
||||||
|
|
||||||
|
if(r < -0.5){
|
||||||
|
color = vec4(s2, color.a);
|
||||||
|
}else if(r < -0.2){
|
||||||
|
color = vec4(s1, color.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 278 KiB After Width: | Height: | Size: 283 KiB |
@@ -90,10 +90,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||||||
assets.load(mods);
|
assets.load(mods);
|
||||||
assets.load(schematics);
|
assets.load(schematics);
|
||||||
|
|
||||||
assets.loadRun("contentinit", ContentLoader.class, () -> {
|
assets.loadRun("contentinit", ContentLoader.class, () -> content.init(), () -> content.load());
|
||||||
content.init();
|
|
||||||
content.load();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class Blocks implements ContentList{
|
|||||||
public static Block
|
public static Block
|
||||||
|
|
||||||
//environment
|
//environment
|
||||||
air, spawn, deepwater, water, taintedWater, tar, stone, craters, charr, sand, darksand, ice, snow, darksandTaintedWater,
|
air, spawn, deepwater, water, taintedWater, tar, slag, stone, craters, charr, sand, darksand, ice, snow, darksandTaintedWater,
|
||||||
holostone, rocks, sporerocks, icerocks, cliffs, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
|
holostone, rocks, sporerocks, icerocks, cliffs, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
|
||||||
iceSnow, sandWater, darksandWater, duneRocks, sandRocks, moss, sporeMoss, shale, shaleRocks, shaleBoulder, sandBoulder, grass, salt,
|
iceSnow, sandWater, darksandWater, duneRocks, sandRocks, moss, sporeMoss, shale, shaleRocks, shaleBoulder, sandBoulder, grass, salt,
|
||||||
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, ignarock, magmarock, hotrock, snowrocks, rock, snowrock, saltRocks,
|
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, ignarock, magmarock, hotrock, snowrocks, rock, snowrock, saltRocks,
|
||||||
@@ -202,6 +202,17 @@ public class Blocks implements ContentList{
|
|||||||
cacheLayer = CacheLayer.tar;
|
cacheLayer = CacheLayer.tar;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
slag = new Floor("slag"){{
|
||||||
|
drownTime = 150f;
|
||||||
|
status = StatusEffects.melting;
|
||||||
|
statusDuration = 240f;
|
||||||
|
speedMultiplier = 0.19f;
|
||||||
|
variants = 0;
|
||||||
|
liquidDrop = Liquids.slag;
|
||||||
|
isLiquid = true;
|
||||||
|
cacheLayer = CacheLayer.slag;
|
||||||
|
}};
|
||||||
|
|
||||||
stone = new Floor("stone"){{
|
stone = new Floor("stone"){{
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|||||||
18
core/src/mindustry/content/Planets.java
Normal file
18
core/src/mindustry/content/Planets.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package mindustry.content;
|
||||||
|
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.maps.planet.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
|
||||||
|
public class Planets implements ContentList{
|
||||||
|
//TODO make all names
|
||||||
|
public static Planet starter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(){
|
||||||
|
starter = new Planet("//TODO"){{
|
||||||
|
detail = 6;
|
||||||
|
generator = new TestPlanetGenerator();
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
}
|
||||||
15
core/src/mindustry/content/Weathers.java
Normal file
15
core/src/mindustry/content/Weathers.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package mindustry.content;
|
||||||
|
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
|
||||||
|
public class Weathers implements ContentList{
|
||||||
|
public static Weather
|
||||||
|
rain,
|
||||||
|
snow;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
package mindustry.content;
|
package mindustry.content;
|
||||||
|
|
||||||
import mindustry.ctype.ContentList;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.*;
|
|
||||||
import mindustry.game.Objectives.*;
|
import mindustry.game.Objectives.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.maps.generators.*;
|
import mindustry.maps.generators.*;
|
||||||
import mindustry.maps.generators.MapGenerator.*;
|
|
||||||
import mindustry.maps.zonegen.*;
|
import mindustry.maps.zonegen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
import static arc.struct.Array.with;
|
import static arc.struct.Array.with;
|
||||||
import static mindustry.content.Items.*;
|
import static mindustry.content.Items.*;
|
||||||
|
import static mindustry.content.Planets.starter;
|
||||||
import static mindustry.type.ItemStack.list;
|
import static mindustry.type.ItemStack.list;
|
||||||
|
|
||||||
public class Zones implements ContentList{
|
public class Zones implements ContentList{
|
||||||
@@ -22,7 +22,7 @@ public class Zones implements ContentList{
|
|||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
|
|
||||||
groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{
|
groundZero = new Zone("groundZero", starter, new MapGenerator("groundZero")){{
|
||||||
baseLaunchCost = list(copper, -60);
|
baseLaunchCost = list(copper, -60);
|
||||||
startingItems = list(copper, 60);
|
startingItems = list(copper, 60);
|
||||||
alwaysUnlocked = true;
|
alwaysUnlocked = true;
|
||||||
@@ -31,7 +31,7 @@ public class Zones implements ContentList{
|
|||||||
resources = with(copper, scrap, lead);
|
resources = with(copper, scrap, lead);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
desertWastes = new Zone("desertWastes", new DesertWastesGenerator(260, 260)){{
|
desertWastes = new Zone("desertWastes", starter, new DesertWastesGenerator(260, 260)){{
|
||||||
startingItems = list(copper, 120);
|
startingItems = list(copper, 120);
|
||||||
conditionWave = 20;
|
conditionWave = 20;
|
||||||
launchPeriod = 10;
|
launchPeriod = 10;
|
||||||
@@ -82,7 +82,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
saltFlats = new Zone("saltFlats", new MapGenerator("saltFlats")){{
|
saltFlats = new Zone("saltFlats", starter, new MapGenerator("saltFlats")){{
|
||||||
startingItems = list(copper, 200, Items.silicon, 200, lead, 200);
|
startingItems = list(copper, 200, Items.silicon, 200, lead, 200);
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
@@ -98,8 +98,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
frozenForest = new Zone("frozenForest", new MapGenerator("frozenForest", 1)
|
frozenForest = new Zone("frozenForest", starter, new MapGenerator("frozenForest")){{
|
||||||
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{
|
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 250);
|
startingItems = list(copper, 250);
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
@@ -111,7 +110,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
craters = new Zone("craters", new MapGenerator("craters", 1).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{
|
craters = new Zone("craters", starter, new MapGenerator("craters")){{
|
||||||
startingItems = list(copper, 100);
|
startingItems = list(copper, 100);
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
resources = with(copper, lead, coal, sand, scrap);
|
resources = with(copper, lead, coal, sand, scrap);
|
||||||
@@ -122,7 +121,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1)){{
|
ruinousShores = new Zone("ruinousShores", starter, new MapGenerator("ruinousShores")){{
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 140, lead, 50);
|
startingItems = list(copper, 140, lead, 50);
|
||||||
conditionWave = 20;
|
conditionWave = 20;
|
||||||
@@ -138,8 +137,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
stainedMountains = new Zone("stainedMountains", new MapGenerator("stainedMountains", 2)
|
stainedMountains = new Zone("stainedMountains", starter, new MapGenerator("stainedMountains")){{
|
||||||
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
|
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 200, lead, 50);
|
startingItems = list(copper, 200, lead, 50);
|
||||||
conditionWave = 10;
|
conditionWave = 10;
|
||||||
@@ -153,7 +151,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
fungalPass = new Zone("fungalPass", new MapGenerator("fungalPass")){{
|
fungalPass = new Zone("fungalPass", starter, new MapGenerator("fungalPass")){{
|
||||||
startingItems = list(copper, 250, lead, 250, Items.metaglass, 100, Items.graphite, 100);
|
startingItems = list(copper, 250, lead, 250, Items.metaglass, 100, Items.graphite, 100);
|
||||||
resources = with(copper, lead, coal, titanium, sand);
|
resources = with(copper, lead, coal, titanium, sand);
|
||||||
configureObjective = new Launched(this);
|
configureObjective = new Launched(this);
|
||||||
@@ -166,7 +164,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
overgrowth = new Zone("overgrowth", new MapGenerator("overgrowth")){{
|
overgrowth = new Zone("overgrowth", starter, new MapGenerator("overgrowth")){{
|
||||||
startingItems = list(copper, 1500, lead, 1000, Items.silicon, 500, Items.metaglass, 250);
|
startingItems = list(copper, 1500, lead, 1000, Items.silicon, 500, Items.metaglass, 250);
|
||||||
conditionWave = 12;
|
conditionWave = 12;
|
||||||
launchPeriod = 4;
|
launchPeriod = 4;
|
||||||
@@ -183,8 +181,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
tarFields = new Zone("tarFields", new MapGenerator("tarFields")
|
tarFields = new Zone("tarFields", starter, new MapGenerator("tarFields")){{
|
||||||
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
|
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
startingItems = list(copper, 250, lead, 100);
|
startingItems = list(copper, 250, lead, 100);
|
||||||
conditionWave = 15;
|
conditionWave = 15;
|
||||||
@@ -198,7 +195,7 @@ public class Zones implements ContentList{
|
|||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift")){{
|
desolateRift = new Zone("desolateRift", starter, new MapGenerator("desolateRift")){{
|
||||||
loadout = Loadouts.basicNucleus;
|
loadout = Loadouts.basicNucleus;
|
||||||
startingItems = list(copper, 1000, lead, 1000, Items.graphite, 250, titanium, 250, Items.silicon, 250);
|
startingItems = list(copper, 1000, lead, 1000, Items.graphite, 250, titanium, 250, Items.silicon, 250);
|
||||||
conditionWave = 3;
|
conditionWave = 3;
|
||||||
@@ -223,8 +220,7 @@ public class Zones implements ContentList{
|
|||||||
resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
|
resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
|
||||||
}};*/
|
}};*/
|
||||||
|
|
||||||
nuclearComplex = new Zone("nuclearComplex", new MapGenerator("nuclearProductionComplex", 1)
|
nuclearComplex = new Zone("nuclearComplex", starter, new MapGenerator("nuclearProductionComplex")){{
|
||||||
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{
|
|
||||||
loadout = Loadouts.basicNucleus;
|
loadout = Loadouts.basicNucleus;
|
||||||
startingItems = list(copper, 1250, lead, 1500, Items.silicon, 400, Items.metaglass, 250);
|
startingItems = list(copper, 1250, lead, 1500, Items.silicon, 400, Items.metaglass, 250);
|
||||||
conditionWave = 30;
|
conditionWave = 30;
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public class ContentLoader{
|
|||||||
new Blocks(),
|
new Blocks(),
|
||||||
new Loadouts(),
|
new Loadouts(),
|
||||||
new TechTree(),
|
new TechTree(),
|
||||||
|
new Weathers(),
|
||||||
|
new Planets(),
|
||||||
new Zones(),
|
new Zones(),
|
||||||
new TypeIDs(),
|
new TypeIDs(),
|
||||||
|
|
||||||
|
|||||||
@@ -249,7 +249,9 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playZone(Zone zone){
|
//TODO remove, make it viable on a server
|
||||||
|
/*public void playZone(Zone zone){
|
||||||
|
|
||||||
ui.loadAnd(() -> {
|
ui.loadAnd(() -> {
|
||||||
logic.reset();
|
logic.reset();
|
||||||
net.reset();
|
net.reset();
|
||||||
@@ -267,6 +269,16 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
logic.play();
|
logic.play();
|
||||||
Events.fire(Trigger.newGame);
|
Events.fire(Trigger.newGame);
|
||||||
});
|
});
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public void playSector(Sector sector){
|
||||||
|
ui.loadAnd(() -> {
|
||||||
|
logic.reset();
|
||||||
|
world.loadSector(sector);
|
||||||
|
state.set(State.playing);
|
||||||
|
logic.play();
|
||||||
|
ui.planet.hide();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playTutorial(){
|
public void playTutorial(){
|
||||||
@@ -277,8 +289,8 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
world.beginMapLoad();
|
world.beginMapLoad();
|
||||||
|
|
||||||
world.createTiles(zone.generator.width, zone.generator.height);
|
world.resize(zone.generator.width, zone.generator.height);
|
||||||
zone.generator.generate(world.getTiles());
|
zone.generator.generate(world.tiles);
|
||||||
|
|
||||||
Tile coreb = null;
|
Tile coreb = null;
|
||||||
|
|
||||||
|
|||||||
@@ -236,6 +236,7 @@ public class Logic implements ApplicationListener{
|
|||||||
bulletGroup.update();
|
bulletGroup.update();
|
||||||
tileGroup.update();
|
tileGroup.update();
|
||||||
fireGroup.update();
|
fireGroup.update();
|
||||||
|
weatherGroup.update();
|
||||||
}else{
|
}else{
|
||||||
unitGroup.updateEvents();
|
unitGroup.updateEvents();
|
||||||
collisions.updatePhysics(unitGroup);
|
collisions.updatePhysics(unitGroup);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
public TraceDialog traces;
|
public TraceDialog traces;
|
||||||
public DatabaseDialog database;
|
public DatabaseDialog database;
|
||||||
public ContentInfoDialog content;
|
public ContentInfoDialog content;
|
||||||
public DeployDialog deploy;
|
public PlanetDialog planet;
|
||||||
public TechTreeDialog tech;
|
public TechTreeDialog tech;
|
||||||
//public MinimapDialog minimap;
|
//public MinimapDialog minimap;
|
||||||
public SchematicsDialog schematics;
|
public SchematicsDialog schematics;
|
||||||
@@ -176,7 +176,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
traces = new TraceDialog();
|
traces = new TraceDialog();
|
||||||
maps = new MapsDialog();
|
maps = new MapsDialog();
|
||||||
content = new ContentInfoDialog();
|
content = new ContentInfoDialog();
|
||||||
deploy = new DeployDialog();
|
planet = new PlanetDialog();
|
||||||
tech = new TechTreeDialog();
|
tech = new TechTreeDialog();
|
||||||
mods = new ModsDialog();
|
mods = new ModsDialog();
|
||||||
schematics = new SchematicsDialog();
|
schematics = new SchematicsDialog();
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package mindustry.core;
|
package mindustry.core;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.func.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.content.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -14,7 +16,6 @@ import mindustry.io.*;
|
|||||||
import mindustry.maps.*;
|
import mindustry.maps.*;
|
||||||
import mindustry.maps.filters.*;
|
import mindustry.maps.filters.*;
|
||||||
import mindustry.maps.filters.GenerateFilter.*;
|
import mindustry.maps.filters.GenerateFilter.*;
|
||||||
import mindustry.maps.generators.*;
|
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
@@ -25,7 +26,7 @@ public class World{
|
|||||||
public final Context context = new Context();
|
public final Context context = new Context();
|
||||||
|
|
||||||
private Map currentMap;
|
private Map currentMap;
|
||||||
private Tile[][] tiles;
|
public @NonNull Tiles tiles = new Tiles(0, 0);
|
||||||
|
|
||||||
private boolean generating, invalidMap;
|
private boolean generating, invalidMap;
|
||||||
|
|
||||||
@@ -67,11 +68,11 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int width(){
|
public int width(){
|
||||||
return tiles == null ? 0 : tiles.length;
|
return tiles.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int height(){
|
public int height(){
|
||||||
return tiles == null ? 0 : tiles[0].length;
|
return tiles.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int unitWidth(){
|
public int unitWidth(){
|
||||||
@@ -88,11 +89,7 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile tile(int x, int y){
|
public @Nullable Tile tile(int x, int y){
|
||||||
if(tiles == null){
|
return tiles.get(x, y);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if(!Structs.inBounds(x, y, tiles)) return null;
|
|
||||||
return tiles[x][y];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile ltile(int x, int y){
|
public @Nullable Tile ltile(int x, int y){
|
||||||
@@ -102,7 +99,7 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Tile rawTile(int x, int y){
|
public Tile rawTile(int x, int y){
|
||||||
return tiles[x][y];
|
return tiles.getn(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Tile tileWorld(float x, float y){
|
public @Nullable Tile tileWorld(float x, float y){
|
||||||
@@ -117,16 +114,10 @@ public class World{
|
|||||||
return Math.round(coord / tilesize);
|
return Math.round(coord / tilesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[][] getTiles(){
|
|
||||||
return tiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearTileEntities(){
|
private void clearTileEntities(){
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
if(tile != null && tile.entity != null){
|
||||||
if(tiles[x][y] != null && tiles[x][y].entity != null){
|
tile.entity.remove();
|
||||||
tiles[x][y].entity.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,15 +126,11 @@ public class World{
|
|||||||
* Resizes the tile array to the specified size and returns the resulting tile array.
|
* Resizes the tile array to the specified size and returns the resulting tile array.
|
||||||
* Only use for loading saves!
|
* Only use for loading saves!
|
||||||
*/
|
*/
|
||||||
public Tile[][] createTiles(int width, int height){
|
public Tiles resize(int width, int height){
|
||||||
if(tiles != null){
|
clearTileEntities();
|
||||||
clearTileEntities();
|
|
||||||
|
|
||||||
if(tiles.length != width || tiles[0].length != height){
|
if(tiles.width() != width || tiles.height() != height){
|
||||||
tiles = new Tile[width][height];
|
tiles = new Tiles(width, height);
|
||||||
}
|
|
||||||
}else{
|
|
||||||
tiles = new Tile[width][height];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tiles;
|
return tiles;
|
||||||
@@ -164,14 +151,11 @@ public class World{
|
|||||||
public void endMapLoad(){
|
public void endMapLoad(){
|
||||||
prepareTiles(tiles);
|
prepareTiles(tiles);
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
tile.updateOcclusion();
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
tile.updateOcclusion();
|
|
||||||
|
|
||||||
if(tile.entity != null){
|
if(tile.entity != null){
|
||||||
tile.entity.updateProximity();
|
tile.entity.updateProximity();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +163,7 @@ public class World{
|
|||||||
addDarkness(tiles);
|
addDarkness(tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2));
|
entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.width() * tilesize + finalWorldBounds * 2, tiles.height() * tilesize + finalWorldBounds * 2));
|
||||||
|
|
||||||
generating = false;
|
generating = false;
|
||||||
Events.fire(new WorldLoadEvent());
|
Events.fire(new WorldLoadEvent());
|
||||||
@@ -201,15 +185,32 @@ public class World{
|
|||||||
return state.rules.zone;
|
return state.rules.zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadGenerator(Generator generator){
|
public void loadGenerator(int width, int height, Cons<Tiles> generator){
|
||||||
beginMapLoad();
|
beginMapLoad();
|
||||||
|
|
||||||
createTiles(generator.width, generator.height);
|
resize(width, height);
|
||||||
generator.generate(tiles);
|
generator.get(tiles);
|
||||||
|
|
||||||
endMapLoad();
|
endMapLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadSector(Sector sector){
|
||||||
|
int size = (int)(sector.rect.radius * 2500);
|
||||||
|
|
||||||
|
loadGenerator(size, size, tiles -> {
|
||||||
|
TileGen gen = new TileGen();
|
||||||
|
tiles.each((x, y) -> {
|
||||||
|
gen.reset();
|
||||||
|
Vec3 position = sector.rect.project(x / (float)size, y / (float)size);
|
||||||
|
|
||||||
|
sector.planet.generator.generate(position, gen);
|
||||||
|
tiles.set(x, y, new Tile(x, y, gen.floor, gen.overlay, gen.block));
|
||||||
|
});
|
||||||
|
|
||||||
|
tiles.get(size/2, size/2).setBlock(Blocks.coreShard, Team.sharded);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void loadMap(Map map){
|
public void loadMap(Map map){
|
||||||
loadMap(map, new Rules());
|
loadMap(map, new Rules());
|
||||||
}
|
}
|
||||||
@@ -297,58 +298,56 @@ public class World{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDarkness(Tile[][] tiles){
|
public void addDarkness(Tiles tiles){
|
||||||
byte[][] dark = new byte[tiles.length][tiles[0].length];
|
byte[] dark = new byte[tiles.width() * tiles.height()];
|
||||||
byte[][] writeBuffer = new byte[tiles.length][tiles[0].length];
|
byte[] writeBuffer = new byte[tiles.width() * tiles.height()];
|
||||||
|
|
||||||
byte darkIterations = 4;
|
byte darkIterations = 4;
|
||||||
for(int x = 0; x < tiles.length; x++){
|
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
for(int i = 0; i < dark.length; i++){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.geti(i);
|
||||||
if(tile.isDarkened()){
|
if(tile.isDarkened()){
|
||||||
dark[x][y] = darkIterations;
|
dark[i] = darkIterations;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < darkIterations; i++){
|
for(int i = 0; i < darkIterations; i++){
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
int idx = tile.y * tiles.width() + tile.x;
|
||||||
boolean min = false;
|
boolean min = false;
|
||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
int newX = x + point.x, newY = y + point.y;
|
int newX = tile.x + point.x, newY = tile.y + point.y;
|
||||||
if(Structs.inBounds(newX, newY, tiles) && dark[newX][newY] < dark[x][y]){
|
int nidx = newY * tiles.width() + newX;
|
||||||
min = true;
|
if(tiles.in(newX, newY) && dark[nidx] < dark[idx]){
|
||||||
break;
|
min = true;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
writeBuffer[x][y] = (byte)Math.max(0, dark[x][y] - Mathf.num(min));
|
|
||||||
}
|
}
|
||||||
|
writeBuffer[idx] = (byte)Math.max(0, dark[idx] - Mathf.num(min));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
System.arraycopy(writeBuffer, 0, dark, 0, writeBuffer.length);
|
||||||
System.arraycopy(writeBuffer[x], 0, dark[x], 0, tiles[0].length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
int idx = tile.y * tiles.width() + tile.x;
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
if(tile.isDarkened()){
|
|
||||||
tiles[x][y].rotation(dark[x][y]);
|
|
||||||
}
|
|
||||||
if(dark[x][y] == 4){
|
|
||||||
boolean full = true;
|
|
||||||
for(Point2 p : Geometry.d4){
|
|
||||||
int px = p.x + x, py = p.y + y;
|
|
||||||
if(Structs.inBounds(px, py, tiles) && !(tiles[px][py].isDarkened() && dark[px][py] == 4)){
|
|
||||||
full = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(full) tiles[x][y].rotation(5);
|
if(tile.isDarkened()){
|
||||||
|
tile.rotation(dark[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dark[idx] == 4){
|
||||||
|
boolean full = true;
|
||||||
|
for(Point2 p : Geometry.d4){
|
||||||
|
int px = p.x + tile.x, py = p.y + tile.y;
|
||||||
|
int nidx = py * tiles.width() + px;
|
||||||
|
if(tiles.in(px, py) && !(tile.isDarkened() && dark[nidx] == 4)){
|
||||||
|
full = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(full) tile.rotation(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,18 +358,13 @@ public class World{
|
|||||||
* - updating occlusion<br>
|
* - updating occlusion<br>
|
||||||
* Usually used before placing structures on a tile array.
|
* Usually used before placing structures on a tile array.
|
||||||
*/
|
*/
|
||||||
public void prepareTiles(Tile[][] tiles){
|
public void prepareTiles(Tiles tiles){
|
||||||
|
|
||||||
//find multiblocks
|
//find multiblocks
|
||||||
IntArray multiblocks = new IntArray();
|
IntArray multiblocks = new IntArray();
|
||||||
|
for(Tile tile : tiles){
|
||||||
for(int x = 0; x < tiles.length; x++){
|
if(tile.block().isMultiblock()){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
multiblocks.add(tile.pos());
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
|
|
||||||
if(tile.block().isMultiblock()){
|
|
||||||
multiblocks.add(tile.pos());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,9 +374,10 @@ public class World{
|
|||||||
|
|
||||||
int x = Pos.x(pos);
|
int x = Pos.x(pos);
|
||||||
int y = Pos.y(pos);
|
int y = Pos.y(pos);
|
||||||
|
Tile tile = tiles.getn(x, y);
|
||||||
|
|
||||||
Block result = tiles[x][y].block();
|
Block result = tile.block();
|
||||||
Team team = tiles[x][y].getTeam();
|
Team team = tile.getTeam();
|
||||||
|
|
||||||
int offsetx = -(result.size - 1) / 2;
|
int offsetx = -(result.size - 1) / 2;
|
||||||
int offsety = -(result.size - 1) / 2;
|
int offsety = -(result.size - 1) / 2;
|
||||||
@@ -409,17 +404,19 @@ public class World{
|
|||||||
private class Context implements WorldContext{
|
private class Context implements WorldContext{
|
||||||
@Override
|
@Override
|
||||||
public Tile tile(int x, int y){
|
public Tile tile(int x, int y){
|
||||||
return tiles[x][y];
|
return tiles.get(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
createTiles(width, height);
|
World.this.resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
||||||
return (tiles[x][y] = new Tile(x, y, floorID, overlayID, wallID));
|
Tile tile = new Tile(x, y, floorID, overlayID, wallID);
|
||||||
|
tiles.set(x, y, tile);
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -454,23 +451,8 @@ public class World{
|
|||||||
GenerateInput input = new GenerateInput();
|
GenerateInput input = new GenerateInput();
|
||||||
|
|
||||||
for(GenerateFilter filter : filters){
|
for(GenerateFilter filter : filters){
|
||||||
input.begin(filter, width(), height(), (x, y) -> tiles[x][y]);
|
input.begin(filter, width(), height(), (x, y) -> tiles.getn(x, y));
|
||||||
|
filter.apply(tiles, input);
|
||||||
//actually apply the filter
|
|
||||||
for(int x = 0; x < width(); x++){
|
|
||||||
for(int y = 0; y < height(); y++){
|
|
||||||
Tile tile = rawTile(x, y);
|
|
||||||
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
|
|
||||||
filter.apply(input);
|
|
||||||
|
|
||||||
tile.setFloor((Floor)input.floor);
|
|
||||||
tile.setOverlay(input.ore);
|
|
||||||
|
|
||||||
if(!tile.block().synthetic() && !input.block.synthetic()){
|
|
||||||
tile.setBlock(input.block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ public enum ContentType{
|
|||||||
zone,
|
zone,
|
||||||
loadout,
|
loadout,
|
||||||
typeid,
|
typeid,
|
||||||
error;
|
error,
|
||||||
|
planet;
|
||||||
|
|
||||||
public static final ContentType[] all = values();
|
public static final ContentType[] all = values();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
public void onUnlock(){
|
public void onUnlock(){
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this content is always hidden in the content info dialog. */
|
/** Whether this content is always hidden in the content database dialog. */
|
||||||
public boolean isHidden(){
|
public boolean isHidden(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import mindustry.world.modules.*;
|
|||||||
import static mindustry.Vars.state;
|
import static mindustry.Vars.state;
|
||||||
import static mindustry.Vars.ui;
|
import static mindustry.Vars.ui;
|
||||||
|
|
||||||
//TODO somehow remove or replace this class with a more flexible solution
|
|
||||||
public class EditorTile extends Tile{
|
public class EditorTile extends Tile{
|
||||||
|
|
||||||
public EditorTile(int x, int y, int floor, int overlay, int wall){
|
public EditorTile(int x, int y, int floor, int overlay, int wall){
|
||||||
|
|||||||
@@ -69,25 +69,23 @@ public class MapEditor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//adds missing blockparts
|
//adds missing blockparts
|
||||||
|
//TODO remove, may not be necessary with blockpart refactor later
|
||||||
public void checkLinkedTiles(){
|
public void checkLinkedTiles(){
|
||||||
Tile[][] tiles = world.getTiles();
|
Tiles tiles = world.tiles;
|
||||||
|
|
||||||
//clear block parts first
|
//clear old parts
|
||||||
for(int x = 0; x < width(); x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < height(); y++){
|
if(tile.block() instanceof BlockPart){
|
||||||
if(tiles[x][y].block() instanceof BlockPart){
|
tile.setBlock(Blocks.air);
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up missing blockparts
|
//re-add them
|
||||||
for(int x = 0; x < width(); x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < height(); y++){
|
if(tile.block().isMultiblock()){
|
||||||
if(tiles[x][y].block().isMultiblock()){
|
tile.set(tile.block(), tile.getTeam());
|
||||||
tiles[x][y].set(tiles[x][y].block(), tiles[x][y].getTeam());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,11 +97,11 @@ public class MapEditor{
|
|||||||
|
|
||||||
/** Creates a 2-D array of EditorTiles with stone as the floor block. */
|
/** Creates a 2-D array of EditorTiles with stone as the floor block. */
|
||||||
private void createTiles(int width, int height){
|
private void createTiles(int width, int height){
|
||||||
Tile[][] tiles = world.createTiles(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
|
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,8 +117,8 @@ public class MapEditor{
|
|||||||
tags = new StringMap();
|
tags = new StringMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[][] tiles(){
|
public Tiles tiles(){
|
||||||
return world.getTiles();
|
return world.tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile tile(int x, int y){
|
public Tile tile(int x, int y){
|
||||||
@@ -245,20 +243,20 @@ public class MapEditor{
|
|||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
clearOp();
|
clearOp();
|
||||||
|
|
||||||
Tile[][] previous = world.getTiles();
|
Tiles previous = world.tiles;
|
||||||
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2;
|
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2;
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
Tile[][] tiles = world.createTiles(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
int px = offsetX + x, py = offsetY + y;
|
int px = offsetX + x, py = offsetY + y;
|
||||||
if(Structs.inBounds(px, py, previous.length, previous[0].length)){
|
if(previous.in(px, py)){
|
||||||
tiles[x][y] = previous[px][py];
|
tiles.set(x, y, previous.getn(px, py));
|
||||||
tiles[x][y].x = (short)x;
|
tiles.getn(x, y).x = (short)x;
|
||||||
tiles[x][y].y = (short)y;
|
tiles.getn(x, y).y = (short)y;
|
||||||
}else{
|
}else{
|
||||||
tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
|
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,12 +312,14 @@ public class MapEditor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
world.createTiles(width, height);
|
world.resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
|
||||||
return (tiles()[x][y] = new EditorTile(x, y, floorID, overlayID, wallID));
|
Tile tile = new EditorTile(x, y, floorID, overlayID, wallID);
|
||||||
|
tiles().set(x, y, tile);
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
private final Prov<GenerateFilter>[] filterTypes = new Prov[]{
|
private final Prov<GenerateFilter>[] filterTypes = new Prov[]{
|
||||||
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
|
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
|
||||||
RiverNoiseFilter::new, OreFilter::new, OreMedianFilter::new, MedianFilter::new,
|
RiverNoiseFilter::new, OreFilter::new, OreMedianFilter::new, MedianFilter::new,
|
||||||
BlendFilter::new, MirrorFilter::new, ClearFilter::new
|
BlendFilter::new, MirrorFilter::new, ClearFilter::new, CoreSpawnFilter::new, EnemySpawnFilter::new
|
||||||
};
|
};
|
||||||
private final MapEditor editor;
|
private final MapEditor editor;
|
||||||
private final boolean applied;
|
private final boolean applied;
|
||||||
@@ -263,7 +263,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
//all the options
|
//all the options
|
||||||
c.table(f -> {
|
c.table(f -> {
|
||||||
f.left().top();
|
f.left().top();
|
||||||
for(FilterOption option : filter.options){
|
for(FilterOption option : filter.options()){
|
||||||
option.changed = this::update;
|
option.changed = this::update;
|
||||||
|
|
||||||
f.table(t -> {
|
f.table(t -> {
|
||||||
@@ -292,7 +292,7 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
for(Prov<GenerateFilter> gen : filterTypes){
|
for(Prov<GenerateFilter> gen : filterTypes){
|
||||||
GenerateFilter filter = gen.get();
|
GenerateFilter filter = gen.get();
|
||||||
|
|
||||||
if(!applied && filter.buffered) continue;
|
if((!applied && filter.isBuffered()) || (filter.isPost() && applied)) continue;
|
||||||
|
|
||||||
selection.cont.addButton(filter.name(), () -> {
|
selection.cont.addButton(filter.name(), () -> {
|
||||||
filters.add(filter);
|
filters.add(filter);
|
||||||
@@ -360,21 +360,17 @@ public class MapGenerateDialog extends FloatingDialog{
|
|||||||
|
|
||||||
for(GenerateFilter filter : copy){
|
for(GenerateFilter filter : copy){
|
||||||
input.begin(filter, editor.width(), editor.height(), (x, y) -> buffer1[Mathf.clamp(x / scaling, 0, pixmap.getWidth()-1)][Mathf.clamp(y / scaling, 0, pixmap.getHeight()-1)].tile());
|
input.begin(filter, editor.width(), editor.height(), (x, y) -> buffer1[Mathf.clamp(x / scaling, 0, pixmap.getWidth()-1)][Mathf.clamp(y / scaling, 0, pixmap.getHeight()-1)].tile());
|
||||||
|
|
||||||
//read from buffer1 and write to buffer2
|
//read from buffer1 and write to buffer2
|
||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
pixmap.each((px, py) -> {
|
||||||
for(int py = 0; py < pixmap.getHeight(); py++){
|
int x = px * scaling, y = py * scaling;
|
||||||
int x = px * scaling, y = py * scaling;
|
GenTile tile = buffer1[px][py];
|
||||||
GenTile tile = buffer1[px][py];
|
input.apply(x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
|
||||||
input.apply(x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
|
filter.apply(input);
|
||||||
filter.apply(input);
|
buffer2[px][py].set(input.floor, input.block, input.ore, Team.get(tile.team), tile.rotation);
|
||||||
buffer2[px][py].set(input.floor, input.block, input.ore, Team.get(tile.team), tile.rotation);
|
});
|
||||||
}
|
|
||||||
}
|
pixmap.each((px, py) -> buffer1[px][py].set(buffer2[px][py]));
|
||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
|
||||||
for(int py = 0; py < pixmap.getHeight(); py++){
|
|
||||||
buffer1[px][py].set(buffer2[px][py]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int px = 0; px < pixmap.getWidth(); px++){
|
for(int px = 0; px < pixmap.getWidth(); px++){
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class MapRenderer implements Disposable{
|
|||||||
private void render(int wx, int wy){
|
private void render(int wx, int wy){
|
||||||
int x = wx / chunkSize, y = wy / chunkSize;
|
int x = wx / chunkSize, y = wy / chunkSize;
|
||||||
IndexedRenderer mesh = chunks[x][y];
|
IndexedRenderer mesh = chunks[x][y];
|
||||||
Tile tile = editor.tiles()[wx][wy];
|
Tile tile = editor.tiles().getn(wx, wy);
|
||||||
|
|
||||||
Team team = tile.getTeam();
|
Team team = tile.getTeam();
|
||||||
Block floor = tile.floor();
|
Block floor = tile.floor();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.entities;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
/** Marks something as saveable; not necessarily used for entities. */
|
||||||
public interface Saveable{
|
public interface Saveable{
|
||||||
void writeSave(DataOutput stream) throws IOException;
|
void writeSave(DataOutput stream) throws IOException;
|
||||||
void readSave(DataInput stream, byte version) throws IOException;
|
void readSave(DataInput stream, byte version) throws IOException;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class MusicControl{
|
|||||||
public void update(){
|
public void update(){
|
||||||
if(state.is(State.menu)){
|
if(state.is(State.menu)){
|
||||||
silenced = false;
|
silenced = false;
|
||||||
if(ui.deploy.isShown()){
|
if(ui.planet.isShown()){
|
||||||
play(Musics.launch);
|
play(Musics.launch);
|
||||||
}else if(ui.editor.isShown()){
|
}else if(ui.editor.isShown()){
|
||||||
play(Musics.editor);
|
play(Musics.editor);
|
||||||
|
|||||||
@@ -31,6 +31,17 @@ public enum CacheLayer{
|
|||||||
endShader(Shaders.tar);
|
endShader(Shaders.tar);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
slag{
|
||||||
|
@Override
|
||||||
|
public void begin(){
|
||||||
|
beginShader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void end(){
|
||||||
|
endShader(Shaders.slag);
|
||||||
|
}
|
||||||
|
},
|
||||||
normal,
|
normal,
|
||||||
walls;
|
walls;
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class MenuRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generate(){
|
private void generate(){
|
||||||
Tile[][] tiles = world.createTiles(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
Array<Block> ores = content.blocks().select(b -> b instanceof OreBlock);
|
Array<Block> ores = content.blocks().select(b -> b instanceof OreBlock);
|
||||||
shadows = new FrameBuffer(width, height);
|
shadows = new FrameBuffer(width, height);
|
||||||
int offset = Mathf.random(100000);
|
int offset = Mathf.random(100000);
|
||||||
@@ -154,10 +154,10 @@ public class MenuRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tile tile;
|
Tile tile;
|
||||||
tiles[x][y] = (tile = new CachedTile());
|
tiles.set(x, y, (tile = new CachedTile()));
|
||||||
tile.x = (short)x;
|
tile.x = (short)x;
|
||||||
tile.y = (short)y;
|
tile.y = (short)y;
|
||||||
tile.setFloor((Floor) floor);
|
tile.setFloor(floor.asFloor());
|
||||||
tile.setBlock(wall);
|
tile.setBlock(wall);
|
||||||
tile.setOverlay(ore);
|
tile.setOverlay(ore);
|
||||||
}
|
}
|
||||||
|
|||||||
266
core/src/mindustry/graphics/PlanetGrid.java
Normal file
266
core/src/mindustry/graphics/PlanetGrid.java
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
package mindustry.graphics;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.util.*;
|
||||||
|
|
||||||
|
//TODO clean this up somehow
|
||||||
|
public class PlanetGrid{
|
||||||
|
private static final PlanetGrid[] cache = new PlanetGrid[10];
|
||||||
|
|
||||||
|
private static final float x = -0.525731112119133606f;
|
||||||
|
private static final float z = -0.850650808352039932f;
|
||||||
|
|
||||||
|
private static final Vec3[] iTiles = {
|
||||||
|
new Vec3(-x, 0, z), new Vec3(x, 0, z), new Vec3(-x, 0, -z), new Vec3(x, 0, -z),
|
||||||
|
new Vec3(0, z, x), new Vec3(0, z, -x), new Vec3(0, -z, x), new Vec3(0, -z, -x),
|
||||||
|
new Vec3(z, x, 0), new Vec3(-z, x, 0), new Vec3(z, -x, 0), new Vec3(-z, -x, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] iTilesP = {
|
||||||
|
{9, 4, 1, 6, 11}, {4, 8, 10, 6, 0}, {11, 7, 3, 5, 9}, {2, 7, 10, 8, 5},
|
||||||
|
{9, 5, 8, 1, 0}, {2, 3, 8, 4, 9}, {0, 1, 10, 7, 11}, {11, 6, 10, 3, 2},
|
||||||
|
{5, 3, 10, 1, 4}, {2, 5, 4, 0, 11}, {3, 7, 6, 1, 8}, {7, 2, 9, 0, 6}
|
||||||
|
};
|
||||||
|
|
||||||
|
public final int size;
|
||||||
|
public final Ptile[] tiles;
|
||||||
|
public final Corner[] corners;
|
||||||
|
public final Edge[] edges;
|
||||||
|
|
||||||
|
PlanetGrid(int size){
|
||||||
|
this.size = size;
|
||||||
|
|
||||||
|
tiles = new Ptile[tileCount(size)];
|
||||||
|
for(int i = 0; i < tiles.length; i++){
|
||||||
|
tiles[i] = new Ptile(i, i < 12 ? 5 : 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
corners = new Corner[cornerCount(size)];
|
||||||
|
for(int i = 0; i < corners.length; i++){
|
||||||
|
corners[i] = new Corner(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
edges = new Edge[edgeCount(size)];
|
||||||
|
for(int i = 0; i < edges.length; i++){
|
||||||
|
edges[i] = new Edge(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlanetGrid newGrid(int size){
|
||||||
|
//cache grids between calls, since only ~5 different grids total are needed
|
||||||
|
if(size < cache.length && cache[size] != null){
|
||||||
|
return cache[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
PlanetGrid result;
|
||||||
|
if(size == 0){
|
||||||
|
result = initialGrid();
|
||||||
|
}else{
|
||||||
|
result = subdividedGrid(newGrid(size - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
//store grid in cache
|
||||||
|
if(size < cache.length){
|
||||||
|
cache[size] = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PlanetGrid initialGrid(){
|
||||||
|
PlanetGrid grid = new PlanetGrid(0);
|
||||||
|
|
||||||
|
for(Ptile t : grid.tiles){
|
||||||
|
t.v = iTiles[t.id];
|
||||||
|
for(int k = 0; k < 5; k++){
|
||||||
|
t.tiles[k] = grid.tiles[iTilesP[t.id][k]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 5; i++){
|
||||||
|
addCorner(i, grid, 0, iTilesP[0][(i + 4) % 5], iTilesP[0][i]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 5; i++){
|
||||||
|
addCorner(i + 5, grid, 3, iTilesP[3][(i + 4) % 5], iTilesP[3][i]);
|
||||||
|
}
|
||||||
|
addCorner(10, grid, 10, 1, 8);
|
||||||
|
addCorner(11, grid, 1, 10, 6);
|
||||||
|
addCorner(12, grid, 6, 10, 7);
|
||||||
|
addCorner(13, grid, 6, 7, 11);
|
||||||
|
addCorner(14, grid, 11, 7, 2);
|
||||||
|
addCorner(15, grid, 11, 2, 9);
|
||||||
|
addCorner(16, grid, 9, 2, 5);
|
||||||
|
addCorner(17, grid, 9, 5, 4);
|
||||||
|
addCorner(18, grid, 4, 5, 8);
|
||||||
|
addCorner(19, grid, 4, 8, 1);
|
||||||
|
|
||||||
|
//add corners to corners
|
||||||
|
for(Corner c : grid.corners){
|
||||||
|
for(int k = 0; k < 3; k++){
|
||||||
|
c.corners[k] = c.tiles[k].corners[(pos(c.tiles[k], c) + 1) % 5];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//new edges
|
||||||
|
int nextEdge = 0;
|
||||||
|
for(Ptile t : grid.tiles){
|
||||||
|
for(int k = 0; k < 5; k++){
|
||||||
|
if(t.edges[k] == null){
|
||||||
|
addEdge(nextEdge++, grid, t.id, iTilesP[t.id][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PlanetGrid subdividedGrid(PlanetGrid prev){
|
||||||
|
PlanetGrid grid = new PlanetGrid(prev.size + 1);
|
||||||
|
|
||||||
|
int prevTiles = prev.tiles.length;
|
||||||
|
int prevCorners = prev.corners.length;
|
||||||
|
|
||||||
|
//old tiles
|
||||||
|
for(int i = 0; i < prevTiles; i++){
|
||||||
|
grid.tiles[i].v = prev.tiles[i].v;
|
||||||
|
for(int k = 0; k < grid.tiles[i].edgeCount; k++){
|
||||||
|
|
||||||
|
grid.tiles[i].tiles[k] = grid.tiles[prev.tiles[i].corners[k].id + prevTiles];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//old corners become tiles
|
||||||
|
for(int i = 0; i < prevCorners; i++){
|
||||||
|
grid.tiles[i + prevTiles].v = prev.corners[i].v;
|
||||||
|
for(int k = 0; k < 3; k++){
|
||||||
|
grid.tiles[i + prevTiles].tiles[2 * k] = grid.tiles[prev.corners[i].corners[k].id + prevTiles];
|
||||||
|
grid.tiles[i + prevTiles].tiles[2 * k + 1] = grid.tiles[prev.corners[i].tiles[k].id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//new corners
|
||||||
|
int nextCorner = 0;
|
||||||
|
for(Ptile n : prev.tiles){
|
||||||
|
Ptile t = grid.tiles[n.id];
|
||||||
|
for(int k = 0; k < t.edgeCount; k++){
|
||||||
|
addCorner(nextCorner, grid, t.id, t.tiles[(k + t.edgeCount - 1) % t.edgeCount].id, t.tiles[k].id);
|
||||||
|
nextCorner++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//connect corners
|
||||||
|
for(Corner c : grid.corners){
|
||||||
|
for(int k = 0; k < 3; k++){
|
||||||
|
c.corners[k] = c.tiles[k].corners[(pos(c.tiles[k], c) + 1) % (c.tiles[k].edgeCount)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//new edges
|
||||||
|
int nextEdge = 0;
|
||||||
|
for(Ptile t : grid.tiles){
|
||||||
|
for(int k = 0; k < t.edgeCount; k++){
|
||||||
|
if(t.edges[k] == null){
|
||||||
|
addEdge(nextEdge, grid, t.id, t.tiles[k].id);
|
||||||
|
nextEdge++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addCorner(int id, PlanetGrid grid, int t1, int t2, int t3){
|
||||||
|
Corner c = grid.corners[id];
|
||||||
|
Ptile[] t = {grid.tiles[t1], grid.tiles[t2], grid.tiles[t3]};
|
||||||
|
c.v = Tmp.v31.set(t[0].v).add(t[1].v).add(t[2].v).cpy().nor();
|
||||||
|
for(int i = 0; i < 3; i++){
|
||||||
|
t[i].corners[pos(t[i], t[(i + 2) % 3])] = c;
|
||||||
|
c.tiles[i] = t[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addEdge(int id, PlanetGrid grid, int t1, int t2){
|
||||||
|
Edge e = grid.edges[id];
|
||||||
|
Ptile[] t = {grid.tiles[t1], grid.tiles[t2]};
|
||||||
|
Corner[] c = {
|
||||||
|
grid.corners[t[0].corners[pos(t[0], t[1])].id],
|
||||||
|
grid.corners[t[0].corners[(pos(t[0], t[1]) + 1) % t[0].edgeCount].id]};
|
||||||
|
for(int i = 0; i < 2; i++){
|
||||||
|
t[i].edges[pos(t[i], t[(i + 1) % 2])] = e;
|
||||||
|
e.tiles[i] = t[i];
|
||||||
|
c[i].edges[pos(c[i], c[(i + 1) % 2])] = e;
|
||||||
|
e.corners[i] = c[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pos(Ptile t, Ptile n){
|
||||||
|
for(int i = 0; i < t.edgeCount; i++)
|
||||||
|
if(t.tiles[i] == n)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pos(Ptile t, Corner c){
|
||||||
|
for(int i = 0; i < t.edgeCount; i++)
|
||||||
|
if(t.corners[i] == c)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pos(Corner c, Corner n){
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(c.corners[i] == n)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tileCount(int size){
|
||||||
|
return 10 * Mathf.pow(3, size) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cornerCount(int size){
|
||||||
|
return 20 * Mathf.pow(3, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int edgeCount(int size){
|
||||||
|
return 30 * Mathf.pow(3, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Ptile{
|
||||||
|
public final int id;
|
||||||
|
public final int edgeCount;
|
||||||
|
|
||||||
|
public final Ptile[] tiles;
|
||||||
|
public final Corner[] corners;
|
||||||
|
public final Edge[] edges;
|
||||||
|
|
||||||
|
public Vec3 v = new Vec3();
|
||||||
|
|
||||||
|
public Ptile(int id, int edgeCount){
|
||||||
|
this.id = id;
|
||||||
|
this.edgeCount = edgeCount;
|
||||||
|
|
||||||
|
tiles = new Ptile[edgeCount];
|
||||||
|
corners = new Corner[edgeCount];
|
||||||
|
edges = new Edge[edgeCount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Corner{
|
||||||
|
public final int id;
|
||||||
|
public final Ptile[] tiles = new Ptile[3];
|
||||||
|
public final Corner[] corners = new Corner[3];
|
||||||
|
public final Edge[] edges = new Edge[3];
|
||||||
|
|
||||||
|
public Vec3 v = new Vec3();
|
||||||
|
public Vec3 bv = new Vec3();
|
||||||
|
|
||||||
|
public Corner(int id){
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Edge{
|
||||||
|
public final int id;
|
||||||
|
public final Ptile[] tiles = new Ptile[2];
|
||||||
|
public final Corner[] corners = new Corner[2];
|
||||||
|
|
||||||
|
public Edge(int id){
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
140
core/src/mindustry/graphics/PlanetMesh.java
Normal file
140
core/src/mindustry/graphics/PlanetMesh.java
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package mindustry.graphics;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.VertexAttributes.*;
|
||||||
|
import arc.graphics.gl.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.graphics.PlanetGrid.*;
|
||||||
|
import mindustry.maps.planet.*;
|
||||||
|
|
||||||
|
public class PlanetMesh{
|
||||||
|
private float[] floats = new float[3 + 3 + 1];
|
||||||
|
private Vec3 vec = new Vec3();
|
||||||
|
private Mesh mesh;
|
||||||
|
private PlanetGrid grid;
|
||||||
|
private Vec3 center = new Vec3();
|
||||||
|
|
||||||
|
private boolean lines;
|
||||||
|
private float radius, intensity = 0.2f;
|
||||||
|
|
||||||
|
private final PlanetGenerator gen;
|
||||||
|
|
||||||
|
public PlanetMesh(int divisions, PlanetGenerator gen){
|
||||||
|
this(divisions, gen, 1f, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlanetMesh(int divisions, PlanetGenerator gen, float radius, boolean lines){
|
||||||
|
this.gen = gen;
|
||||||
|
this.radius = radius;
|
||||||
|
this.grid = PlanetGrid.newGrid(divisions);
|
||||||
|
this.lines = lines;
|
||||||
|
|
||||||
|
int vertices = grid.tiles.length * 12 * (3 + 3 + 1);
|
||||||
|
|
||||||
|
mesh = new Mesh(true, vertices, 0,
|
||||||
|
new VertexAttribute(Usage.position, 3, Shader.positionAttribute),
|
||||||
|
new VertexAttribute(Usage.normal, 3, Shader.normalAttribute),
|
||||||
|
new VertexAttribute(Usage.colorPacked, 4, Shader.colorAttribute));
|
||||||
|
|
||||||
|
mesh.getVerticesBuffer().limit(mesh.getMaxVertices());
|
||||||
|
mesh.getVerticesBuffer().position(0);
|
||||||
|
|
||||||
|
generateMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return the sector that is hit by this ray, or null if nothing intersects it. */
|
||||||
|
public @Nullable Ptile getTile(Ray ray){
|
||||||
|
boolean found = Intersector3D.intersectRaySphere(ray, center, radius, Tmp.v33);
|
||||||
|
if(!found) return null;
|
||||||
|
return Structs.findMin(grid.tiles, t -> t.v.dst(Tmp.v33));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(Mat3D mat){
|
||||||
|
Shaders.planet.begin();
|
||||||
|
Shaders.planet.setUniformMatrix4("u_projModelView", mat.val);
|
||||||
|
mesh.render(Shaders.planet, lines ? Gl.lines : Gl.triangles);
|
||||||
|
Shaders.planet.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateMesh(){
|
||||||
|
|
||||||
|
for(Ptile tile : grid.tiles){
|
||||||
|
|
||||||
|
Vec3 nor = Tmp.v31.setZero();
|
||||||
|
Corner[] c = tile.corners;
|
||||||
|
|
||||||
|
for(Corner corner : c){
|
||||||
|
corner.bv.set(corner.v).setLength(radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Corner corner : c){
|
||||||
|
corner.v.setLength(radius + elevation(corner.bv)*intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Corner corner : c){
|
||||||
|
nor.add(corner.v);
|
||||||
|
}
|
||||||
|
nor.nor();
|
||||||
|
|
||||||
|
Vec3 realNormal = normal(c[0].v, c[2].v, c[4].v);
|
||||||
|
nor.set(realNormal);
|
||||||
|
|
||||||
|
Color color = color(tile.v);
|
||||||
|
|
||||||
|
if(lines){
|
||||||
|
nor.set(1f, 1f, 1f);
|
||||||
|
|
||||||
|
for(int i = 0; i < c.length; i++){
|
||||||
|
Vec3 v1 = c[i].v;
|
||||||
|
Vec3 v2 = c[(i + 1) % c.length].v;
|
||||||
|
|
||||||
|
vert(v1, nor, color);
|
||||||
|
vert(v2, nor, color);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
verts(c[0].v, c[1].v, c[2].v, nor, color);
|
||||||
|
verts(c[0].v, c[2].v, c[3].v, nor, color);
|
||||||
|
verts(c[0].v, c[3].v, c[4].v, nor, color);
|
||||||
|
|
||||||
|
if(c.length > 5){
|
||||||
|
verts(c[0].v, c[4].v, c[5].v, nor, color);
|
||||||
|
}else{
|
||||||
|
verts(c[0].v, c[3].v, c[4].v, nor, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3){
|
||||||
|
return Tmp.v32.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float elevation(Vec3 v){
|
||||||
|
return gen.getHeight(vec.set(v).scl(1f / radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color color(Vec3 v){
|
||||||
|
return gen.getColor(vec.set(v).scl(1f / radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal, Color color){
|
||||||
|
vert(a, normal, color);
|
||||||
|
vert(b, normal, color);
|
||||||
|
vert(c, normal, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void vert(Vec3 a, Vec3 normal, Color color){
|
||||||
|
floats[0] = a.x;
|
||||||
|
floats[1] = a.y;
|
||||||
|
floats[2] = a.z;
|
||||||
|
|
||||||
|
floats[3] = normal.x;
|
||||||
|
floats[4] = normal.y;
|
||||||
|
floats[5] = normal.z;
|
||||||
|
|
||||||
|
floats[6] = color.toFloatBits();
|
||||||
|
mesh.getVerticesBuffer().put(floats);
|
||||||
|
}
|
||||||
|
}
|
||||||
123
core/src/mindustry/graphics/PlanetRenderer.java
Normal file
123
core/src/mindustry/graphics/PlanetRenderer.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package mindustry.graphics;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.graphics.g3d.*;
|
||||||
|
import arc.input.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.graphics.PlanetGrid.*;
|
||||||
|
import mindustry.maps.planet.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.type.Sector.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
public class PlanetRenderer implements PlanetGenerator{
|
||||||
|
private final Color outlineColor = Pal.accent.cpy().a(0.7f);
|
||||||
|
private final float camLength = 4f, outlineRad = 1.15f;
|
||||||
|
private final boolean drawnRect = true;
|
||||||
|
|
||||||
|
private final PlanetMesh[] outlines = new PlanetMesh[10];
|
||||||
|
private final Camera3D cam = new Camera3D();
|
||||||
|
private final VertexBatch3D batch = new VertexBatch3D(false, true, 0);
|
||||||
|
|
||||||
|
private float lastX, lastY;
|
||||||
|
|
||||||
|
public PlanetRenderer(){
|
||||||
|
Tmp.v1.trns(0, camLength);
|
||||||
|
cam.position.set(Tmp.v1.x, 0f, Tmp.v1.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(Planet planet){
|
||||||
|
Draw.flush();
|
||||||
|
Gl.clear(Gl.depthBufferBit);
|
||||||
|
Gl.enable(Gl.depthTest);
|
||||||
|
|
||||||
|
input();
|
||||||
|
|
||||||
|
cam.resize(Core.graphics.getWidth(), Core.graphics.getHeight());
|
||||||
|
cam.update();
|
||||||
|
cam.lookAt(0, 0, 0);
|
||||||
|
cam.update();
|
||||||
|
|
||||||
|
PlanetMesh outline = outline(planet.size);
|
||||||
|
|
||||||
|
planet.mesh.render(cam.combined());
|
||||||
|
outline.render(cam.combined());
|
||||||
|
|
||||||
|
Ptile tile = outline.getTile(cam.getPickRay(Core.input.mouseX(), Core.input.mouseY()));
|
||||||
|
if(tile != null){
|
||||||
|
|
||||||
|
Sector sector = planet.getSector(tile);
|
||||||
|
for(int i = 0; i < sector.tile.corners.length; i++){
|
||||||
|
batch.color(outlineColor);
|
||||||
|
batch.vertex(sector.tile.corners[i].v);
|
||||||
|
}
|
||||||
|
batch.flush(cam.combined(), Gl.triangleFan);
|
||||||
|
|
||||||
|
if(drawnRect){
|
||||||
|
//TODO hack.
|
||||||
|
SectorRect rect = sector.rect;
|
||||||
|
rect.center.scl(outlineRad);
|
||||||
|
rect.right.scl(outlineRad);
|
||||||
|
rect.top.scl(outlineRad);
|
||||||
|
|
||||||
|
batch.color(Pal.place);
|
||||||
|
batch.vertex(rect.project(0, 0));
|
||||||
|
batch.color(Pal.place);
|
||||||
|
batch.vertex(rect.project(1, 0));
|
||||||
|
batch.color(Pal.place);
|
||||||
|
batch.vertex(rect.project(1, 1));
|
||||||
|
batch.color(Pal.place);
|
||||||
|
batch.vertex(rect.project(0, 1));
|
||||||
|
batch.flush(cam.combined(), Gl.lineLoop);
|
||||||
|
|
||||||
|
rect.center.scl(1f / outlineRad);
|
||||||
|
rect.right.scl(1f / outlineRad);
|
||||||
|
rect.top.scl(1f / outlineRad);
|
||||||
|
|
||||||
|
if(Core.input.keyTap(KeyCode.SPACE)){
|
||||||
|
control.playSector(sector);
|
||||||
|
ui.planet.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gl.disable(Gl.depthTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlanetMesh outline(int size){
|
||||||
|
if(outlines[size] == null){
|
||||||
|
outlines[size] = new PlanetMesh(size, this, outlineRad, true);
|
||||||
|
}
|
||||||
|
return outlines[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void input(){
|
||||||
|
Vec3 v = Tmp.v33.set(Core.input.mouseX(), Core.input.mouseY(), 0);
|
||||||
|
|
||||||
|
if(Core.input.keyDown(KeyCode.MOUSE_LEFT)){
|
||||||
|
cam.position.rotate(Vec3.Y, (v.x - lastX) / 10);
|
||||||
|
}
|
||||||
|
lastX = v.x;
|
||||||
|
lastY = v.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getHeight(Vec3 position){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getColor(Vec3 position){
|
||||||
|
return outlineColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(Vec3 position, TileGen tile){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,13 +11,13 @@ import arc.util.Time;
|
|||||||
public class Shaders{
|
public class Shaders{
|
||||||
public static Shadow shadow;
|
public static Shadow shadow;
|
||||||
public static BlockBuild blockbuild;
|
public static BlockBuild blockbuild;
|
||||||
public static @Nullable
|
public static @Nullable Shield shield;
|
||||||
Shield shield;
|
|
||||||
public static UnitBuild build;
|
public static UnitBuild build;
|
||||||
public static FogShader fog;
|
public static FogShader fog;
|
||||||
public static MenuShader menu;
|
public static MenuShader menu;
|
||||||
public static LightShader light;
|
public static LightShader light;
|
||||||
public static SurfaceShader water, tar;
|
public static SurfaceShader water, tar, slag;
|
||||||
|
public static Shader planet;
|
||||||
|
|
||||||
public static void init(){
|
public static void init(){
|
||||||
shadow = new Shadow();
|
shadow = new Shadow();
|
||||||
@@ -35,6 +35,8 @@ public class Shaders{
|
|||||||
light = new LightShader();
|
light = new LightShader();
|
||||||
water = new SurfaceShader("water");
|
water = new SurfaceShader("water");
|
||||||
tar = new SurfaceShader("tar");
|
tar = new SurfaceShader("tar");
|
||||||
|
slag = new SurfaceShader("slag");
|
||||||
|
planet = new LoadShader("planet", "planet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LightShader extends LoadShader{
|
public static class LightShader extends LoadShader{
|
||||||
|
|||||||
@@ -133,11 +133,11 @@ public class MapIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pixmap generatePreview(Tile[][] tiles){
|
public static Pixmap generatePreview(Tiles tiles){
|
||||||
Pixmap pixmap = new Pixmap(tiles.length, tiles[0].length, Format.RGBA8888);
|
Pixmap pixmap = new Pixmap(tiles.width(), tiles.height(), Format.RGBA8888);
|
||||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
for(int y = 0; y < pixmap.getHeight(); y++){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
|
pixmap.draw(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,12 +152,12 @@ public class MapIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Reads a pixmap in the 3.5 pixmap format. */
|
/** Reads a pixmap in the 3.5 pixmap format. */
|
||||||
public static void readPixmap(Pixmap pixmap, Tile[][] tiles){
|
public static void readPixmap(Pixmap pixmap, Tiles tiles){
|
||||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
for(int y = 0; y < pixmap.getHeight(); y++){
|
||||||
int color = pixmap.getPixel(x, pixmap.getHeight() - 1 - y);
|
int color = pixmap.getPixel(x, pixmap.getHeight() - 1 - y);
|
||||||
LegacyBlock block = LegacyColorMapper.get(color);
|
LegacyBlock block = LegacyColorMapper.get(color);
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
|
|
||||||
tile.setFloor(block.floor);
|
tile.setFloor(block.floor);
|
||||||
tile.setBlock(block.wall);
|
tile.setBlock(block.wall);
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ public class Maps{
|
|||||||
|
|
||||||
for(int x = 0; x < map.width; x++){
|
for(int x = 0; x < map.width; x++){
|
||||||
for(int y = 0; y < map.height; y++){
|
for(int y = 0; y < map.height; y++){
|
||||||
Tile tile = world.getTiles()[x][y];
|
Tile tile = world.rawTile(x, y);
|
||||||
|
|
||||||
if(tile.block() instanceof CoreBlock){
|
if(tile.block() instanceof CoreBlock){
|
||||||
map.teams.add(tile.getTeamID());
|
map.teams.add(tile.getTeamID());
|
||||||
@@ -228,7 +228,7 @@ public class Maps{
|
|||||||
Core.assets.unload(map.previewFile().path() + "." + mapExtension);
|
Core.assets.unload(map.previewFile().path() + "." + mapExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pixmap pix = MapIO.generatePreview(world.getTiles());
|
Pixmap pix = MapIO.generatePreview(world.tiles);
|
||||||
executor.submit(() -> map.previewFile().writePNG(pix));
|
executor.submit(() -> map.previewFile().writePNG(pix));
|
||||||
writeCache(map);
|
writeCache(map);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.maps.filters.FilterOption.*;
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -11,16 +12,21 @@ public class BlendFilter extends GenerateFilter{
|
|||||||
float radius = 2f;
|
float radius = 2f;
|
||||||
Block block = Blocks.stone, floor = Blocks.ice, ignore = Blocks.air;
|
Block block = Blocks.stone, floor = Blocks.ice, ignore = Blocks.air;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 10f),
|
||||||
new BlockOption("block", () -> block, b -> block = b, anyOptional),
|
new BlockOption("block", () -> block, b -> block = b, anyOptional),
|
||||||
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly),
|
new BlockOption("floor", () -> floor, b -> floor = b, floorsOnly),
|
||||||
new BlockOption("ignore", () -> ignore, b -> ignore = b, floorsOptional)
|
new BlockOption("ignore", () -> ignore, b -> ignore = b, floorsOptional)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
if(in.floor == block || block == Blocks.air || in.floor == ignore) return;
|
if(in.floor == block || block == Blocks.air || in.floor == ignore) return;
|
||||||
@@ -31,7 +37,7 @@ public class BlendFilter extends GenerateFilter{
|
|||||||
outer:
|
outer:
|
||||||
for(int x = -rad; x <= rad; x++){
|
for(int x = -rad; x <= rad; x++){
|
||||||
for(int y = -rad; y <= rad; y++){
|
for(int y = -rad; y <= rad; y++){
|
||||||
if(Mathf.dst2(x, y) > rad*rad) continue;
|
if(Mathf.within(x, y, rad)) continue;
|
||||||
Tile tile = in.tile(in.x + x, in.y + y);
|
Tile tile = in.tile(in.x + x, in.y + y);
|
||||||
|
|
||||||
if(tile.floor() == block || tile.block() == block || tile.overlay() == block){
|
if(tile.floor() == block || tile.block() == block || tile.overlay() == block){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
@@ -8,10 +9,9 @@ import static mindustry.maps.filters.FilterOption.*;
|
|||||||
public class ClearFilter extends GenerateFilter{
|
public class ClearFilter extends GenerateFilter{
|
||||||
protected Block block = Blocks.air;
|
protected Block block = Blocks.air;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
new BlockOption("block", () -> block, b -> block = b, wallsOnly)
|
return Structs.arr(new BlockOption("block", () -> block, b -> block = b, wallsOnly));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
43
core/src/mindustry/maps/filters/CoreSpawnFilter.java
Normal file
43
core/src/mindustry/maps/filters/CoreSpawnFilter.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
/** Selects X spawns from the core spawn pool.*/
|
||||||
|
public class CoreSpawnFilter extends GenerateFilter{
|
||||||
|
int amount = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
|
new SliderOption("amount", () -> amount, f -> amount = (int)f, 1, 10).display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
|
IntArray spawns = new IntArray();
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
if(tile.getTeam() == state.rules.defaultTeam && tile.block() instanceof CoreBlock){
|
||||||
|
spawns.add(tile.pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawns.shuffle();
|
||||||
|
|
||||||
|
int used = Math.min(spawns.size, amount);
|
||||||
|
for(int i = used; i < spawns.size; i++){
|
||||||
|
tiles.getp(spawns.get(i)).remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPost(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.maps.filters.FilterOption.*;
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
@@ -7,14 +8,19 @@ import mindustry.world.blocks.*;
|
|||||||
public class DistortFilter extends GenerateFilter{
|
public class DistortFilter extends GenerateFilter{
|
||||||
float scl = 40, mag = 5;
|
float scl = 40, mag = 5;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 200f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 200f),
|
||||||
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 100f)
|
new SliderOption("mag", () -> mag, f -> mag = f, 0.5f, 100f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
Tile tile = in.tile(in.x + noise(in.x, in.y, scl, mag) - mag / 2f, in.y + noise(in.x, in.y + o, scl, mag) - mag / 2f);
|
Tile tile = in.tile(in.x + noise(in.x, in.y, scl, mag) - mag / 2f, in.y + noise(in.x, in.y + o, scl, mag) - mag / 2f);
|
||||||
|
|||||||
42
core/src/mindustry/maps/filters/EnemySpawnFilter.java
Normal file
42
core/src/mindustry/maps/filters/EnemySpawnFilter.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
/** Selects X spawns from the spawn pool.*/
|
||||||
|
public class EnemySpawnFilter extends GenerateFilter{
|
||||||
|
int amount = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
|
new SliderOption("amount", () -> amount, f -> amount = (int)f, 1, 10).display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
|
IntArray spawns = new IntArray();
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
if(tile.overlay() == Blocks.spawn){
|
||||||
|
spawns.add(tile.pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawns.shuffle();
|
||||||
|
|
||||||
|
int used = Math.min(spawns.size, amount);
|
||||||
|
for(int i = used; i < spawns.size; i++){
|
||||||
|
Tile tile = tiles.getp(spawns.get(i));
|
||||||
|
tile.clearOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPost(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,8 @@ public abstract class FilterOption{
|
|||||||
final Floatc setter;
|
final Floatc setter;
|
||||||
final float min, max, step;
|
final float min, max, step;
|
||||||
|
|
||||||
|
boolean display;
|
||||||
|
|
||||||
SliderOption(String name, Floatp getter, Floatc setter, float min, float max){
|
SliderOption(String name, Floatp getter, Floatc setter, float min, float max){
|
||||||
this(name, getter, setter, min, max, (max - min) / 200);
|
this(name, getter, setter, min, max, (max - min) / 200);
|
||||||
}
|
}
|
||||||
@@ -48,9 +50,18 @@ public abstract class FilterOption{
|
|||||||
this.step = step;
|
this.step = step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SliderOption display(){
|
||||||
|
display = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(Table table){
|
public void build(Table table){
|
||||||
table.add("$filter.option." + name);
|
if(!display){
|
||||||
|
table.add("$filter.option." + name);
|
||||||
|
}else{
|
||||||
|
table.label(() -> Core.bundle.get("filter.option." + name) + ": " + (int)getter.get());
|
||||||
|
}
|
||||||
table.row();
|
table.row();
|
||||||
Slider slider = table.addSlider(min, max, step, setter).growX().get();
|
Slider slider = table.addSlider(min, max, step, setter).growX().get();
|
||||||
slider.setValue(getter.get());
|
slider.setValue(getter.get());
|
||||||
|
|||||||
@@ -7,32 +7,37 @@ import arc.util.*;
|
|||||||
import arc.util.noise.*;
|
import arc.util.noise.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
|
||||||
|
|
||||||
public abstract class GenerateFilter{
|
public abstract class GenerateFilter{
|
||||||
protected transient float o = (float)(Math.random() * 10000000.0);
|
protected transient float o = (float)(Math.random() * 10000000.0);
|
||||||
protected transient long seed;
|
protected transient long seed;
|
||||||
protected transient GenerateInput in;
|
protected transient GenerateInput in;
|
||||||
|
|
||||||
public transient boolean buffered = false;
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
public transient FilterOption[] options;
|
this.in = in;
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
in.apply(tile.x, tile.y, tile.floor(), tile.block(), tile.overlay());
|
||||||
|
apply();
|
||||||
|
|
||||||
|
tile.setFloor(in.floor.asFloor());
|
||||||
|
tile.setOverlay(in.floor.asFloor().isLiquid ? Blocks.air : in.ore);
|
||||||
|
|
||||||
|
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||||
|
tile.setBlock(in.block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final void apply(GenerateInput in){
|
public final void apply(GenerateInput in){
|
||||||
this.in = in;
|
this.in = in;
|
||||||
apply();
|
apply();
|
||||||
//remove extra ores on liquids
|
|
||||||
if(((Floor)in.floor).isLiquid){
|
|
||||||
in.ore = Blocks.air;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** sets up the options; this is necessary since the constructor can't access subclass variables. */
|
/** @return a new array of options for configuring this filter */
|
||||||
protected void options(FilterOption... options){
|
public abstract FilterOption[] options();
|
||||||
this.options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** apply the actual filter on the input */
|
/** apply the actual filter on the input */
|
||||||
protected abstract void apply();
|
protected void apply(){}
|
||||||
|
|
||||||
/** draw any additional guides */
|
/** draw any additional guides */
|
||||||
public void draw(Image image){}
|
public void draw(Image image){}
|
||||||
@@ -47,6 +52,16 @@ public abstract class GenerateFilter{
|
|||||||
seed = Mathf.random(99999999);
|
seed = Mathf.random(99999999);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether this filter needs a read/write buffer (e.g. not a 1:1 tile mapping). */
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether this filter can *only* be used while generating the map, e.g. is not undoable. */
|
||||||
|
public boolean isPost(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//utility generation functions
|
//utility generation functions
|
||||||
|
|
||||||
protected float noise(float x, float y, float scl, float mag){
|
protected float noise(float x, float y, float scl, float mag){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.maps.filters;
|
|||||||
|
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.maps.filters.FilterOption.*;
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
@@ -12,14 +13,19 @@ public class MedianFilter extends GenerateFilter{
|
|||||||
float percentile = 0.5f;
|
float percentile = 0.5f;
|
||||||
IntArray blocks = new IntArray(), floors = new IntArray();
|
IntArray blocks = new IntArray(), floors = new IntArray();
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
||||||
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
int rad = (int)radius;
|
int rad = (int)radius;
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ public class MirrorFilter extends GenerateFilter{
|
|||||||
|
|
||||||
int angle = 45;
|
int angle = 45;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(new SliderOption("angle", () -> angle, f -> angle = (int)f, 0, 360, 45));
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
|
new SliderOption("angle", () -> angle, f -> angle = (int)f, 0, 360, 45)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.maps.filters.FilterOption.BlockOption;
|
import mindustry.maps.filters.FilterOption.BlockOption;
|
||||||
import mindustry.maps.filters.FilterOption.SliderOption;
|
import mindustry.maps.filters.FilterOption.SliderOption;
|
||||||
@@ -12,8 +13,9 @@ public class NoiseFilter extends GenerateFilter{
|
|||||||
float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f;
|
float scl = 40, threshold = 0.5f, octaves = 3f, falloff = 0.5f;
|
||||||
Block floor = Blocks.stone, block = Blocks.rocks;
|
Block floor = Blocks.stone, block = Blocks.rocks;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.maps.filters.FilterOption.SliderOption;
|
import mindustry.maps.filters.FilterOption.SliderOption;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.Block;
|
||||||
@@ -11,13 +12,14 @@ public class OreFilter extends GenerateFilter{
|
|||||||
public float scl = 23, threshold = 0.81f, octaves = 2f, falloff = 0.3f;
|
public float scl = 23, threshold = 0.81f, octaves = 2f, falloff = 0.3f;
|
||||||
public Block ore = Blocks.oreCopper;
|
public Block ore = Blocks.oreCopper;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
return Structs.arr(
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f),
|
new SliderOption("octaves", () -> octaves, f -> octaves = f, 1f, 10f),
|
||||||
new BlockOption("ore", () -> ore, b -> ore = b, oresOnly)
|
new SliderOption("falloff", () -> falloff, f -> falloff = f, 0f, 1f),
|
||||||
|
new BlockOption("ore", () -> ore, b -> ore = b, oresOnly)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.maps.filters;
|
|||||||
|
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.maps.filters.FilterOption.*;
|
import mindustry.maps.filters.FilterOption.*;
|
||||||
@@ -13,14 +14,19 @@ public class OreMedianFilter extends GenerateFilter{
|
|||||||
|
|
||||||
private IntArray blocks = new IntArray();
|
private IntArray blocks = new IntArray();
|
||||||
|
|
||||||
{
|
@Override
|
||||||
buffered = true;
|
public FilterOption[] options(){
|
||||||
options(
|
return Structs.arr(
|
||||||
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
new SliderOption("radius", () -> radius, f -> radius = f, 1f, 12f),
|
||||||
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
new SliderOption("percentile", () -> percentile, f -> percentile = f, 0f, 1f)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuffered(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
if(in.ore == Blocks.spawn) return;
|
if(in.ore == Blocks.spawn) return;
|
||||||
|
|||||||
35
core/src/mindustry/maps/filters/RandomItemFilter.java
Normal file
35
core/src/mindustry/maps/filters/RandomItemFilter.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
|
public class RandomItemFilter extends GenerateFilter{
|
||||||
|
public Array<ItemStack> drops = new Array<>();
|
||||||
|
public float chance = 0.3f;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterOption[] options(){
|
||||||
|
return new FilterOption[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Tiles tiles, GenerateInput in){
|
||||||
|
for(Tile tile : tiles){
|
||||||
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock)){
|
||||||
|
for(ItemStack stack : drops){
|
||||||
|
if(Mathf.chance(chance)){
|
||||||
|
tile.entity.items.add(stack.item, Math.min(Mathf.random(stack.amount), tile.block().itemCapacity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPost(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.maps.filters.FilterOption.BlockOption;
|
import mindustry.maps.filters.FilterOption.BlockOption;
|
||||||
import mindustry.maps.filters.FilterOption.SliderOption;
|
import mindustry.maps.filters.FilterOption.SliderOption;
|
||||||
@@ -12,8 +13,9 @@ public class RiverNoiseFilter extends GenerateFilter{
|
|||||||
float scl = 40, threshold = 0f, threshold2 = 0.1f;
|
float scl = 40, threshold = 0f, threshold2 = 0.1f;
|
||||||
Block floor = Blocks.water, floor2 = Blocks.deepwater, block = Blocks.sandRocks;
|
Block floor = Blocks.water, floor2 = Blocks.deepwater, block = Blocks.sandRocks;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, -1f, 0.3f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, -1f, 0.3f),
|
||||||
new SliderOption("threshold2", () -> threshold2, f -> threshold2 = f, -1f, 0.3f),
|
new SliderOption("threshold2", () -> threshold2, f -> threshold2 = f, -1f, 0.3f),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.maps.filters.FilterOption.BlockOption;
|
import mindustry.maps.filters.FilterOption.BlockOption;
|
||||||
import mindustry.maps.filters.FilterOption.SliderOption;
|
import mindustry.maps.filters.FilterOption.SliderOption;
|
||||||
@@ -11,8 +12,9 @@ public class ScatterFilter extends GenerateFilter{
|
|||||||
protected float chance = 0.014f;
|
protected float chance = 0.014f;
|
||||||
protected Block flooronto = Blocks.air, floor = Blocks.air, block = Blocks.air;
|
protected Block flooronto = Blocks.air, floor = Blocks.air, block = Blocks.air;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("chance", () -> chance, f -> chance = f, 0f, 1f),
|
new SliderOption("chance", () -> chance, f -> chance = f, 0f, 1f),
|
||||||
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOptional),
|
new BlockOption("flooronto", () -> flooronto, b -> flooronto = b, floorsOptional),
|
||||||
new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional),
|
new BlockOption("floor", () -> floor, b -> floor = b, floorsOptional),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.maps.filters;
|
package mindustry.maps.filters;
|
||||||
|
|
||||||
import arc.math.Mathf;
|
import arc.math.Mathf;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.maps.filters.FilterOption.BlockOption;
|
import mindustry.maps.filters.FilterOption.BlockOption;
|
||||||
import mindustry.maps.filters.FilterOption.SliderOption;
|
import mindustry.maps.filters.FilterOption.SliderOption;
|
||||||
@@ -13,8 +14,9 @@ public class TerrainFilter extends GenerateFilter{
|
|||||||
float scl = 40, threshold = 0.9f, octaves = 3f, falloff = 0.5f, magnitude = 1f, circleScl = 2.1f;
|
float scl = 40, threshold = 0.9f, octaves = 3f, falloff = 0.5f, magnitude = 1f, circleScl = 2.1f;
|
||||||
Block floor = Blocks.stone, block = Blocks.rocks;
|
Block floor = Blocks.stone, block = Blocks.rocks;
|
||||||
|
|
||||||
{
|
@Override
|
||||||
options(
|
public FilterOption[] options(){
|
||||||
|
return Structs.arr(
|
||||||
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
new SliderOption("scale", () -> scl, f -> scl = f, 1f, 500f),
|
||||||
new SliderOption("mag", () -> magnitude, f -> magnitude = f, 0f, 2f),
|
new SliderOption("mag", () -> magnitude, f -> magnitude = f, 0f, 2f),
|
||||||
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
new SliderOption("threshold", () -> threshold, f -> threshold = f, 0f, 1f),
|
||||||
|
|||||||
4
core/src/mindustry/maps/generators/BaseGenerator.java
Normal file
4
core/src/mindustry/maps/generators/BaseGenerator.java
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package mindustry.maps.generators;
|
||||||
|
|
||||||
|
public class BaseGenerator{
|
||||||
|
}
|
||||||
@@ -26,14 +26,14 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tiles tiles){
|
||||||
int seed = Mathf.random(99999999);
|
int seed = Mathf.random(99999999);
|
||||||
sim.setSeed(seed);
|
sim.setSeed(seed);
|
||||||
sim2.setSeed(seed + 1);
|
sim2.setSeed(seed + 1);
|
||||||
super.generate(tiles);
|
super.generate(tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ores(Tile[][] tiles){
|
public void ores(Tiles tiles){
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(ores != null){
|
if(ores != null){
|
||||||
int offsetX = x - 4, offsetY = y + 23;
|
int offsetX = x - 4, offsetY = y + 23;
|
||||||
@@ -49,7 +49,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terrain(Tile[][] tiles, Block dst, float scl, float mag, float cmag){
|
public void terrain(Tiles tiles, Block dst, float scl, float mag, float cmag){
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
double rocks = sim.octaveNoise2D(5, 0.5, 1f / scl, x, y) * mag
|
double rocks = sim.octaveNoise2D(5, 0.5, 1f / scl, x, y) * mag
|
||||||
+ Mathf.dst((float)x / width, (float)y / height, 0.5f, 0.5f) * cmag;
|
+ Mathf.dst((float)x / width, (float)y / height, 0.5f, 0.5f) * cmag;
|
||||||
@@ -66,11 +66,11 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void noise(Tile[][] tiles, Block floor, Block block, int octaves, float falloff, float scl, float threshold){
|
public void noise(Tiles tiles, Block floor, Block block, int octaves, float falloff, float scl, float threshold){
|
||||||
sim.setSeed(Mathf.random(99999));
|
sim.setSeed(Mathf.random(99999));
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold){
|
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
this.floor = floor;
|
this.floor = floor;
|
||||||
if(tile.block().solid){
|
if(tile.block().solid){
|
||||||
this.block = block;
|
this.block = block;
|
||||||
@@ -79,16 +79,16 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void overlay(Tile[][] tiles, Block floor, Block block, float chance, int octaves, float falloff, float scl, float threshold){
|
public void overlay(Tiles tiles, Block floor, Block block, float chance, int octaves, float falloff, float scl, float threshold){
|
||||||
sim.setSeed(Mathf.random(99999));
|
sim.setSeed(Mathf.random(99999));
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold && Mathf.chance(chance) && tiles[x][y].floor() == floor){
|
if(sim.octaveNoise2D(octaves, falloff, 1f / scl, x, y) > threshold && Mathf.chance(chance) && tiles.getn(x, y).floor() == floor){
|
||||||
ore = block;
|
ore = block;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tech(Tile[][] tiles){
|
public void tech(Tiles tiles){
|
||||||
Block[] blocks = {Blocks.darkPanel3};
|
Block[] blocks = {Blocks.darkPanel3};
|
||||||
int secSize = 20;
|
int secSize = 20;
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
@@ -109,13 +109,13 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void distort(Tile[][] tiles, float scl, float mag){
|
public void distort(Tiles tiles, float scl, float mag){
|
||||||
Block[][] blocks = new Block[width][height];
|
Block[][] blocks = new Block[width][height];
|
||||||
Floor[][] floors = new Floor[width][height];
|
Floor[][] floors = new Floor[width][height];
|
||||||
|
|
||||||
each((x, y) -> {
|
each((x, y) -> {
|
||||||
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x, y + 1525215f, scl, mag) - mag / 2f;
|
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x, y + 1525215f, scl, mag) - mag / 2f;
|
||||||
Tile other = tiles[Mathf.clamp((int)cx, 0, width-1)][Mathf.clamp((int)cy, 0, height-1)];
|
Tile other = tiles.getn(Mathf.clamp((int)cx, 0, width-1), Mathf.clamp((int)cy, 0, height-1));
|
||||||
blocks[x][y] = other.block();
|
blocks[x][y] = other.block();
|
||||||
floors[x][y] = other.floor();
|
floors[x][y] = other.floor();
|
||||||
});
|
});
|
||||||
@@ -126,7 +126,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scatter(Tile[][] tiles, Block target, Block dst, float chance){
|
public void scatter(Tiles tiles, Block target, Block dst, float chance){
|
||||||
pass(tiles, (x, y) -> {
|
pass(tiles, (x, y) -> {
|
||||||
if(!Mathf.chance(chance)) return;
|
if(!Mathf.chance(chance)) return;
|
||||||
if(floor == target){
|
if(floor == target){
|
||||||
@@ -149,40 +149,40 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
return (float)sim2.octaveNoise2D(1f, 0f, 1f / scl, x + 0x361266f, y + 0x251259f) * mag;
|
return (float)sim2.octaveNoise2D(1f, 0f, 1f / scl, x + 0x361266f, y + 0x251259f) * mag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pass(Tile[][] tiles, Intc2 r){
|
public void pass(Tiles tiles, Intc2 r){
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
floor = tiles[x][y].floor();
|
floor = tiles.getn(x, y).floor();
|
||||||
block = tiles[x][y].block();
|
block = tiles.getn(x, y).block();
|
||||||
ore = tiles[x][y].overlay();
|
ore = tiles.getn(x, y).overlay();
|
||||||
r.get(x, y);
|
r.get(x, y);
|
||||||
tiles[x][y] = new Tile(x, y, floor.id, ore.id, block.id);
|
tiles.set(x, y, new Tile(x, y, floor, ore, block));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void brush(Tile[][] tiles, Array<Tile> path, int rad){
|
public void brush(Tiles tiles, Array<Tile> path, int rad){
|
||||||
path.each(tile -> erase(tiles, tile.x, tile.y, rad));
|
path.each(tile -> erase(tiles, tile.x, tile.y, rad));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void erase(Tile[][] tiles, int cx, int cy, int rad){
|
public void erase(Tiles tiles, int cx, int cy, int rad){
|
||||||
for(int x = -rad; x <= rad; x++){
|
for(int x = -rad; x <= rad; x++){
|
||||||
for(int y = -rad; y <= rad; y++){
|
for(int y = -rad; y <= rad; y++){
|
||||||
int wx = cx + x, wy = cy + y;
|
int wx = cx + x, wy = cy + y;
|
||||||
if(Structs.inBounds(wx, wy, width, height) && Mathf.dst(x, y, 0, 0) <= rad){
|
if(Structs.inBounds(wx, wy, width, height) && Mathf.dst(x, y, 0, 0) <= rad){
|
||||||
Tile other = tiles[wx][wy];
|
Tile other = tiles.getn(wx, wy);
|
||||||
other.setBlock(Blocks.air);
|
other.setBlock(Blocks.air);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Array<Tile> pathfind(Tile[][] tiles, int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh){
|
public Array<Tile> pathfind(Tiles tiles, int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh){
|
||||||
Tile start = tiles[startX][startY];
|
Tile start = tiles.getn(startX, startY);
|
||||||
Tile end = tiles[endX][endY];
|
Tile end = tiles.getn(endX, endY);
|
||||||
GridBits closed = new GridBits(width, height);
|
GridBits closed = new GridBits(width, height);
|
||||||
IntFloatMap costs = new IntFloatMap();
|
IntFloatMap costs = new IntFloatMap();
|
||||||
PriorityQueue<Tile> queue = new PriorityQueue<>(tiles.length * tiles[0].length / 2, (a, b) -> Float.compare(costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y), costs.get(b.pos(), 0f) + dh.cost(b.x, b.y, end.x, end.y)));
|
PriorityQueue<Tile> queue = new PriorityQueue<>(tiles.width() * tiles.height()/4, (a, b) -> Float.compare(costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y), costs.get(b.pos(), 0f) + dh.cost(b.x, b.y, end.x, end.y)));
|
||||||
queue.add(start);
|
queue.add(start);
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
while(!queue.isEmpty()){
|
while(!queue.isEmpty()){
|
||||||
@@ -196,7 +196,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
int newx = next.x + point.x, newy = next.y + point.y;
|
int newx = next.x + point.x, newy = next.y + point.y;
|
||||||
if(Structs.inBounds(newx, newy, width, height)){
|
if(Structs.inBounds(newx, newy, width, height)){
|
||||||
Tile child = tiles[newx][newy];
|
Tile child = tiles.getn(newx, newy);
|
||||||
if(!closed.get(child.x, child.y)){
|
if(!closed.get(child.x, child.y)){
|
||||||
closed.set(child.x, child.y);
|
closed.set(child.x, child.y);
|
||||||
child.rotation(child.relativeTo(next.x, next.y));
|
child.rotation(child.relativeTo(next.x, next.y));
|
||||||
@@ -215,7 +215,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
while(current != start){
|
while(current != start){
|
||||||
out.add(current);
|
out.add(current);
|
||||||
Point2 p = Geometry.d4(current.rotation());
|
Point2 p = Geometry.d4(current.rotation());
|
||||||
current = tiles[current.x + p.x][current.y + p.y];
|
current = tiles.getn(current.x + p.x, current.y + p.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.reverse();
|
out.reverse();
|
||||||
@@ -223,17 +223,17 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inverseFloodFill(Tile[][] tiles, Tile start, Block block){
|
public void inverseFloodFill(Tiles tiles, Tile start, Block block){
|
||||||
IntArray arr = new IntArray();
|
IntArray arr = new IntArray();
|
||||||
arr.add(start.pos());
|
arr.add(start.pos());
|
||||||
while(!arr.isEmpty()){
|
while(!arr.isEmpty()){
|
||||||
int i = arr.pop();
|
int i = arr.pop();
|
||||||
int x = Pos.x(i), y = Pos.y(i);
|
int x = Pos.x(i), y = Pos.y(i);
|
||||||
tiles[x][y].cost = 2;
|
tiles.getn(x, y).cost = 2;
|
||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
int newx = x + point.x, newy = y + point.y;
|
int newx = x + point.x, newy = y + point.y;
|
||||||
if(Structs.inBounds(newx, newy, width, height)){
|
if(tiles.in(newx, newy)){
|
||||||
Tile child = tiles[newx][newy];
|
Tile child = tiles.getn(newx, newy);
|
||||||
if(child.block() == Blocks.air && child.cost != 2){
|
if(child.block() == Blocks.air && child.cost != 2){
|
||||||
child.cost = 2;
|
child.cost = 2;
|
||||||
arr.add(child.pos());
|
arr.add(child.pos());
|
||||||
@@ -244,7 +244,7 @@ public abstract class BasicGenerator extends RandomGenerator{
|
|||||||
|
|
||||||
for(int x = 0; x < width; x ++){
|
for(int x = 0; x < width; x ++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles.getn(x, y);
|
||||||
if(tile.cost != 2 && tile.block() == Blocks.air){
|
if(tile.cost != 2 && tile.block() == Blocks.air){
|
||||||
tile.setBlock(block);
|
tile.setBlock(block);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,5 @@ public abstract class Generator{
|
|||||||
this.loadout = loadout;
|
this.loadout = loadout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void generate(Tile[][] tiles);
|
public abstract void generate(Tiles tiles);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,33 @@
|
|||||||
package mindustry.maps.generators;
|
package mindustry.maps.generators;
|
||||||
|
|
||||||
import arc.struct.*;
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.maps.*;
|
import mindustry.maps.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
|
||||||
import mindustry.world.blocks.storage.*;
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
//- limited # of enemy spawns as filter
|
||||||
|
//- spawn loadout selection as filter
|
||||||
|
//- configure map loadout, make 1 core the default
|
||||||
public class MapGenerator extends Generator{
|
public class MapGenerator extends Generator{
|
||||||
private Map map;
|
private Map map;
|
||||||
private String mapName;
|
private String mapName;
|
||||||
private Array<Decoration> decorations = Array.with(new Decoration(Blocks.stone, Blocks.rock, 0.003f));
|
|
||||||
/**
|
|
||||||
* The amount of final enemy spawns used. -1 to use everything in the map.
|
|
||||||
* This amount of enemy spawns is selected randomly from the map.
|
|
||||||
*/
|
|
||||||
public int enemySpawns = -1;
|
|
||||||
/** Whether floor is distorted along with blocks. */
|
|
||||||
public boolean distortFloor = false;
|
|
||||||
|
|
||||||
public MapGenerator(String mapName){
|
public MapGenerator(String mapName){
|
||||||
this.mapName = mapName;
|
this.mapName = mapName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapGenerator(String mapName, int enemySpawns){
|
|
||||||
this.mapName = mapName;
|
|
||||||
this.enemySpawns = enemySpawns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapGenerator decor(Decoration... decor){
|
|
||||||
this.decorations.addAll(decor);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public void removePrefix(String name){
|
public void removePrefix(String name){
|
||||||
this.mapName = this.mapName.substring(name.length() + 1);
|
this.mapName = this.mapName.substring(name.length() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
decor(new Decoration(Blocks.snow, Blocks.snowrock, 0.01), new Decoration(Blocks.ignarock, Blocks.pebbles, 0.03f));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getMap(){
|
public Map getMap(){
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@@ -61,110 +41,44 @@ public class MapGenerator extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tiles tiles){
|
||||||
for(int x = 0; x < width; x++){
|
tiles.fill();
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
tiles[x][y] = new Tile(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveIO.load(map.file);
|
SaveIO.load(map.file);
|
||||||
Array<Point2> players = new Array<>();
|
|
||||||
Array<Point2> enemies = new Array<>();
|
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
for(Tile tile : tiles){
|
||||||
for(int y = 0; y < height; y++){
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && world.getZone() != null){
|
||||||
if(tiles[x][y].block() instanceof CoreBlock && tiles[x][y].getTeam() == state.rules.defaultTeam){
|
for(Item item : world.getZone().resources){
|
||||||
players.add(new Point2(x, y));
|
if(Mathf.chance(0.3)){
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
tile.entity.items().add(item, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
||||||
}
|
|
||||||
|
|
||||||
if(tiles[x][y].overlay() == Blocks.spawn && enemySpawns != -1){
|
|
||||||
enemies.add(new Point2(x, y));
|
|
||||||
tiles[x][y].setOverlay(Blocks.air);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tiles[x][y].block() instanceof BlockPart){
|
|
||||||
tiles[x][y].setBlock(Blocks.air);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int x = 0; x < width; x++){
|
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
|
|
||||||
for(Decoration decor : decorations){
|
|
||||||
if(x > 0 && y > 0 && (tiles[x - 1][y].block() == decor.wall || tiles[x][y - 1].block() == decor.wall)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.block() == Blocks.air && !(decor.wall instanceof Floor) && tile.floor() == decor.floor && Mathf.chance(decor.chance)){
|
|
||||||
tile.setBlock(decor.wall);
|
|
||||||
}else if(tile.floor() == decor.floor && decor.wall.isOverlay() && Mathf.chance(decor.chance)){
|
|
||||||
tile.setOverlay(decor.wall);
|
|
||||||
}else if(tile.floor() == decor.floor && decor.wall.isFloor() && !decor.wall.isOverlay() && Mathf.chance(decor.chance)){
|
|
||||||
tile.setFloor((Floor)decor.wall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && world.getZone() != null){
|
|
||||||
for(Item item : world.getZone().resources){
|
|
||||||
if(Mathf.chance(0.3)){
|
|
||||||
tile.entity.items().add(item, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enemySpawns != -1){
|
boolean anyCores = false;
|
||||||
if(enemySpawns > enemies.size){
|
|
||||||
throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number for map: " + mapName);
|
for(Tile tile : tiles){
|
||||||
|
if(tile.overlay() == Blocks.spawn){
|
||||||
|
int rad = 10;
|
||||||
|
Geometry.circle(tile.x, tile.y, tiles.width(), tiles.height(), rad, (wx, wy) -> {
|
||||||
|
if(tile.overlay().itemDrop != null){
|
||||||
|
tile.clearOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
enemies.shuffle();
|
if(tile.block() instanceof CoreBlock && tile.getTeam() == state.rules.defaultTeam){
|
||||||
for(int i = 0; i < enemySpawns; i++){
|
schematics.placeLoadout(loadout, tile.x, tile.y);
|
||||||
Point2 point = enemies.get(i);
|
anyCores = true;
|
||||||
tiles[point.x][point.y].setOverlay(Blocks.spawn);
|
|
||||||
|
|
||||||
int rad = 10, frad = 12;
|
|
||||||
|
|
||||||
for(int x = -rad; x <= rad; x++){
|
|
||||||
for(int y = -rad; y <= rad; y++){
|
|
||||||
int wx = x + point.x, wy = y + point.y;
|
|
||||||
double dst = Mathf.dst(x, y);
|
|
||||||
if(dst < frad && Structs.inBounds(wx, wy, tiles) && (dst <= rad || Mathf.chance(0.5))){
|
|
||||||
Tile tile = tiles[wx][wy];
|
|
||||||
if(tile.overlay() != Blocks.spawn){
|
|
||||||
tile.clearOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Point2 core = players.random();
|
if(!anyCores){
|
||||||
if(core == null){
|
|
||||||
throw new IllegalArgumentException("All zone maps must have a core.");
|
throw new IllegalArgumentException("All zone maps must have a core.");
|
||||||
}
|
}
|
||||||
|
|
||||||
schematics.placeLoadout(loadout, core.x, core.y);
|
|
||||||
|
|
||||||
world.prepareTiles(tiles);
|
world.prepareTiles(tiles);
|
||||||
world.setMap(map);
|
world.setMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Decoration{
|
|
||||||
public final Block floor;
|
|
||||||
public final Block wall;
|
|
||||||
public final double chance;
|
|
||||||
|
|
||||||
public Decoration(Block floor, Block wall, double chance){
|
|
||||||
this.floor = floor;
|
|
||||||
this.wall = wall;
|
|
||||||
this.chance = chance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package mindustry.maps.generators;
|
package mindustry.maps.generators;
|
||||||
|
|
||||||
import arc.struct.StringMap;
|
import arc.struct.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.*;
|
||||||
import mindustry.maps.Map;
|
import mindustry.maps.*;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.*;
|
||||||
import mindustry.world.Tile;
|
|
||||||
|
|
||||||
import static mindustry.Vars.world;
|
import static mindustry.Vars.world;
|
||||||
|
|
||||||
@@ -18,14 +17,14 @@ public abstract class RandomGenerator extends Generator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Tile[][] tiles){
|
public void generate(Tiles tiles){
|
||||||
for(int x = 0; x < width; x++){
|
for(int x = 0; x < width; x++){
|
||||||
for(int y = 0; y < height; y++){
|
for(int y = 0; y < height; y++){
|
||||||
floor = Blocks.air;
|
floor = Blocks.air;
|
||||||
block = Blocks.air;
|
block = Blocks.air;
|
||||||
ore = Blocks.air;
|
ore = Blocks.air;
|
||||||
generate(x, y);
|
generate(x, y);
|
||||||
tiles[x][y] = new Tile(x, y, floor.id, ore.id, block.id);
|
tiles.set(x, y, new Tile(x, y, floor, ore, block));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ public abstract class RandomGenerator extends Generator{
|
|||||||
world.setMap(new Map(new StringMap()));
|
world.setMap(new Map(new StringMap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void decorate(Tile[][] tiles);
|
public abstract void decorate(Tiles tiles);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets {@link #floor} and {@link #block} to the correct values as output.
|
* Sets {@link #floor} and {@link #block} to the correct values as output.
|
||||||
|
|||||||
11
core/src/mindustry/maps/planet/PlanetGenerator.java
Normal file
11
core/src/mindustry/maps/planet/PlanetGenerator.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package mindustry.maps.planet;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
public interface PlanetGenerator{
|
||||||
|
float getHeight(Vec3 position);
|
||||||
|
Color getColor(Vec3 position);
|
||||||
|
void generate(Vec3 position, TileGen tile);
|
||||||
|
}
|
||||||
60
core/src/mindustry/maps/planet/TestPlanetGenerator.java
Normal file
60
core/src/mindustry/maps/planet/TestPlanetGenerator.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package mindustry.maps.planet;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import arc.util.noise.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
public class TestPlanetGenerator implements PlanetGenerator{
|
||||||
|
Pixmap pix;
|
||||||
|
Simplex noise = new Simplex();
|
||||||
|
int waterLevel = 5;
|
||||||
|
float water;
|
||||||
|
float scl = 5f;
|
||||||
|
Array<Block> blocks = Array.with(Blocks.sporeMoss, Blocks.moss, Blocks.ice, Blocks.snow, Blocks.sand, Blocks.darksand, Blocks.darksandWater, Blocks.darksandTaintedWater);
|
||||||
|
|
||||||
|
public TestPlanetGenerator(){
|
||||||
|
try{
|
||||||
|
pix = new Pixmap("planets/colors.png");
|
||||||
|
water = waterLevel / (float)(pix.getHeight());
|
||||||
|
}catch(Exception ignored){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getHeight(Vec3 position){
|
||||||
|
position = Tmp.v33.set(position).scl(scl);
|
||||||
|
|
||||||
|
float height = Mathf.pow((float)noise.octaveNoise3D(7, 0.48f, 1f/3f, position.x, position.y, position.z), 2.4f);
|
||||||
|
if(height <= water){
|
||||||
|
return water;
|
||||||
|
}
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getColor(Vec3 position){
|
||||||
|
float height = getHeight(position);
|
||||||
|
position = Tmp.v33.set(position).scl(scl);
|
||||||
|
float rad = scl;
|
||||||
|
float temp = Mathf.clamp(Math.abs(position.y * 2f) / (rad));
|
||||||
|
float tnoise = (float)noise.octaveNoise3D(7, 0.48f, 1f/3f, position.x, position.y + 999f, position.z);
|
||||||
|
temp = Mathf.lerp(temp, tnoise, 0.5f);
|
||||||
|
height *= 1.2f;
|
||||||
|
height = Mathf.clamp(height);
|
||||||
|
|
||||||
|
Color color = Tmp.c1.set(pix.getPixel((int)(temp * (pix.getWidth()-1)), (int)((1f-height) * (pix.getHeight()-1))));
|
||||||
|
return blocks.min(c -> color.diff(c.color)).color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(Vec3 position, TileGen tile){
|
||||||
|
Color color = getColor(position);
|
||||||
|
tile.floor = blocks.min(c -> color.diff(c.color));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package mindustry.maps.zonegen;
|
|||||||
import arc.math.Mathf;
|
import arc.math.Mathf;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.maps.generators.BasicGenerator;
|
import mindustry.maps.generators.BasicGenerator;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.schematics;
|
import static mindustry.Vars.schematics;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ public class DesertWastesGenerator extends BasicGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decorate(Tile[][] tiles){
|
public void decorate(Tiles tiles){
|
||||||
ores(tiles);
|
ores(tiles);
|
||||||
terrain(tiles, Blocks.sandRocks, 60f, 1.5f, 0.9f);
|
terrain(tiles, Blocks.sandRocks, 60f, 1.5f, 0.9f);
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class DesertWastesGenerator extends BasicGenerator{
|
|||||||
erase(tiles, endX, endY, 10);
|
erase(tiles, endX, endY, 10);
|
||||||
erase(tiles, spawnX, spawnY, 20);
|
erase(tiles, spawnX, spawnY, 20);
|
||||||
distort(tiles, 20f, 4f);
|
distort(tiles, 20f, 4f);
|
||||||
inverseFloodFill(tiles, tiles[spawnX][spawnY], Blocks.sandRocks);
|
inverseFloodFill(tiles, tiles.getn(spawnX, spawnY), Blocks.sandRocks);
|
||||||
|
|
||||||
noise(tiles, Blocks.salt, Blocks.saltRocks, 5, 0.6f, 200f, 0.55f);
|
noise(tiles, Blocks.salt, Blocks.saltRocks, 5, 0.6f, 200f, 0.55f);
|
||||||
noise(tiles, Blocks.darksand, Blocks.duneRocks, 5, 0.7f, 120f, 0.5f);
|
noise(tiles, Blocks.darksand, Blocks.duneRocks, 5, 0.7f, 120f, 0.5f);
|
||||||
@@ -43,7 +43,7 @@ public class DesertWastesGenerator extends BasicGenerator{
|
|||||||
overlay(tiles, Blocks.sand, Blocks.pebbles, 0.15f, 5, 0.8f, 30f, 0.62f);
|
overlay(tiles, Blocks.sand, Blocks.pebbles, 0.15f, 5, 0.8f, 30f, 0.62f);
|
||||||
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
|
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
|
||||||
|
|
||||||
tiles[endX][endY].setOverlay(Blocks.spawn);
|
tiles.getn(endX, endY).setOverlay(Blocks.spawn);
|
||||||
schematics.placeLoadout(loadout, spawnX, spawnY);
|
schematics.placeLoadout(loadout, spawnX, spawnY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package mindustry.maps.zonegen;
|
package mindustry.maps.zonegen;
|
||||||
|
|
||||||
import arc.math.Mathf;
|
import arc.math.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.*;
|
||||||
import mindustry.maps.generators.BasicGenerator;
|
import mindustry.maps.generators.*;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.schematics;
|
import static mindustry.Vars.schematics;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ public class OvergrowthGenerator extends BasicGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decorate(Tile[][] tiles){
|
public void decorate(Tiles tiles){
|
||||||
ores(tiles);
|
ores(tiles);
|
||||||
terrain(tiles, Blocks.sporePine, 70f, 1.4f, 1f);
|
terrain(tiles, Blocks.sporePine, 70f, 1.4f, 1f);
|
||||||
|
|
||||||
@@ -34,12 +34,12 @@ public class OvergrowthGenerator extends BasicGenerator{
|
|||||||
erase(tiles, endX, endY, 10);
|
erase(tiles, endX, endY, 10);
|
||||||
erase(tiles, spawnX, spawnY, 20);
|
erase(tiles, spawnX, spawnY, 20);
|
||||||
distort(tiles, 20f, 4f);
|
distort(tiles, 20f, 4f);
|
||||||
inverseFloodFill(tiles, tiles[spawnX][spawnY], Blocks.sporerocks);
|
inverseFloodFill(tiles, tiles.getn(spawnX, spawnY), Blocks.sporerocks);
|
||||||
|
|
||||||
noise(tiles, Blocks.darksandTaintedWater, Blocks.duneRocks, 4, 0.7f, 120f, 0.64f);
|
noise(tiles, Blocks.darksandTaintedWater, Blocks.duneRocks, 4, 0.7f, 120f, 0.64f);
|
||||||
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
|
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
|
||||||
|
|
||||||
tiles[endX][endY].setOverlay(Blocks.spawn);
|
tiles.getn(endX, endY).setOverlay(Blocks.spawn);
|
||||||
schematics.placeLoadout(loadout, spawnX, spawnY);
|
schematics.placeLoadout(loadout, spawnX, spawnY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
76
core/src/mindustry/type/Planet.java
Normal file
76
core/src/mindustry/type/Planet.java
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package mindustry.type;
|
||||||
|
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.graphics.PlanetGrid.*;
|
||||||
|
import mindustry.maps.planet.*;
|
||||||
|
|
||||||
|
public class Planet extends UnlockableContent{
|
||||||
|
/** Mesh used for rendering. Created on load() - will be null on the server! */
|
||||||
|
public PlanetMesh mesh;
|
||||||
|
/** Grid used for the sectors on the planet. */
|
||||||
|
public @NonNull PlanetGrid grid;
|
||||||
|
/** Generator that will make the planet. */
|
||||||
|
public @NonNull PlanetGenerator generator;
|
||||||
|
/** Array of sectors; directly maps to tiles in the grid. */
|
||||||
|
public @NonNull Array<Sector> sectors;
|
||||||
|
/** Detail in divisions. Must be between 1 and 10. 6 is a good number for this.*/
|
||||||
|
public int detail = 3;
|
||||||
|
/** Size in terms of divisions. This only controls the amount of sectors on the planet, not the visuals. */
|
||||||
|
public int size = 3;
|
||||||
|
/** Radius of the mesh/sphere. */
|
||||||
|
public float radius = 1f;
|
||||||
|
|
||||||
|
public Planet(String name){
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(){
|
||||||
|
mesh = new PlanetMesh(detail, generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(){
|
||||||
|
grid = PlanetGrid.newGrid(size);
|
||||||
|
sectors = new Array<>(grid.tiles.length);
|
||||||
|
for(int i = 0; i < grid.tiles.length; i++){
|
||||||
|
sectors.add(new Sector(this, grid.tiles[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a sector a tile position. */
|
||||||
|
public Sector getSector(Ptile tile){
|
||||||
|
return sectors.get(tile.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return the sector that is hit by this ray, or null if nothing intersects it.
|
||||||
|
* @param center the center of this planet in 3D space, usually (0,0,0). */
|
||||||
|
public @Nullable Sector getSector(Vec3 center, Ray ray){
|
||||||
|
boolean found = Intersector3D.intersectRaySphere(ray, center, radius, Tmp.v33);
|
||||||
|
if(!found) return null;
|
||||||
|
//TODO fix O(N) search
|
||||||
|
return sectors.min(t -> t.tile.v.dst(Tmp.v33));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Planets cannot be viewed in the database dialog. */
|
||||||
|
@Override
|
||||||
|
public boolean isHidden(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayInfo(Table table){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentType getContentType(){
|
||||||
|
return ContentType.planet;
|
||||||
|
}
|
||||||
|
}
|
||||||
66
core/src/mindustry/type/Sector.java
Normal file
66
core/src/mindustry/type/Sector.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package mindustry.type;
|
||||||
|
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.graphics.PlanetGrid.*;
|
||||||
|
|
||||||
|
/** A small section of a planet. */
|
||||||
|
//TODO should this be content?
|
||||||
|
public class Sector{
|
||||||
|
public final SectorRect rect;
|
||||||
|
public final Planet planet;
|
||||||
|
public final Ptile tile;
|
||||||
|
|
||||||
|
public Sector(Planet planet, Ptile tile){
|
||||||
|
this.planet = planet;
|
||||||
|
this.tile = tile;
|
||||||
|
this.rect = makeRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Projects this sector onto a 4-corner square for use in map gen.
|
||||||
|
* Allocates a new object. Do not call in the main loop. */
|
||||||
|
private SectorRect makeRect(){
|
||||||
|
Vec3[] corners = new Vec3[tile.corners.length];
|
||||||
|
for(int i = 0; i < corners.length; i++){
|
||||||
|
corners[i] = tile.corners[i].v.cpy().setLength(planet.radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp.v33.setZero();
|
||||||
|
for(Vec3 c : corners){
|
||||||
|
Tmp.v33.add(c);
|
||||||
|
}
|
||||||
|
//v33 is now the center of this shape
|
||||||
|
Vec3 center = Tmp.v33.scl(1f / corners.length).cpy();
|
||||||
|
//radius of circle
|
||||||
|
float radius = Tmp.v33.dst(corners[0]) * 0.9f;
|
||||||
|
|
||||||
|
//get plane that these points are on
|
||||||
|
Plane plane = new Plane();
|
||||||
|
plane.set(corners[0], corners[2], corners[4]);
|
||||||
|
|
||||||
|
Vec3 planeTop = plane.project(center.cpy().add(0f, 1f, 0f)).sub(center).setLength(radius).add(center);
|
||||||
|
Vec3 planeRight = plane.project(center.cpy().rotate(Vec3.Y, -4f)).sub(center).setLength(radius).add(center);
|
||||||
|
|
||||||
|
return new SectorRect(radius, center, planeTop.sub(center), planeRight.sub(center));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SectorRect{
|
||||||
|
public final Vec3 center, top, right;
|
||||||
|
public final Vec3 result = new Vec3();
|
||||||
|
public final float radius;
|
||||||
|
|
||||||
|
public SectorRect(float radius, Vec3 center, Vec3 top, Vec3 right){
|
||||||
|
this.center = center;
|
||||||
|
this.top = top;
|
||||||
|
this.right = right;
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Project a coordinate into 3D space.
|
||||||
|
* Both coordinates should be normalized to floats in the range [0, 1] */
|
||||||
|
public Vec3 project(float x, float y){
|
||||||
|
float nx = (x - 0.5f) * 2f, ny = (y - 0.5f) * 2f;
|
||||||
|
return result.set(center).add(right, nx).add(top, ny);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
core/src/mindustry/type/Weather.java
Normal file
81
core/src/mindustry/type/Weather.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package mindustry.type;
|
||||||
|
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.traits.*;
|
||||||
|
import mindustry.entities.type.*;
|
||||||
|
import mindustry.type.Weather.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
public abstract class Weather<T extends WeatherEntity> extends MappableContent{
|
||||||
|
protected float duration = 100f;
|
||||||
|
|
||||||
|
public Weather(String name){
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void update(T entity);
|
||||||
|
|
||||||
|
public abstract void draw(T entity);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentType getContentType(){
|
||||||
|
return ContentType.weather;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Represents the in-game state of a weather event. */
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static class WeatherEntity extends BaseEntity implements SaveTrait, DrawTrait{
|
||||||
|
/** How long this event has been occuring in ticks. */
|
||||||
|
protected float life;
|
||||||
|
/** Type of weather that is being simulated. */
|
||||||
|
protected @NonNull
|
||||||
|
Weather weather;
|
||||||
|
|
||||||
|
public WeatherEntity(Weather weather){
|
||||||
|
this.weather = weather;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(){
|
||||||
|
weather.update(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(){
|
||||||
|
weather.draw(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
@Override
|
||||||
|
public void writeSave(DataOutput stream) throws IOException{
|
||||||
|
stream.writeShort(weather.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
@Override
|
||||||
|
public void readSave(DataInput stream, byte version) throws IOException{
|
||||||
|
weather = content.getByID(ContentType.weather, stream.readShort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte version(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeID getTypeID(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityGroup targetGroup(){
|
||||||
|
return weatherGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package mindustry.type;
|
|
||||||
|
|
||||||
import mindustry.ctype.Content;
|
|
||||||
import mindustry.ctype.ContentType;
|
|
||||||
|
|
||||||
//currently unimplemented, see trello for implementation plans
|
|
||||||
public class WeatherEvent extends Content{
|
|
||||||
public final String name;
|
|
||||||
|
|
||||||
public WeatherEvent(String name){
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentType getContentType(){
|
|
||||||
return ContentType.weather;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
package mindustry.type;
|
package mindustry.type;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.graphics.g2d.*;
|
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.ContentType;
|
import mindustry.ctype.*;
|
||||||
import mindustry.ctype.UnlockableContent;
|
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Objectives.*;
|
import mindustry.game.Objectives.*;
|
||||||
@@ -19,6 +17,7 @@ import static mindustry.Vars.*;
|
|||||||
public class Zone extends UnlockableContent{
|
public class Zone extends UnlockableContent{
|
||||||
public @NonNull Generator generator;
|
public @NonNull Generator generator;
|
||||||
public @NonNull Objective configureObjective = new ZoneWave(this, 15);
|
public @NonNull Objective configureObjective = new ZoneWave(this, 15);
|
||||||
|
public @NonNull Planet planet;
|
||||||
public Array<Objective> requirements = new Array<>();
|
public Array<Objective> requirements = new Array<>();
|
||||||
//TODO autogenerate
|
//TODO autogenerate
|
||||||
public Array<Item> resources = new Array<>();
|
public Array<Item> resources = new Array<>();
|
||||||
@@ -28,7 +27,6 @@ public class Zone extends UnlockableContent{
|
|||||||
public int conditionWave = Integer.MAX_VALUE;
|
public int conditionWave = Integer.MAX_VALUE;
|
||||||
public int launchPeriod = 10;
|
public int launchPeriod = 10;
|
||||||
public Schematic loadout = Loadouts.basicShard;
|
public Schematic loadout = Loadouts.basicShard;
|
||||||
public TextureRegion preview;
|
|
||||||
|
|
||||||
protected Array<ItemStack> baseLaunchCost = new Array<>();
|
protected Array<ItemStack> baseLaunchCost = new Array<>();
|
||||||
protected Array<ItemStack> startingItems = new Array<>();
|
protected Array<ItemStack> startingItems = new Array<>();
|
||||||
@@ -36,18 +34,14 @@ public class Zone extends UnlockableContent{
|
|||||||
|
|
||||||
private Array<ItemStack> defaultStartingItems = new Array<>();
|
private Array<ItemStack> defaultStartingItems = new Array<>();
|
||||||
|
|
||||||
public Zone(String name, Generator generator){
|
public Zone(String name, Planet planet, Generator generator){
|
||||||
super(name);
|
super(name);
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
|
this.planet = planet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Zone(String name){
|
public Zone(String name){
|
||||||
this(name, new MapGenerator(name));
|
this(name, Planets.starter, new MapGenerator(name));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(){
|
|
||||||
preview = Core.atlas.find("zone-" + name, Core.atlas.find(name + "-zone"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rules getRules(){
|
public Rules getRules(){
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
@@ -10,10 +9,10 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.scene.*;
|
import arc.scene.*;
|
||||||
import arc.scene.event.*;
|
import arc.scene.event.*;
|
||||||
import arc.scene.style.*;
|
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.scene.utils.*;
|
import arc.scene.utils.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
@@ -29,6 +28,7 @@ import mindustry.ui.layout.TreeLayout.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
//TODO remove (legacy, no longer needed)
|
||||||
public class DeployDialog extends FloatingDialog{
|
public class DeployDialog extends FloatingDialog{
|
||||||
private final float nodeSize = Scl.scl(230f);
|
private final float nodeSize = Scl.scl(230f);
|
||||||
private ObjectSet<ZoneNode> nodes = new ObjectSet<>();
|
private ObjectSet<ZoneNode> nodes = new ObjectSet<>();
|
||||||
@@ -105,7 +105,7 @@ public class DeployDialog extends FloatingDialog{
|
|||||||
bounds.y += nodeSize*0.4f;
|
bounds.y += nodeSize*0.4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setup(){
|
void setup(){
|
||||||
platform.updateRPC();
|
platform.updateRPC();
|
||||||
|
|
||||||
cont.clear();
|
cont.clear();
|
||||||
@@ -122,7 +122,7 @@ public class DeployDialog extends FloatingDialog{
|
|||||||
setFilter(TextureFilter.Linear);
|
setFilter(TextureFilter.Linear);
|
||||||
}}){{
|
}}){{
|
||||||
float[] time = {0};
|
float[] time = {0};
|
||||||
setColor(Color.grays(0.3f));
|
setColor(Color.gray(0.3f));
|
||||||
setScale(1.5f);
|
setScale(1.5f);
|
||||||
update(() -> {
|
update(() -> {
|
||||||
setOrigin(Align.center);
|
setOrigin(Align.center);
|
||||||
@@ -140,19 +140,19 @@ public class DeployDialog extends FloatingDialog{
|
|||||||
Stack sub = new Stack();
|
Stack sub = new Stack();
|
||||||
|
|
||||||
if(slot.getZone() != null){
|
if(slot.getZone() != null){
|
||||||
sub.add(new Table(f -> f.margin(4f).add(new Image()).color(Color.grays(0.1f)).grow()));
|
sub.add(new Table(f -> f.margin(4f).add(new Image()).color(Color.gray(0.1f)).grow()));
|
||||||
|
|
||||||
sub.add(new Table(f -> f.margin(4f).add(new Image(slot.getZone().preview).setScaling(Scaling.fit)).update(img -> {
|
//sub.add(new Table(f -> f.margin(4f).add(new Image(slot.getZone().preview).setScaling(Scaling.fit)).update(img -> {
|
||||||
TextureRegionDrawable draw = (TextureRegionDrawable)img.getDrawable();
|
//TextureRegionDrawable draw = (TextureRegionDrawable)img.getDrawable();
|
||||||
if(draw.getRegion().getTexture().isDisposed()){
|
//if(draw.getRegion().getTexture().isDisposed()){
|
||||||
draw.setRegion(slot.getZone().preview);
|
// draw.setRegion(slot.getZone().preview);
|
||||||
}
|
// }
|
||||||
|
|
||||||
Texture text = slot.previewTexture();
|
Texture text = slot.previewTexture();
|
||||||
if(draw.getRegion() == slot.getZone().preview && text != null){
|
//if(draw.getRegion() == slot.getZone().preview && text != null){
|
||||||
draw.setRegion(new TextureRegion(text));
|
// draw.setRegion(new TextureRegion(text));
|
||||||
}
|
//}
|
||||||
}).color(Color.darkGray).grow()));
|
// }).color(Color.darkGray).grow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextButton button = Elements.newButton(Core.bundle.format("resume", slot.getZone().localizedName), Styles.squaret, () -> {
|
TextButton button = Elements.newButton(Core.bundle.format("resume", slot.getZone().localizedName), Styles.squaret, () -> {
|
||||||
@@ -249,12 +249,12 @@ public class DeployDialog extends FloatingDialog{
|
|||||||
for(ZoneNode node : nodes){
|
for(ZoneNode node : nodes){
|
||||||
Stack stack = new Stack();
|
Stack stack = new Stack();
|
||||||
Tmp.v1.set(node.width, node.height);
|
Tmp.v1.set(node.width, node.height);
|
||||||
if(node.zone.preview != null){
|
//if(node.zone.preview != null){
|
||||||
Tmp.v1.set(Scaling.fit.apply(node.zone.preview.getWidth(), node.zone.preview.getHeight(), node.width, node.height));
|
// Tmp.v1.set(Scaling.fit.apply(node.zone.preview.getWidth(), node.zone.preview.getHeight(), node.width, node.height));
|
||||||
}
|
//}
|
||||||
|
|
||||||
stack.setSize(Tmp.v1.x, Tmp.v1.y);
|
// stack.setSize(Tmp.v1.x, Tmp.v1.y);
|
||||||
stack.add(new Table(t -> t.margin(4f).add(new Image(node.zone.preview).setScaling(Scaling.stretch)).color(node.zone.unlocked() ? Color.darkGray : Color.grays(0.2f)).grow()));
|
// stack.add(new Table(t -> t.margin(4f).add(new Image(node.zone.preview).setScaling(Scaling.stretch)).color(node.zone.unlocked() ? Color.darkGray : Color.gray(0.2f)).grow()));
|
||||||
stack.update(() -> stack.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f, Align.center));
|
stack.update(() -> stack.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f, Align.center));
|
||||||
|
|
||||||
Button button = new Button(Styles.squaret);
|
Button button = new Button(Styles.squaret);
|
||||||
|
|||||||
@@ -200,7 +200,6 @@ public class FileChooser extends FloatingDialog{
|
|||||||
files.add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2);
|
files.add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2);
|
||||||
files.row();
|
files.row();
|
||||||
|
|
||||||
|
|
||||||
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
||||||
group.setMinCheckCount(0);
|
group.setMinCheckCount(0);
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class GameOverDialog extends FloatingDialog{
|
|||||||
hide();
|
hide();
|
||||||
state.set(State.menu);
|
state.set(State.menu);
|
||||||
logic.reset();
|
logic.reset();
|
||||||
ui.deploy.show();
|
ui.planet.show();
|
||||||
}).size(130f, 60f);
|
}).size(130f, 60f);
|
||||||
}else{
|
}else{
|
||||||
buttons.addButton("$menu", () -> {
|
buttons.addButton("$menu", () -> {
|
||||||
|
|||||||
30
core/src/mindustry/ui/dialogs/PlanetDialog.java
Normal file
30
core/src/mindustry/ui/dialogs/PlanetDialog.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.ui;
|
||||||
|
|
||||||
|
public class PlanetDialog extends FloatingDialog{
|
||||||
|
private PlanetRenderer renderer = new PlanetRenderer();
|
||||||
|
|
||||||
|
public PlanetDialog(){
|
||||||
|
super("", Styles.fullDialog);
|
||||||
|
|
||||||
|
addCloseButton();
|
||||||
|
buttons.addImageTextButton("$techtree", Icon.tree, () -> ui.tech.show()).size(230f, 64f);
|
||||||
|
|
||||||
|
shown(this::setup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
cont.clear();
|
||||||
|
titleTable.remove();
|
||||||
|
|
||||||
|
cont.addRect((x, y, w, h) -> {
|
||||||
|
renderer.render(Planets.starter);
|
||||||
|
}).grow();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ public class TechTreeDialog extends FloatingDialog{
|
|||||||
treeLayout();
|
treeLayout();
|
||||||
});
|
});
|
||||||
|
|
||||||
hidden(ui.deploy::setup);
|
hidden(ui.planet::setup);
|
||||||
|
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import mindustry.ui.Cicon;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
//TODO remove
|
||||||
public class ZoneInfoDialog extends FloatingDialog{
|
public class ZoneInfoDialog extends FloatingDialog{
|
||||||
private LoadoutDialog loadout = new LoadoutDialog();
|
private LoadoutDialog loadout = new LoadoutDialog();
|
||||||
|
|
||||||
@@ -152,13 +153,13 @@ public class ZoneInfoDialog extends FloatingDialog{
|
|||||||
if(!data.isUnlocked(zone)){
|
if(!data.isUnlocked(zone)){
|
||||||
Sounds.unlock.play();
|
Sounds.unlock.play();
|
||||||
data.unlockContent(zone);
|
data.unlockContent(zone);
|
||||||
ui.deploy.setup();
|
ui.planet.setup();
|
||||||
setup(zone);
|
setup(zone);
|
||||||
}else{
|
}else{
|
||||||
ui.deploy.hide();
|
ui.planet.hide();
|
||||||
data.removeItems(zone.getLaunchCost());
|
data.removeItems(zone.getLaunchCost());
|
||||||
hide();
|
hide();
|
||||||
control.playZone(zone);
|
//control.playZone(zone);
|
||||||
}
|
}
|
||||||
}).minWidth(200f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !zone.canUnlock() : !data.hasItems(zone.getLaunchCost())).uniformY().get();
|
}).minWidth(200f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !zone.canUnlock() : !data.hasItems(zone.getLaunchCost())).uniformY().get();
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ public class FadeInFragment extends Fragment{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
Draw.color(0f, 0f, 0f, Mathf.clamp(1f - time));
|
Draw.color(0f, 0f, 0f, Mathf.clamp(1f - time));
|
||||||
Fill.crect(0, 0, Core.graphics.getWidth(), Core.graphics.getHeight());
|
Fill.crect(0, 0, Core.graphics.getWidth(), Core.graphics.getHeight());
|
||||||
Draw.color();
|
Draw.color();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class MenuFragment extends Fragment{
|
|||||||
container.defaults().size(size).pad(5).padTop(4f);
|
container.defaults().size(size).pad(5).padTop(4f);
|
||||||
|
|
||||||
MobileButton
|
MobileButton
|
||||||
play = new MobileButton(Icon.play, "$campaign", () -> checkPlay(ui.deploy::show)),
|
play = new MobileButton(Icon.play, "$campaign", () -> checkPlay(ui.planet::show)),
|
||||||
custom = new MobileButton(Icon.rightOpenOut, "$customgame", () -> checkPlay(ui.custom::show)),
|
custom = new MobileButton(Icon.rightOpenOut, "$customgame", () -> checkPlay(ui.custom::show)),
|
||||||
maps = new MobileButton(Icon.download, "$loadgame", () -> checkPlay(ui.load::show)),
|
maps = new MobileButton(Icon.download, "$loadgame", () -> checkPlay(ui.load::show)),
|
||||||
join = new MobileButton(Icon.add, "$joingame", () -> checkPlay(ui.join::show)),
|
join = new MobileButton(Icon.add, "$joingame", () -> checkPlay(ui.join::show)),
|
||||||
@@ -165,7 +165,7 @@ public class MenuFragment extends Fragment{
|
|||||||
|
|
||||||
buttons(t,
|
buttons(t,
|
||||||
new Buttoni("$play", Icon.play,
|
new Buttoni("$play", Icon.play,
|
||||||
new Buttoni("$campaign", Icon.play, () -> checkPlay(ui.deploy::show)),
|
new Buttoni("$campaign", Icon.play, () -> checkPlay(ui.planet::show)),
|
||||||
new Buttoni("$joingame", Icon.add, () -> checkPlay(ui.join::show)),
|
new Buttoni("$joingame", Icon.add, () -> checkPlay(ui.join::show)),
|
||||||
new Buttoni("$customgame", Icon.terrain, () -> checkPlay(ui.custom::show)),
|
new Buttoni("$customgame", Icon.terrain, () -> checkPlay(ui.custom::show)),
|
||||||
new Buttoni("$loadgame", Icon.download, () -> checkPlay(ui.load::show)),
|
new Buttoni("$loadgame", Icon.download, () -> checkPlay(ui.load::show)),
|
||||||
|
|||||||
@@ -35,17 +35,21 @@ public class Tile implements Position{
|
|||||||
block = floor = overlay = (Floor)Blocks.air;
|
block = floor = overlay = (Floor)Blocks.air;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile(int x, int y, int floor, int overlay, int wall){
|
public Tile(int x, int y, Block floor, Block overlay, Block wall){
|
||||||
this.x = (short)x;
|
this.x = (short)x;
|
||||||
this.y = (short)y;
|
this.y = (short)y;
|
||||||
this.floor = (Floor)content.block(floor);
|
this.floor = (Floor)floor;
|
||||||
this.overlay = (Floor)content.block(overlay);
|
this.overlay = (Floor)overlay;
|
||||||
this.block = content.block(wall);
|
this.block = wall;
|
||||||
|
|
||||||
//update entity and create it if needed
|
//update entity and create it if needed
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Tile(int x, int y, int floor, int overlay, int wall){
|
||||||
|
this(x, y, content.block(floor), content.block(overlay), content.block(wall));
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns this tile's position as a {@link Pos}. */
|
/** Returns this tile's position as a {@link Pos}. */
|
||||||
public int pos(){
|
public int pos(){
|
||||||
return Pos.get(x, y);
|
return Pos.get(x, y);
|
||||||
|
|||||||
19
core/src/mindustry/world/TileGen.java
Normal file
19
core/src/mindustry/world/TileGen.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package mindustry.world;
|
||||||
|
|
||||||
|
import mindustry.content.*;
|
||||||
|
|
||||||
|
public class TileGen{
|
||||||
|
public Block floor;
|
||||||
|
public Block block ;
|
||||||
|
public Block overlay;
|
||||||
|
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(){
|
||||||
|
floor = Blocks.stone;
|
||||||
|
block = Blocks.air;
|
||||||
|
overlay = Blocks.air;
|
||||||
|
}
|
||||||
|
}
|
||||||
93
core/src/mindustry/world/Tiles.java
Normal file
93
core/src/mindustry/world/Tiles.java
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package mindustry.world;
|
||||||
|
|
||||||
|
import arc.func.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/** A tile container. */
|
||||||
|
public class Tiles implements Iterable<Tile>{
|
||||||
|
private final Tile[] array;
|
||||||
|
private final int width, height;
|
||||||
|
private final TileIterator iterator = new TileIterator();
|
||||||
|
|
||||||
|
public Tiles(int width, int height){
|
||||||
|
this.array = new Tile[width * height];
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void each(Intc2 cons){
|
||||||
|
for(int x = 0; x < width; x++){
|
||||||
|
for(int y = 0; y < height; y++){
|
||||||
|
cons.get(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** fills this tile set with empty air tiles. */
|
||||||
|
public void fill(){
|
||||||
|
for(int i = 0; i < array.length; i++){
|
||||||
|
array[i] = new Tile(i % width, i / width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** set a tile at a position; does not range-check. use with caution. */
|
||||||
|
public void set(int x, int y, Tile tile){
|
||||||
|
array[y*width + x] = tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether these coordinates are in bounds */
|
||||||
|
public boolean in(int x, int y){
|
||||||
|
return x >= 0 && x < width && y >= 0 && y < height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at coordinates, or null if out of bounds */
|
||||||
|
public @Nullable Tile get(int x, int y){
|
||||||
|
return (x < 0 || x >= width || y < 0 || y >= height) ? null : array[y*width + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at coordinates; throws an exception if out of bounds */
|
||||||
|
public @NonNull Tile getn(int x, int y){
|
||||||
|
if(x < 0 || x >= width || y < 0 || y >= height) throw new IllegalArgumentException(x + ", " + y + " out of bounds: width=" + width + ", height=" + height);
|
||||||
|
return array[y*width + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at an iteration index [0, width * height] */
|
||||||
|
public @NonNull Tile geti(int idx){
|
||||||
|
return array[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a tile at an int position (not equivalent to geti) */
|
||||||
|
public @Nullable Tile getp(int pos){
|
||||||
|
return get(Pos.x(pos), Pos.y(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int width(){
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int height(){
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Tile> iterator(){
|
||||||
|
iterator.index = 0;
|
||||||
|
return iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TileIterator implements Iterator<Tile>{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext(){
|
||||||
|
return index < array.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tile next(){
|
||||||
|
return array[index++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import arc.graphics.g2d.*;
|
|||||||
import arc.graphics.g2d.TextureAtlas.*;
|
import arc.graphics.g2d.TextureAtlas.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
@@ -35,13 +36,13 @@ public class Floor extends Block{
|
|||||||
/** Effect displayed when drowning on this floor. */
|
/** Effect displayed when drowning on this floor. */
|
||||||
public Effect drownUpdateEffect = Fx.bubble;
|
public Effect drownUpdateEffect = Fx.bubble;
|
||||||
/** Status effect applied when walking on. */
|
/** Status effect applied when walking on. */
|
||||||
public StatusEffect status = StatusEffects.none;
|
public @NonNull StatusEffect status = StatusEffects.none;
|
||||||
/** Intensity of applied status effect. */
|
/** Intensity of applied status effect. */
|
||||||
public float statusDuration = 60f;
|
public float statusDuration = 60f;
|
||||||
/** liquids that drop from this block, used for pumps */
|
/** liquids that drop from this block, used for pumps */
|
||||||
public Liquid liquidDrop = null;
|
public @Nullable Liquid liquidDrop = null;
|
||||||
/** item that drops from this block, used for drills */
|
/** item that drops from this block, used for drills */
|
||||||
public Item itemDrop = null;
|
public @Nullable Item itemDrop = null;
|
||||||
/** whether this block can be drowned in */
|
/** whether this block can be drowned in */
|
||||||
public boolean isLiquid;
|
public boolean isLiquid;
|
||||||
/** 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. */
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ public class DesktopLauncher extends ClientLauncher{
|
|||||||
new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{
|
new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{
|
||||||
title = "Mindustry";
|
title = "Mindustry";
|
||||||
maximized = true;
|
maximized = true;
|
||||||
depth = 0;
|
|
||||||
stencil = 0;
|
stencil = 0;
|
||||||
width = 900;
|
width = 900;
|
||||||
height = 700;
|
height = 700;
|
||||||
@@ -267,7 +266,7 @@ public class DesktopLauncher extends ClientLauncher{
|
|||||||
}else{
|
}else{
|
||||||
if(ui.editor != null && ui.editor.isShown()){
|
if(ui.editor != null && ui.editor.isShown()){
|
||||||
uiState = "In Editor";
|
uiState = "In Editor";
|
||||||
}else if(ui.deploy != null && ui.deploy.isShown()){
|
}else if(ui.planet != null && ui.planet.isShown()){
|
||||||
uiState = "In Launch Selection";
|
uiState = "In Launch Selection";
|
||||||
}else{
|
}else{
|
||||||
uiState = "In Menu";
|
uiState = "In Menu";
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ if(!hasProperty("release")){
|
|||||||
use(':Arc:extensions:recorder')
|
use(':Arc:extensions:recorder')
|
||||||
use(':Arc:extensions:arcnet')
|
use(':Arc:extensions:arcnet')
|
||||||
use(':Arc:extensions:packer')
|
use(':Arc:extensions:packer')
|
||||||
|
use(':Arc:extensions:g3d')
|
||||||
use(':Arc:backends')
|
use(':Arc:backends')
|
||||||
use(':Arc:backends:backend-sdl')
|
use(':Arc:backends:backend-sdl')
|
||||||
use(':Arc:backends:backend-android')
|
use(':Arc:backends:backend-android')
|
||||||
|
|||||||
@@ -109,14 +109,10 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createMap(){
|
void createMap(){
|
||||||
Tile[][] tiles = world.createTiles(8, 8);
|
Tiles tiles = world.resize(8, 8);
|
||||||
|
|
||||||
world.beginMapLoad();
|
world.beginMapLoad();
|
||||||
for(int x = 0; x < tiles.length; x++){
|
tiles.fill();
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
|
||||||
tiles[x][y] = new Tile(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
world.endMapLoad();
|
world.endMapLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,29 +375,29 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void allBlockTest(){
|
void allBlockTest(){
|
||||||
Tile[][] tiles = world.createTiles(256*2 + 20, 10);
|
Tiles tiles = world.resize(256*2 + 20, 10);
|
||||||
|
|
||||||
world.beginMapLoad();
|
world.beginMapLoad();
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(int x = 0; x < tiles.width(); x++){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
for(int y = 0; y < tiles.height(); y++){
|
||||||
tiles[x][y] = new Tile(x, y, Blocks.stone.id, (byte)0, (byte)0);
|
tiles.set(x, y, new Tile(x, y, Blocks.stone, Blocks.air, Blocks.air));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for(int x = 5; x < tiles.length && i < content.blocks().size; ){
|
for(int x = 5; x < tiles.width() && i < content.blocks().size; ){
|
||||||
Block block = content.block(i++);
|
Block block = content.block(i++);
|
||||||
if(block.isBuildable()){
|
if(block.isBuildable()){
|
||||||
x += block.size;
|
x += block.size;
|
||||||
tiles[x][5].setBlock(block);
|
tiles.get(x, 5).setBlock(block);
|
||||||
x += block.size;
|
x += block.size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
world.endMapLoad();
|
world.endMapLoad();
|
||||||
|
|
||||||
for(int x = 0; x < tiles.length; x++){
|
for(int x = 0; x < tiles.width(); x++){
|
||||||
for(int y = 0; y < tiles[0].length; y++){
|
for(int y = 0; y < tiles.height(); y++){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.rawTile(x, y);
|
||||||
if(tile.entity != null){
|
if(tile.entity != null){
|
||||||
try{
|
try{
|
||||||
tile.entity.update();
|
tile.entity.update();
|
||||||
@@ -429,7 +425,7 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
void depositTest(Block block, Item item){
|
void depositTest(Block block, Item item){
|
||||||
BaseUnit unit = UnitTypes.spirit.create(Team.derelict);
|
BaseUnit unit = UnitTypes.spirit.create(Team.derelict);
|
||||||
Tile tile = new Tile(0, 0, Blocks.air.id, (byte)0, block.id);
|
Tile tile = new Tile(0, 0, Blocks.air, Blocks.air, block);
|
||||||
int capacity = tile.block().itemCapacity;
|
int capacity = tile.block().itemCapacity;
|
||||||
|
|
||||||
assertNotNull(tile.entity, "Tile should have an entity, but does not: " + tile);
|
assertNotNull(tile.entity, "Tile should have an entity, but does not: " + tile);
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ public class ZoneTests{
|
|||||||
Array<DynamicTest> out = new Array<>();
|
Array<DynamicTest> out = new Array<>();
|
||||||
if(world == null) world = new World();
|
if(world == null) world = new World();
|
||||||
|
|
||||||
|
fail("Zone validity tests need to be refactored!");
|
||||||
|
|
||||||
for(Zone zone : content.zones()){
|
for(Zone zone : content.zones()){
|
||||||
out.add(dynamicTest(zone.name, () -> {
|
out.add(dynamicTest(zone.name, () -> {
|
||||||
zone.generator.init(zone.loadout);
|
zone.generator.init(zone.loadout);
|
||||||
logic.reset();
|
logic.reset();
|
||||||
try{
|
try{
|
||||||
world.loadGenerator(zone.generator);
|
//world.loadGenerator(zone.generator);
|
||||||
}catch(SaveException e){
|
}catch(SaveException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user