* HDustry - scl() & private map Co-Authored-By: citrusMarmelade <20476281+citrusMarmelade@users.noreply.github.com> * MEEP stop doing stuff when i work <3 <3 * Replaced Draw.scl Co-authored-by: citrusMarmelade <20476281+citrusMarmelade@users.noreply.github.com> Co-authored-by: Anuken <arnukren@gmail.com>
295 lines
9.9 KiB
Java
295 lines
9.9 KiB
Java
package mindustry.graphics;
|
|
|
|
import arc.*;
|
|
import arc.func.*;
|
|
import arc.graphics.*;
|
|
import arc.graphics.g2d.*;
|
|
import arc.graphics.gl.*;
|
|
import arc.math.*;
|
|
import arc.scene.ui.layout.*;
|
|
import arc.struct.*;
|
|
import arc.util.*;
|
|
import arc.util.noise.*;
|
|
import mindustry.content.*;
|
|
import mindustry.type.*;
|
|
import mindustry.world.*;
|
|
|
|
import static mindustry.Vars.*;
|
|
|
|
public class MenuRenderer implements Disposable{
|
|
private static final float darkness = 0.3f;
|
|
private final int width = !mobile ? 100 : 60, height = !mobile ? 50 : 40;
|
|
|
|
private int cacheFloor, cacheWall;
|
|
private Camera camera = new Camera();
|
|
private Mat mat = new Mat();
|
|
private FrameBuffer shadows;
|
|
private CacheBatch batch;
|
|
private float time = 0f;
|
|
private float flyerRot = 45f;
|
|
private int flyers = Mathf.chance(0.2) ? Mathf.random(35) : Mathf.random(15);
|
|
//no longer random or "dynamic", mod units in the menu look jarring, and it's not worth the configuration effort
|
|
private UnitType flyerType = Seq.with(UnitTypes.flare, UnitTypes.horizon, UnitTypes.zenith, UnitTypes.mono, UnitTypes.poly, UnitTypes.mega, UnitTypes.alpha, UnitTypes.beta, UnitTypes.gamma).random();
|
|
|
|
public MenuRenderer(){
|
|
Time.mark();
|
|
generate();
|
|
cache();
|
|
Log.debug("Time to generate menu: @", Time.elapsed());
|
|
}
|
|
|
|
private void generate(){
|
|
//suppress tile change events.
|
|
world.setGenerating(true);
|
|
|
|
Tiles tiles = world.resize(width, height);
|
|
//only uses base game ores now, mod ones usually contrast too much with the floor
|
|
Seq<Block> ores = Seq.with(Blocks.oreCopper, Blocks.oreLead, Blocks.oreScrap, Blocks.oreCoal, Blocks.oreTitanium, Blocks.oreThorium);
|
|
shadows = new FrameBuffer(width, height);
|
|
int offset = Mathf.random(100000);
|
|
int s1 = offset, s2 = offset + 1, s3 = offset + 2;
|
|
Block[] selected = Structs.random(
|
|
new Block[]{Blocks.sand, Blocks.sandWall},
|
|
new Block[]{Blocks.shale, Blocks.shaleWall},
|
|
new Block[]{Blocks.ice, Blocks.iceWall},
|
|
new Block[]{Blocks.sand, Blocks.sandWall},
|
|
new Block[]{Blocks.shale, Blocks.shaleWall},
|
|
new Block[]{Blocks.ice, Blocks.iceWall},
|
|
new Block[]{Blocks.moss, Blocks.sporePine},
|
|
new Block[]{Blocks.dirt, Blocks.dirtWall},
|
|
new Block[]{Blocks.dacite, Blocks.daciteWall}
|
|
);
|
|
Block[] selected2 = Structs.random(
|
|
new Block[]{Blocks.basalt, Blocks.duneWall},
|
|
new Block[]{Blocks.basalt, Blocks.duneWall},
|
|
new Block[]{Blocks.stone, Blocks.stoneWall},
|
|
new Block[]{Blocks.stone, Blocks.stoneWall},
|
|
new Block[]{Blocks.moss, Blocks.sporeWall},
|
|
new Block[]{Blocks.salt, Blocks.saltWall}
|
|
);
|
|
|
|
Block ore1 = ores.random();
|
|
ores.remove(ore1);
|
|
Block ore2 = ores.random();
|
|
|
|
double tr1 = Mathf.random(0.65f, 0.85f);
|
|
double tr2 = Mathf.random(0.65f, 0.85f);
|
|
boolean doheat = Mathf.chance(0.25);
|
|
boolean tendrils = Mathf.chance(0.25);
|
|
boolean tech = Mathf.chance(0.25);
|
|
int secSize = 10;
|
|
|
|
Block floord = selected[0], walld = selected[1];
|
|
Block floord2 = selected2[0], walld2 = selected2[1];
|
|
|
|
for(int x = 0; x < width; x++){
|
|
for(int y = 0; y < height; y++){
|
|
Block floor = floord;
|
|
Block ore = Blocks.air;
|
|
Block wall = Blocks.air;
|
|
|
|
if(Simplex.noise2d(s1, 3, 0.5, 1/20.0, x, y) > 0.5){
|
|
wall = walld;
|
|
}
|
|
|
|
if(Simplex.noise2d(s3, 3, 0.5, 1/20.0, x, y) > 0.5){
|
|
floor = floord2;
|
|
if(wall != Blocks.air){
|
|
wall = walld2;
|
|
}
|
|
}
|
|
|
|
if(Simplex.noise2d(s2, 3, 0.3, 1/30.0, x, y) > tr1){
|
|
ore = ore1;
|
|
}
|
|
|
|
if(Simplex.noise2d(s2, 2, 0.2, 1/15.0, x, y+99999) > tr2){
|
|
ore = ore2;
|
|
}
|
|
|
|
if(doheat){
|
|
double heat = Simplex.noise2d(s3, 4, 0.6, 1 / 50.0, x, y + 9999);
|
|
double base = 0.65;
|
|
|
|
if(heat > base){
|
|
ore = Blocks.air;
|
|
wall = Blocks.air;
|
|
floor = Blocks.basalt;
|
|
|
|
if(heat > base + 0.1){
|
|
floor = Blocks.hotrock;
|
|
|
|
if(heat > base + 0.15){
|
|
floor = Blocks.magmarock;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(tech){
|
|
int mx = x % secSize, my = y % secSize;
|
|
int sclx = x / secSize, scly = y / secSize;
|
|
if(Simplex.noise2d(s1, 2, 1f / 10f, 0.5f, sclx, scly) > 0.4f && (mx == 0 || my == 0 || mx == secSize - 1 || my == secSize - 1)){
|
|
floor = Blocks.darkPanel3;
|
|
if(Mathf.dst(mx, my, secSize/2, secSize/2) > secSize/2f + 1){
|
|
floor = Blocks.darkPanel4;
|
|
}
|
|
|
|
|
|
if(wall != Blocks.air && Mathf.chance(0.7)){
|
|
wall = Blocks.darkMetal;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(tendrils){
|
|
if(Ridged.noise2d(1 + offset, x, y, 1f / 17f) > 0f){
|
|
floor = Mathf.chance(0.2) ? Blocks.sporeMoss : Blocks.moss;
|
|
|
|
if(wall != Blocks.air){
|
|
wall = Blocks.sporeWall;
|
|
}
|
|
}
|
|
}
|
|
|
|
Tile tile;
|
|
tiles.set(x, y, (tile = new CachedTile()));
|
|
tile.x = (short)x;
|
|
tile.y = (short)y;
|
|
tile.setFloor(floor.asFloor());
|
|
tile.setBlock(wall);
|
|
tile.setOverlay(ore);
|
|
}
|
|
}
|
|
|
|
//don't fire a world load event, it just causes lag and confusion
|
|
world.setGenerating(false);
|
|
}
|
|
|
|
private void cache(){
|
|
|
|
//draw shadows
|
|
Draw.proj().setOrtho(0, 0, shadows.getWidth(), shadows.getHeight());
|
|
shadows.begin(Color.clear);
|
|
Draw.color(Color.black);
|
|
|
|
for(Tile tile : world.tiles){
|
|
if(tile.block() != Blocks.air){
|
|
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
|
|
}
|
|
}
|
|
|
|
Draw.color();
|
|
shadows.end();
|
|
|
|
Batch prev = Core.batch;
|
|
|
|
Core.batch = batch = new CacheBatch(new SpriteCache(width * height * 6, false));
|
|
batch.beginCache();
|
|
|
|
for(Tile tile : world.tiles){
|
|
tile.floor().drawBase(tile);
|
|
}
|
|
|
|
for(Tile tile : world.tiles){
|
|
tile.overlay().drawBase(tile);
|
|
}
|
|
|
|
cacheFloor = batch.endCache();
|
|
batch.beginCache();
|
|
|
|
for(Tile tile : world.tiles){
|
|
tile.block().drawBase(tile);
|
|
}
|
|
|
|
cacheWall = batch.endCache();
|
|
|
|
Core.batch = prev;
|
|
}
|
|
|
|
public void render(){
|
|
time += Time.delta;
|
|
float scaling = Math.max(Scl.scl(4f), Math.max(Core.graphics.getWidth() / ((width - 1f) * tilesize), Core.graphics.getHeight() / ((height - 1f) * tilesize)));
|
|
camera.position.set(width * tilesize / 2f, height * tilesize / 2f);
|
|
camera.resize(Core.graphics.getWidth() / scaling,
|
|
Core.graphics.getHeight() / scaling);
|
|
|
|
mat.set(Draw.proj());
|
|
Draw.flush();
|
|
Draw.proj(camera);
|
|
batch.setProjection(camera.mat);
|
|
batch.beginDraw();
|
|
batch.drawCache(cacheFloor);
|
|
batch.endDraw();
|
|
Draw.color();
|
|
Draw.rect(Draw.wrap(shadows.getTexture()),
|
|
width * tilesize / 2f - 4f, height * tilesize / 2f - 4f,
|
|
width * tilesize, -height * tilesize);
|
|
Draw.flush();
|
|
batch.beginDraw();
|
|
batch.drawCache(cacheWall);
|
|
batch.endDraw();
|
|
|
|
drawFlyers();
|
|
|
|
Draw.proj(mat);
|
|
Draw.color(0f, 0f, 0f, darkness);
|
|
Fill.crect(0, 0, Core.graphics.getWidth(), Core.graphics.getHeight());
|
|
Draw.color();
|
|
}
|
|
|
|
private void drawFlyers(){
|
|
Draw.color(0f, 0f, 0f, 0.4f);
|
|
|
|
TextureRegion icon = flyerType.fullIcon;
|
|
|
|
flyers((x, y) -> {
|
|
Draw.rect(icon, x - 12f, y - 13f, flyerRot - 90);
|
|
});
|
|
|
|
float size = Math.max(icon.width, icon.height) * icon.scl() * 1.6f;
|
|
|
|
flyers((x, y) -> {
|
|
Draw.rect("circle-shadow", x, y, size, size);
|
|
});
|
|
Draw.color();
|
|
|
|
flyers((x, y) -> {
|
|
float engineOffset = flyerType.engineOffset, engineSize = flyerType.engineSize, rotation = flyerRot;
|
|
|
|
Draw.color(Pal.engine);
|
|
Fill.circle(x + Angles.trnsx(rotation + 180, engineOffset), y + Angles.trnsy(rotation + 180, engineOffset),
|
|
engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f));
|
|
|
|
Draw.color(Color.white);
|
|
Fill.circle(x + Angles.trnsx(rotation + 180, engineOffset - 1f), y + Angles.trnsy(rotation + 180, engineOffset - 1f),
|
|
(engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f)) / 2f);
|
|
Draw.color();
|
|
|
|
Draw.rect(icon, x, y, flyerRot - 90);
|
|
});
|
|
}
|
|
|
|
private void flyers(Floatc2 cons){
|
|
float tw = width * tilesize * 1f + tilesize;
|
|
float th = height * tilesize * 1f + tilesize;
|
|
float range = 500f;
|
|
float offset = -100f;
|
|
|
|
for(int i = 0; i < flyers; i++){
|
|
Tmp.v1.trns(flyerRot, time * (flyerType.speed));
|
|
|
|
cons.get(
|
|
(Mathf.randomSeedRange(i, range) + Tmp.v1.x + Mathf.absin(time + Mathf.randomSeedRange(i + 2, 500), 10f, 3.4f) + offset) % (tw + Mathf.randomSeed(i + 5, 0, 500)),
|
|
(Mathf.randomSeedRange(i + 1, range) + Tmp.v1.y + Mathf.absin(time + Mathf.randomSeedRange(i + 3, 500), 10f, 3.4f) + offset) % th
|
|
);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void dispose(){
|
|
batch.dispose();
|
|
shadows.dispose();
|
|
}
|
|
}
|