diff --git a/core/assets/shaders/space.frag b/core/assets/shaders/space.frag index 1c13446c27..b071f9390c 100755 --- a/core/assets/shaders/space.frag +++ b/core/assets/shaders/space.frag @@ -1,6 +1,6 @@ #define HIGHP -#define NSCALE 1800.0 -#define CAMSCALE (NSCALE*1.1) +#define NSCALE 2700.0 +#define CAMSCALE (NSCALE*5) uniform sampler2D u_texture; uniform sampler2D u_stars; @@ -14,10 +14,10 @@ varying vec2 v_texCoords; void main(){ vec2 c = v_texCoords.xy; - vec2 coords = vec2(c.x * u_resolution.x + u_campos.x, c.y * u_resolution.y + u_campos.y); + vec2 coords = vec2(c.x * u_resolution.x, c.y * u_resolution.y); vec4 color = texture2D(u_texture, c); - color.rgb = texture2D(u_stars, coords / NSCALE + vec2(0.3, 0.3) - u_ccampos / CAMSCALE).rgb; + color.rgb = texture2D(u_stars, coords/NSCALE + vec2(-0.1, -0.1) + u_ccampos / CAMSCALE).rgb; gl_FragColor = color; } \ No newline at end of file diff --git a/core/assets/sprites/space.png b/core/assets/sprites/space.png index 0099b68f39..188e9e40ae 100644 Binary files a/core/assets/sprites/space.png and b/core/assets/sprites/space.png differ diff --git a/core/src/mindustry/ai/BaseRegistry.java b/core/src/mindustry/ai/BaseRegistry.java index d5922ac822..269b79d3bf 100644 --- a/core/src/mindustry/ai/BaseRegistry.java +++ b/core/src/mindustry/ai/BaseRegistry.java @@ -9,6 +9,7 @@ import mindustry.game.*; import mindustry.game.Schematic.*; import mindustry.type.*; import mindustry.world.*; +import mindustry.world.blocks.environment.*; import mindustry.world.blocks.production.*; import mindustry.world.blocks.sandbox.*; import mindustry.world.blocks.storage.*; @@ -19,9 +20,13 @@ import java.io.*; import static mindustry.Vars.*; public class BaseRegistry{ + /** cores, sorted by tier */ public Seq cores = new Seq<>(); + /** parts with no requirement */ public Seq parts = new Seq<>(); public ObjectMap> reqParts = new ObjectMap<>(); + public ObjectMap ores = new ObjectMap<>(); + public ObjectMap oreFloors = new ObjectMap<>(); public Seq forResource(Content item){ return reqParts.get(item, Seq::new); @@ -32,6 +37,15 @@ public class BaseRegistry{ parts.clear(); reqParts.clear(); + //load ore types and corresponding items + for(Block block : content.blocks()){ + if(block instanceof OreBlock && block.asFloor().itemDrop != null){ + ores.put(block.asFloor().itemDrop, (OreBlock)block); + }else if(block.isFloor() && block.asFloor().itemDrop != null && !oreFloors.containsKey(block.asFloor().itemDrop)){ + oreFloors.put(block.asFloor().itemDrop, block.asFloor()); + } + } + String[] names = Core.files.internal("basepartnames").readString().split("\n"); for(String name : names){ diff --git a/core/src/mindustry/entities/comp/WeaponsComp.java b/core/src/mindustry/entities/comp/WeaponsComp.java index 08d87081f6..d891dbc1e4 100644 --- a/core/src/mindustry/entities/comp/WeaponsComp.java +++ b/core/src/mindustry/entities/comp/WeaponsComp.java @@ -111,7 +111,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{ //update continuous state if(weapon.continuous && mount.bullet != null){ - if(!mount.bullet.isAdded() || mount.bullet.time >= mount.bullet.lifetime){ + if(!mount.bullet.isAdded() || mount.bullet.time >= mount.bullet.lifetime || mount.bullet.type != weapon.bullet){ mount.bullet = null; }else{ mount.bullet.rotation(weaponRotation + 90); diff --git a/core/src/mindustry/graphics/Shaders.java b/core/src/mindustry/graphics/Shaders.java index 61506ba545..9cb7b3c5f7 100644 --- a/core/src/mindustry/graphics/Shaders.java +++ b/core/src/mindustry/graphics/Shaders.java @@ -213,9 +213,9 @@ public class Shaders{ @Override public void apply(){ - setUniformf("u_campos", Core.camera.position.x - Core.camera.width / 2, Core.camera.position.y - Core.camera.height / 2); + setUniformf("u_campos", Core.camera.position.x, Core.camera.position.y); setUniformf("u_ccampos", Core.camera.position); - setUniformf("u_resolution", Core.camera.width, Core.camera.height); + setUniformf("u_resolution", Core.graphics.getWidth(), Core.graphics.getHeight()); setUniformf("u_time", Time.time()); texture.bind(1); diff --git a/core/src/mindustry/maps/generators/BaseGenerator.java b/core/src/mindustry/maps/generators/BaseGenerator.java index d8965014b7..3a28078f74 100644 --- a/core/src/mindustry/maps/generators/BaseGenerator.java +++ b/core/src/mindustry/maps/generators/BaseGenerator.java @@ -4,6 +4,7 @@ import arc.func.*; import arc.math.*; import arc.math.geom.*; import arc.struct.*; +import arc.util.*; import mindustry.ai.BaseRegistry.*; import mindustry.content.*; import mindustry.game.*; @@ -12,7 +13,6 @@ import mindustry.gen.*; import mindustry.type.*; import mindustry.world.*; import mindustry.world.blocks.defense.*; -import mindustry.world.blocks.environment.*; import mindustry.world.blocks.power.*; import mindustry.world.blocks.production.*; import mindustry.world.meta.*; @@ -26,8 +26,6 @@ public class BaseGenerator{ private Tiles tiles; private Team team; - private ObjectMap ores = new ObjectMap<>(); - private ObjectMap oreFloors = new ObjectMap<>(); private Seq cores; public void generate(Tiles tiles, Seq cores, Tile spawn, Team team, Sector sector, float difficulty){ @@ -40,14 +38,6 @@ public class BaseGenerator{ Mathf.rand.setSeed(sector.id); - for(Block block : content.blocks()){ - if(block instanceof OreBlock && block.asFloor().itemDrop != null){ - ores.put(block.asFloor().itemDrop, (OreBlock)block); - }else if(block.isFloor() && block.asFloor().itemDrop != null && !oreFloors.containsKey(block.asFloor().itemDrop)){ - oreFloors.put(block.asFloor().itemDrop, block.asFloor()); - } - } - //TODO limit base size float costBudget = 1000; @@ -70,7 +60,7 @@ public class BaseGenerator{ for(Tile tile : cores){ tile.clearOverlay(); - Schematics.placeLoadout(coreschem.schematic, tile.x, tile.y, team, coreschem.required instanceof Item ? ores.get((Item)coreschem.required) : Blocks.oreCopper); + Schematics.placeLoadout(coreschem.schematic, tile.x, tile.y, team, coreschem.required instanceof Item ? bases.ores.get((Item)coreschem.required) : Blocks.oreCopper); //fill core with every type of item (even non-material) Building entity = tile.build; @@ -87,10 +77,10 @@ public class BaseGenerator{ || (tile.floor().liquidDrop != null && Mathf.chance(nonResourceChance * 2))) && Mathf.chance(resourceChance)){ Seq parts = bases.forResource(tile.drop() != null ? tile.drop() : tile.floor().liquidDrop); if(!parts.isEmpty()){ - tryPlace(parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y); + tryPlace(parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y, team); } }else if(Mathf.chance(nonResourceChance)){ - tryPlace(bases.parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y); + tryPlace(bases.parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y, team); } }); @@ -164,7 +154,19 @@ public class BaseGenerator{ core.circle(range, (x, y) -> cons.get(tiles.getn(x, y))); } - boolean tryPlace(BasePart part, int x, int y){ + /** + * Tries to place a base part at a certain location with a certain team. + * @return success state + * */ + public static boolean tryPlace(BasePart part, int x, int y, Team team){ + return tryPlace(part, x, y, team, null); + } + + /** + * Tries to place a base part at a certain location with a certain team. + * @return success state + * */ + public static boolean tryPlace(BasePart part, int x, int y, Team team, @Nullable Intc2 posc){ int rotation = Mathf.range(2); axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f)); Schematic result = Schematics.rotate(part.schematic, rotation); @@ -180,6 +182,10 @@ public class BaseGenerator{ if(isTaken(tile.block, realX, realY)){ return false; } + + if(posc != null){ + posc.get(realX, realY); + } } if(part.required instanceof Item item){ @@ -188,11 +194,11 @@ public class BaseGenerator{ tile.block.iterateTaken(tile.x + cx, tile.y + cy, (ex, ey) -> { - if(tiles.getn(ex, ey).floor().hasSurface()){ - set(tiles.getn(ex, ey), item); + if(world.tiles.getn(ex, ey).floor().hasSurface()){ + set(world.tiles.getn(ex, ey), item); } - Tile rand = tiles.getc(ex + Mathf.range(1), ey + Mathf.range(1)); + Tile rand = world.tiles.getc(ex + Mathf.range(1), ey + Mathf.range(1)); if(rand.floor().hasSurface()){ //random ores nearby to make it look more natural set(rand, item); @@ -221,15 +227,15 @@ public class BaseGenerator{ return true; } - void set(Tile tile, Item item){ - if(ores.containsKey(item)){ - tile.setOverlay(ores.get(item)); - }else if(oreFloors.containsKey(item)){ - tile.setFloor(oreFloors.get(item)); + static void set(Tile tile, Item item){ + if(bases.ores.containsKey(item)){ + tile.setOverlay(bases.ores.get(item)); + }else if(bases.oreFloors.containsKey(item)){ + tile.setFloor(bases.oreFloors.get(item)); } } - boolean isTaken(Block block, int x, int y){ + static boolean isTaken(Block block, int x, int y){ int offsetx = -(block.size - 1) / 2; int offsety = -(block.size - 1) / 2; int pad = 1; @@ -245,8 +251,8 @@ public class BaseGenerator{ return false; } - boolean overlaps(int x, int y){ - Tile tile = tiles.get(x, y); + static boolean overlaps(int x, int y){ + Tile tile = world.tiles.get(x, y); return tile == null || !tile.block().alwaysReplace || world.getDarkness(x, y) > 0; } diff --git a/core/src/mindustry/maps/generators/PlanetGenerator.java b/core/src/mindustry/maps/generators/PlanetGenerator.java index 6bbc15ed2f..2f0bd37058 100644 --- a/core/src/mindustry/maps/generators/PlanetGenerator.java +++ b/core/src/mindustry/maps/generators/PlanetGenerator.java @@ -1,6 +1,7 @@ package mindustry.maps.generators; import arc.math.geom.*; +import arc.struct.*; import arc.util.noise.*; import mindustry.graphics.g3d.*; import mindustry.graphics.g3d.PlanetGrid.*; @@ -8,6 +9,7 @@ import mindustry.type.*; import mindustry.world.*; public abstract class PlanetGenerator extends BasicGenerator implements HexMesher{ + protected IntSeq ints = new IntSeq(); protected Sector sector; /** Should generate sector bases for a planet. */ diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java index f9d33df5f0..e4f49f29e6 100644 --- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java @@ -7,6 +7,7 @@ import arc.struct.*; import arc.util.*; import arc.util.noise.*; import mindustry.ai.*; +import mindustry.ai.BaseRegistry.*; import mindustry.content.*; import mindustry.game.*; import mindustry.maps.generators.*; @@ -261,10 +262,21 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ tech(); pass((x, y) -> { + //random moss if(floor == Blocks.sporeMoss && rand.chance(0.9)){ floor = Blocks.moss; } + //tar + if(floor == Blocks.darksand){ + if(Math.abs(0.5f - noise(x - 40, y, 2, 0.7, 80)) > 0.25f && + Math.abs(0.5f - noise(x, y + sector.id*10, 1, 1, 60)) > 0.41f){ + floor = Blocks.tar; + ore = Blocks.air; + } + } + + //hotrock tweaks if(floor == Blocks.hotrock){ if(rand.chance(0.3)){ floor = Blocks.basalt; @@ -298,9 +310,84 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ } }); - Schematics.placeLaunchLoadout(spawn.x, spawn.y); - float difficulty = sector.baseCoverage; + ints.clear(); + ints.ensureCapacity(width * height / 4); + + int ruinCount = rand.random(-2, 4); + if(ruinCount > 0){ + int padding = 25; + + //create list of potential positions + for(int x = padding; x < width - padding; x++){ + for(int y = padding; y < height - padding; y++){ + Tile tile = tiles.getn(x, y); + if(!tile.solid() && (tile.drop() != null || tile.floor().liquidDrop != null)){ + ints.add(tile.pos()); + } + } + } + + ints.shuffle(rand); + + int placed = 0; + float diffRange = 0.4f; + //try each position + for(int i = 0; i < ints.size && placed < ruinCount; i++){ + int val = ints.items[i]; + int x = Point2.x(val), y = Point2.y(val); + + //do not overwrite player spawn + if(Mathf.within(x, y, spawn.x, spawn.y, 18f)){ + continue; + } + + float range = difficulty + rand.random(diffRange); + + Tile tile = tiles.getn(x, y); + BasePart part = null; + if(tile.overlay().itemDrop != null){ + part = bases.forResource(tile.drop()).getFrac(range); + }else if(tile.floor().liquidDrop != null && rand.chance(0.05)){ + part = bases.forResource(tile.floor().liquidDrop).getFrac(range); + }else if(rand.chance(0.05)){ //ore-less parts are less likely to occur. + part = bases.parts.getFrac(range); + } + + //actually place the part + if(part != null && BaseGenerator.tryPlace(part, x, y, Team.derelict, (cx, cy) -> { + Tile other = tiles.getn(cx, cy); + other.setOverlay(Blocks.oreScrap); + for(int j = 1; j <= 2; j++){ + for(Point2 p : Geometry.d8){ + Tile t = tiles.get(cx + p.x*j, cy + p.y*j); + if(t != null && t.floor().hasSurface() && rand.chance(j == 1 ? 0.4 : 0.2)){ + t.setOverlay(Blocks.oreScrap); + } + } + } + })){ + placed ++; + + int debrisRadius = Math.max(part.schematic.width, part.schematic.height)/2 + 3; + Geometry.circle(x, y, tiles.width, tiles.height, debrisRadius, (cx, cy) -> { + float dst = Mathf.dst(cx, cy, x, y); + float removeChance = Mathf.lerp(0.05f, 0.5f, dst / debrisRadius); + + Tile other = tiles.getn(cx, cy); + if(other.build != null && other.isCenter()){ + if(other.team() == Team.derelict && rand.chance(removeChance)){ + other.remove(); + }else if(rand.chance(0.5)){ + other.build.health = other.build.health - rand.random(other.build.health * 0.9f); + } + } + }); + } + } + } + + Schematics.placeLaunchLoadout(spawn.x, spawn.y); if(sector.hasEnemyBase()){ basegen.generate(tiles, enemies.map(r -> tiles.getn(r.x, r.y)), tiles.get(spawn.x, spawn.y), state.rules.waveTeam, sector, difficulty); diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index 8ee4447079..38ae0cd1f2 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -262,6 +262,7 @@ public class HudFragment extends Fragment{ }); t.top().visible(() -> { + if(!shown) return false; if(state.isMenu() || !state.teams.get(player.team()).hasCore()){ coreAttackTime[0] = 0f; return false;