diff --git a/core/assets/maps/two.msav b/core/assets/maps/two.msav index 85399dc349..b5782042e7 100644 Binary files a/core/assets/maps/two.msav and b/core/assets/maps/two.msav differ diff --git a/core/src/mindustry/ai/BlockIndexer.java b/core/src/mindustry/ai/BlockIndexer.java index 333c5d6b4f..81c7a8457d 100644 --- a/core/src/mindustry/ai/BlockIndexer.java +++ b/core/src/mindustry/ai/BlockIndexer.java @@ -356,9 +356,9 @@ public class BlockIndexer{ float dist = candidate.dst(x, y) - candidate.hitSize() / 2f; if(target == null || //if its closer and is at least equal priority - (dist < targetDist && candidate.block.priority.ordinal() >= target.block.priority.ordinal()) || + (dist < targetDist && candidate.block.priority >= target.block.priority) || // block has higher priority (so range doesnt matter) - (candidate.block.priority.ordinal() > target.block.priority.ordinal())){ + (candidate.block.priority > target.block.priority)){ target = candidate; targetDist = dist; } @@ -388,9 +388,9 @@ public class BlockIndexer{ float bdst = next.dst(x, y) - next.hitSize() / 2f; if(bdst < range && (closest == null || //this one is closer, and it is at least of equal priority - (bdst < dst && (!usePriority || closest.block.priority.ordinal() <= next.block.priority.ordinal())) || + (bdst < dst && (!usePriority || closest.block.priority <= next.block.priority)) || //priority is used, and new block has higher priority regardless of range - (usePriority && closest.block.priority.ordinal() < next.block.priority.ordinal()))){ + (usePriority && closest.block.priority < next.block.priority))){ dst = bdst; closest = next; } diff --git a/core/src/mindustry/ai/Pathfinder.java b/core/src/mindustry/ai/Pathfinder.java index 05b6ec0a5f..2b81119e12 100644 --- a/core/src/mindustry/ai/Pathfinder.java +++ b/core/src/mindustry/ai/Pathfinder.java @@ -131,7 +131,7 @@ public class Pathfinder implements Runnable{ } } //the other tile is no longer near solid, remove the solid bit - if(!otherNearSolid){ + if(!otherNearSolid && tiles.length > other.array()){ tiles[other.array()] &= ~(PathTile.bitMaskNearSolid); } } diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index b635288352..4a048b97f9 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -182,6 +182,22 @@ public class Fx{ } }), + coreBuildShockwave = new Effect(120, 500f, e -> { + e.lifetime = e.rotation; + + color(Pal.command); + stroke(e.fout(Interp.pow5Out) * 4f); + Lines.circle(e.x, e.y, e.fin() * e.rotation); + }), + + coreBuildBlock = new Effect(80f, e -> { + if(!(e.data instanceof Block block)) return; + + mixcol(Pal.accent, 1f); + alpha(e.fout()); + rect(block.fullIcon, e.x, e.y); + }).layer(Layer.turret - 5f), + moveCommand = new Effect(20, e -> { color(Pal.command); stroke(e.fout() * 5f); diff --git a/core/src/mindustry/content/Planets.java b/core/src/mindustry/content/Planets.java index af7d055650..a68fd079e2 100644 --- a/core/src/mindustry/content/Planets.java +++ b/core/src/mindustry/content/Planets.java @@ -72,9 +72,9 @@ public class Planets{ r.attributes.set(Attribute.heat, 0.8f); r.showSpawns = true; r.fog = true; - r.staticFog = true; //TODO decide, is this a good idea? + r.staticFog = true; r.lighting = false; - r.onlyDepositCore = true; + r.onlyDepositCore = true; //TODO not sure }; unlockedOnLand.add(Blocks.coreBastion); diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 4b8a2f0b2e..0196147dcc 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -30,6 +30,7 @@ import mindustry.net.*; import mindustry.type.*; import mindustry.ui.dialogs.*; import mindustry.world.*; +import mindustry.world.blocks.storage.CoreBlock.*; import java.io.*; import java.text.*; @@ -207,7 +208,10 @@ public class Control implements ApplicationListener, Loadable{ camera.position.set(core); player.set(core); + float coreDelay = 0f; + if(!settings.getBool("skipcoreanimation")){ + coreDelay = coreLandDuration; //delay player respawn so animation can play. player.deathTimer = -80f; //TODO this sounds pretty bad due to conflict @@ -232,6 +236,47 @@ public class Control implements ApplicationListener, Loadable{ } }); } + + if(state.isCampaign()){ + + //TODO add a delay for landing. + if(state.rules.sector.planet.prebuildBase){ + float unitsPerTick = 1f; + + boolean anyBuilds = false; + for(Tile tile : world.tiles){ + var build = tile.build; + if(!(build instanceof CoreBuild) && build != null && build.team == state.rules.defaultTeam){ + var ccore = build.closestCore(); + + if(ccore != null && build.within(ccore, state.rules.enemyCoreBuildRadius)){ + build.pickedUp(); + build.tile.remove(); + anyBuilds = true; + + Time.run(build.dst(ccore) * unitsPerTick + coreDelay, () -> { + //TODO instance reuse bad? + build.tile.setBlock(build.block, build.team, build.rotation, () -> build); + + //TODO dropped bad? + build.dropped(); + + Fx.coreBuildBlock.at(build.x, build.y, 0f, build.block); + Fx.placeBlock.at(build.x, build.y, build.block.size); + }); + } + } + } + + if(anyBuilds){ + for(var ccore : state.rules.defaultTeam.data().cores){ + Time.run(coreDelay, () -> { + Fx.coreBuildShockwave.at(ccore.x, ccore.y, state.rules.enemyCoreBuildRadius); + }); + } + } + } + } }); } diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index f4a2780551..3074080e4b 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -126,7 +126,7 @@ public class Logic implements ApplicationListener{ state.rules.coreIncinerates = true; state.rules.waveTeam.rules().infiniteResources = true; - //fill enemy cores by default. + //fill enemy cores by default? TODO decide for(var core : state.rules.waveTeam.cores()){ for(Item item : content.items()){ core.items.set(item, core.block.itemCapacity); diff --git a/core/src/mindustry/entities/TargetPriority.java b/core/src/mindustry/entities/TargetPriority.java index b8b9757961..9528ae4a75 100644 --- a/core/src/mindustry/entities/TargetPriority.java +++ b/core/src/mindustry/entities/TargetPriority.java @@ -1,8 +1,10 @@ package mindustry.entities; -/** A higher ordinal means a higher priority. Higher priority blocks will always get targeted over those of lower priority, regardless of distance. */ -public enum TargetPriority{ - base, - turret, - core +/** Higher priority blocks will always get targeted over those of lower priority, regardless of distance. */ +public class TargetPriority{ + public static final float + base = 0f, + constructing = 1f, + turret = 2f, + core = 3f; } diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 8f9ff64f31..ed6501348a 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -264,7 +264,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, //region utility methods public void addPlan(boolean checkPrevious){ - if(!block.rebuildable || (team == state.rules.defaultTeam && state.isCampaign() && !block.isVisible())) return; + addPlan(checkPrevious, false); + } + + public void addPlan(boolean checkPrevious, boolean ignoreConditions){ + if(!ignoreConditions && (!block.rebuildable || (team == state.rules.defaultTeam && state.isCampaign() && !block.isVisible()))) return; Object overrideConfig = null; diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index 4d3d6f645e..49606742ff 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -95,6 +95,8 @@ public class Planet extends UnlockableContent{ public boolean allowSectorInvasion = false; /** If true, sectors saves are cleared when lost. */ public boolean clearSectorOnLose = false; + /** If true, blocks in the radius of the core will be removed and "built up" in a shockwave upon landing. */ + public boolean prebuildBase = true; /** If true, waves are created on sector loss. TODO remove. */ public boolean allowWaves = false; /** Sets up rules on game load for any sector on this planet. */ diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 8b24f851f6..5b035bffb6 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -178,8 +178,8 @@ public class Block extends UnlockableContent implements Senseable{ public BlockGroup group = BlockGroup.none; /** List of block flags. Used for AI indexing. */ public EnumSet flags = EnumSet.of(); - /** Targeting priority of this block, as seen by enemies .*/ - public TargetPriority priority = TargetPriority.base; + /** Targeting priority of this block, as seen by enemies. */ + public float priority = TargetPriority.base; /** How much this block affects the unit cap by. * The block flags must contain unitModifier in order for this to work. */ public int unitCapModifier = 0; diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index a5f220b9b8..1686383977 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -44,6 +44,7 @@ public class ConstructBlock extends Block{ inEditor = false; consBlocks[size - 1] = this; sync = true; + priority = TargetPriority.constructing; } /** Returns a ConstructBlock by size. */