diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index ccea7515da..535f5a8965 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -78,13 +78,12 @@ schematic.tagexists = That tag already exists. stats = Stats stat.wave = Waves Defeated:[accent] {0} +stat.unitsCreated = Units Created:[accent] {0} stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} stat.built = Buildings Built:[accent] {0} stat.destroyed = Buildings Destroyed:[accent] {0} stat.deconstructed = Buildings Deconstructed:[accent] {0} -stat.delivered = Resources Launched: stat.playtime = Time Played:[accent] {0} -stat.rank = Final Rank: [accent]{0} globalitems = [accent]Total Items map.delete = Are you sure you want to delete the map "[accent]{0}[]"? @@ -385,6 +384,7 @@ waves.waves = wave(s) waves.perspawn = per spawn waves.shields = shields/wave waves.to = to +waves.max = max units waves.guardian = Guardian waves.preview = Preview waves.edit = Edit... diff --git a/core/assets/sounds/wind3.ogg b/core/assets/sounds/wind3.ogg new file mode 100644 index 0000000000..35e732725b Binary files /dev/null and b/core/assets/sounds/wind3.ogg differ diff --git a/core/src/mindustry/ai/BlockIndexer.java b/core/src/mindustry/ai/BlockIndexer.java index f91aa89e11..519720e4ac 100644 --- a/core/src/mindustry/ai/BlockIndexer.java +++ b/core/src/mindustry/ai/BlockIndexer.java @@ -202,15 +202,20 @@ public class BlockIndexer{ } public boolean eachBlock(@Nullable Team team, float wx, float wy, float range, Boolf pred, Cons cons){ - breturnArray.clear(); if(team == null){ + returnBool = false; + allBuildings(wx, wy, range, b -> { if(pred.get(b)){ - breturnArray.add(b); + returnBool = true; + cons.get(b); } }); + return returnBool; }else{ + breturnArray.clear(); + var buildings = team.data().buildings; if(buildings == null) return false; buildings.intersect(wx - range, wy - range, range*2f, range*2f, b -> { diff --git a/core/src/mindustry/ai/types/GroundAI.java b/core/src/mindustry/ai/types/GroundAI.java index 4ebdfe1595..05358ae5e8 100644 --- a/core/src/mindustry/ai/types/GroundAI.java +++ b/core/src/mindustry/ai/types/GroundAI.java @@ -2,7 +2,6 @@ package mindustry.ai.types; import arc.math.*; import mindustry.ai.*; -import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.world.*; @@ -49,13 +48,6 @@ public class GroundAI extends AIController{ unit.elevation = Mathf.approachDelta(unit.elevation, 0f, unit.type.riseSpeed); } - if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting){ - if(unit.type.hasWeapons()){ - unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed)); - } - }else if(unit.moving()){ - unit.lookAt(unit.vel().angle()); - } - + faceTarget(); } } diff --git a/core/src/mindustry/ai/types/HugAI.java b/core/src/mindustry/ai/types/HugAI.java index 76acdec8c8..70d2bce36e 100644 --- a/core/src/mindustry/ai/types/HugAI.java +++ b/core/src/mindustry/ai/types/HugAI.java @@ -47,10 +47,10 @@ public class HugAI extends AIController{ })){ if(unit.within(target, (unit.hitSize + (target instanceof Sized s ? s.hitSize() : 1f)) * 0.6f)){ //circle target - unit.moveAt(vec.set(target).sub(unit).rotate(90f).setLength(unit.speed())); + unit.movePref(vec.set(target).sub(unit).rotate(90f).setLength(unit.speed())); }else{ //move toward target in a straight line - unit.moveAt(vec.set(target).sub(unit).limit(unit.speed())); + unit.movePref(vec.set(target).sub(unit).limit(unit.speed())); } }else if(move){ pathfind(Pathfinder.fieldCore); @@ -69,13 +69,6 @@ public class HugAI extends AIController{ unit.elevation = Mathf.approachDelta(unit.elevation, 0f, unit.type.riseSpeed); } - if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting){ - if(unit.type.hasWeapons()){ - unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed)); - } - }else if(unit.moving()){ - unit.lookAt(unit.vel().angle()); - } - + faceTarget(); } } diff --git a/core/src/mindustry/ai/types/SuicideAI.java b/core/src/mindustry/ai/types/SuicideAI.java index 1db94b95b0..70e365e775 100644 --- a/core/src/mindustry/ai/types/SuicideAI.java +++ b/core/src/mindustry/ai/types/SuicideAI.java @@ -41,10 +41,6 @@ public class SuicideAI extends GroundAI{ shoot = unit.within(target, unit.type.weapons.first().bullet.range() + (target instanceof Building b ? b.block.size * Vars.tilesize / 2f : ((Hitboxc)target).hitSize() / 2f)); - if(unit.type.hasWeapons()){ - unit.aimLook(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed)); - } - //do not move toward walls or transport blocks if(!(target instanceof Building build && !(build.block instanceof CoreBlock) && ( build.block.group == BlockGroup.walls || @@ -76,7 +72,7 @@ public class SuicideAI extends GroundAI{ if(!blocked){ moveToTarget = true; //move towards target directly - unit.moveAt(vec.set(target).sub(unit).limit(unit.speed())); + unit.movePref(vec.set(target).sub(unit).limit(unit.speed())); } } } @@ -103,11 +99,11 @@ public class SuicideAI extends GroundAI{ pathfind(Pathfinder.fieldCore); } } - - if(unit.moving()) unit.lookAt(unit.vel().angle()); } unit.controlWeapons(rotate, shoot); + + faceTarget(); } @Override diff --git a/core/src/mindustry/content/StatusEffects.java b/core/src/mindustry/content/StatusEffects.java index 710995d4a1..0a93c2103c 100644 --- a/core/src/mindustry/content/StatusEffects.java +++ b/core/src/mindustry/content/StatusEffects.java @@ -164,7 +164,7 @@ public class StatusEffects implements ContentList{ }}; boss = new StatusEffect("boss"){{ - color = Team.sharded.color; + color = Team.crux.color; permanent = true; damageMultiplier = 1.3f; healthMultiplier = 1.5f; diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index c8ec84674f..08c811f0f1 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -172,13 +172,19 @@ public class Control implements ApplicationListener, Loadable{ Events.on(BlockDestroyEvent.class, e -> { if(e.tile.team() == player.team()){ - state.stats.buildingsDestroyed++; + state.stats.buildingsDestroyed ++; } }); Events.on(UnitDestroyEvent.class, e -> { if(e.unit.team() != player.team()){ - state.stats.enemyUnitsDestroyed++; + state.stats.enemyUnitsDestroyed ++; + } + }); + + Events.on(UnitCreateEvent.class, e -> { + if(e.unit.team == state.rules.defaultTeam){ + state.stats.unitsCreated++; } }); diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index b557bbaf89..c45f076061 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -149,9 +149,17 @@ public abstract class UnlockableContent extends MappableContent{ } } + public boolean unlockedNowHost(){ + if(!state.isCampaign()) return true; + return net != null && net.client() ? + alwaysUnlocked || state.rules.researched.contains(name) : + unlocked || alwaysUnlocked; + } + public boolean unlocked(){ - if(net != null && net.client()) return alwaysUnlocked || state.rules.researched.contains(name); - return unlocked || alwaysUnlocked; + return net != null && net.client() ? + alwaysUnlocked || unlocked || state.rules.researched.contains(name) : + unlocked || alwaysUnlocked; } /** Locks this content again. */ diff --git a/core/src/mindustry/editor/MapResizeDialog.java b/core/src/mindustry/editor/MapResizeDialog.java index fe3e6eda06..b9925e14dc 100644 --- a/core/src/mindustry/editor/MapResizeDialog.java +++ b/core/src/mindustry/editor/MapResizeDialog.java @@ -15,6 +15,8 @@ public class MapResizeDialog extends BaseDialog{ public MapResizeDialog(Intc2 cons){ super("@editor.resizemap"); + + closeOnBack(); shown(() -> { cont.clear(); width = editor.width(); diff --git a/core/src/mindustry/editor/WaveInfoDialog.java b/core/src/mindustry/editor/WaveInfoDialog.java index 611c7e29ee..15049f7381 100644 --- a/core/src/mindustry/editor/WaveInfoDialog.java +++ b/core/src/mindustry/editor/WaveInfoDialog.java @@ -170,9 +170,8 @@ public class WaveInfoDialog extends BaseDialog{ t.remove(); updateWaves(); }).pad(-6).size(46f).padRight(-12f); - }, () -> showUpdate(group)).height(46f).pad(-6f).padBottom(0f); + }, () -> showUpdate(group)).height(46f).pad(-6f).padBottom(0f).row(); - t.row(); t.table(spawns -> { spawns.field("" + (group.begin + 1), TextFieldFilter.digitsOnly, text -> { if(Strings.canParsePositiveInt(text)){ @@ -190,8 +189,8 @@ public class WaveInfoDialog extends BaseDialog{ updateWaves(); } }).width(100f).get().setMessageText("∞"); - }); - t.row(); + }).row(); + t.table(p -> { p.add("@waves.every").padRight(4); p.field(group.spacing + "", TextFieldFilter.digitsOnly, text -> { @@ -201,9 +200,8 @@ public class WaveInfoDialog extends BaseDialog{ } }).width(100f); p.add("@waves.waves").padLeft(4); - }); + }).row(); - t.row(); t.table(a -> { a.field(group.unitAmount + "", TextFieldFilter.digitsOnly, text -> { if(Strings.canParsePositiveInt(text)){ @@ -220,8 +218,19 @@ public class WaveInfoDialog extends BaseDialog{ } }).width(80f); a.add("@waves.perspawn").padLeft(4); - }); - t.row(); + }).row(); + + t.table(a -> { + a.field(group.max + "", TextFieldFilter.digitsOnly, text -> { + if(Strings.canParsePositiveInt(text)){ + group.max = Strings.parseInt(text); + updateWaves(); + } + }).width(80f); + + a.add("@waves.max").padLeft(5); + }).row(); + t.table(a -> { a.field((int)group.shields + "", TextFieldFilter.digitsOnly, text -> { if(Strings.canParsePositiveInt(text)){ @@ -238,9 +247,8 @@ public class WaveInfoDialog extends BaseDialog{ } }).width(80f); a.add("@waves.shields").padLeft(4); - }); + }).row(); - t.row(); t.check("@waves.guardian", b -> group.effect = (b ? StatusEffects.boss : null)).padTop(4).update(b -> b.setChecked(group.effect == StatusEffects.boss)).padBottom(8f); }).width(340f).pad(8); diff --git a/core/src/mindustry/entities/abilities/UnitSpawnAbility.java b/core/src/mindustry/entities/abilities/UnitSpawnAbility.java index c3f826e5a5..04be58be39 100644 --- a/core/src/mindustry/entities/abilities/UnitSpawnAbility.java +++ b/core/src/mindustry/entities/abilities/UnitSpawnAbility.java @@ -7,6 +7,7 @@ import arc.util.*; import mindustry.*; import mindustry.content.*; import mindustry.entities.*; +import mindustry.game.EventType.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; @@ -40,6 +41,7 @@ public class UnitSpawnAbility extends Ability{ Unit u = this.unit.create(unit.team); u.set(x, y); u.rotation = unit.rotation; + Events.fire(new UnitCreateEvent(u, null, unit)); if(!Vars.net.client()){ u.add(); } diff --git a/core/src/mindustry/entities/comp/MechComp.java b/core/src/mindustry/entities/comp/MechComp.java index e8ed72974d..bd822d523b 100644 --- a/core/src/mindustry/entities/comp/MechComp.java +++ b/core/src/mindustry/entities/comp/MechComp.java @@ -76,6 +76,17 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati return raw; } + @Override + @Replace + public void rotateMove(Vec2 vec){ + //mechs use baseRotation to rotate, not rotation. + moveAt(Tmp.v2.trns(baseRotation, vec.len())); + + if(!vec.isZero()){ + baseRotation = Angles.moveToward(baseRotation, vec.angle(), type.rotateSpeed * Math.max(Time.delta, 1)); + } + } + @Override public void moveAt(Vec2 vector, float acceleration){ //mark walking state when moving in a controlled manner diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index ae4001d25f..ca168362d2 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -51,6 +51,15 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I private transient boolean wasPlayer; private transient boolean wasHealed; + /** Move based on preferred unit movement type. */ + public void movePref(Vec2 movement){ + if(type.omniMovement){ + moveAt(movement); + }else{ + rotateMove(movement); + } + } + public void moveAt(Vec2 vector){ moveAt(vector, type.accel); } diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 583691adaa..c06fe06d88 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -76,6 +76,23 @@ public class AIController implements UnitController{ } } + /** For ground units: Looks at the target, or the movement position. Does not apply to non-omni units. */ + public void faceTarget(){ + if(unit.type.omniMovement || unit instanceof Mechc){ + if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting && unit.type.hasWeapons()){ + unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed)); + }else if(unit.moving()){ + unit.lookAt(unit.vel().angle()); + } + } + } + + public void faceMovement(){ + if((unit.type.omniMovement || unit instanceof Mechc) && unit.moving()){ + unit.lookAt(unit.vel().angle()); + } + } + public boolean invalid(Teamc target){ return Units.invalidateTarget(target, unit.team, unit.x, unit.y); } @@ -89,7 +106,7 @@ public class AIController implements UnitController{ if(tile == targetTile || (costType == Pathfinder.costNaval && !targetTile.floor().isLiquid)) return; - unit.moveAt(vec.trns(unit.angleTo(targetTile.worldx(), targetTile.worldy()), unit.speed())); + unit.movePref(vec.trns(unit.angleTo(targetTile.worldx(), targetTile.worldy()), unit.speed())); } public void updateWeapons(){ diff --git a/core/src/mindustry/entities/units/UnitDecal.java b/core/src/mindustry/entities/units/UnitDecal.java new file mode 100644 index 0000000000..62a12e3c29 --- /dev/null +++ b/core/src/mindustry/entities/units/UnitDecal.java @@ -0,0 +1,25 @@ +package mindustry.entities.units; + +import arc.graphics.*; +import mindustry.graphics.*; + +/** A sprite drawn in addition to the base unit sprites. */ +public class UnitDecal{ + public String region = "error"; + public float x, y, rotation; + public float layer = Layer.flyingUnit + 1f; + public float xScale = 1f, yScale = 1f; + public Color color = Color.white; + + public UnitDecal(String region, float x, float y, float rotation, float layer, Color color){ + this.region = region; + this.x = x; + this.y = y; + this.rotation = rotation; + this.layer = layer; + this.color = color; + } + + public UnitDecal(){ + } +} diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index 5ff6a6f264..c72ffc403c 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -411,14 +411,20 @@ public class EventType{ } } - /** Called when a unit is created in a reconstructor or factory. */ + /** Called when a unit is created in a reconstructor, factory or other unit. */ public static class UnitCreateEvent{ public final Unit unit; - public final Building spawner; + public final @Nullable Building spawner; + public final @Nullable Unit spawnerUnit; - public UnitCreateEvent(Unit unit, Building spawner){ + public UnitCreateEvent(Unit unit, Building spawner, Unit spawnerUnit){ this.unit = unit; this.spawner = spawner; + this.spawnerUnit = spawnerUnit; + } + + public UnitCreateEvent(Unit unit, Building spawner){ + this(unit, spawner, null); } } diff --git a/core/src/mindustry/game/GameStats.java b/core/src/mindustry/game/GameStats.java index 19d404c802..5b54385e32 100644 --- a/core/src/mindustry/game/GameStats.java +++ b/core/src/mindustry/game/GameStats.java @@ -1,52 +1,16 @@ package mindustry.game; -import arc.math.*; -import arc.struct.*; -import mindustry.type.*; - -//TODO more stats: -//- units constructed public class GameStats{ - /** Total items delivered to global resoure counter. Campaign only. */ - public ObjectIntMap itemsDelivered = new ObjectIntMap<>(); /** Enemy (red team) units destroyed. */ public int enemyUnitsDestroyed; /** Total waves lasted. */ public int wavesLasted; - /** Total (ms) time lasted in this save/zone. */ - public long timeLasted; /** Friendly buildings fully built. */ public int buildingsBuilt; /** Friendly buildings fully deconstructed. */ public int buildingsDeconstructed; /** Friendly buildings destroyed. */ public int buildingsDestroyed; - - //unused - public RankResult calculateRank(Sector sector){ - float score = 0; - - int rankIndex = Mathf.clamp((int)score, 0, Rank.all.length - 1); - Rank rank = Rank.all[rankIndex]; - String sign = Math.abs((rankIndex + 0.5f) - score) < 0.2f || rank.name().contains("S") ? "" : (rankIndex + 0.5f) < score ? "-" : "+"; - - return new RankResult(rank, sign); - } - - public static class RankResult{ - public final Rank rank; - /** + or - */ - public final String modifier; - - public RankResult(Rank rank, String modifier){ - this.rank = rank; - this.modifier = modifier; - } - } - - public enum Rank{ - F, D, C, B, A, S, SS; - - public static final Rank[] all = values(); - } + /** Total units created by any means. */ + public int unitsCreated; } diff --git a/core/src/mindustry/graphics/MenuRenderer.java b/core/src/mindustry/graphics/MenuRenderer.java index 1cd431c7e8..57f435e945 100644 --- a/core/src/mindustry/graphics/MenuRenderer.java +++ b/core/src/mindustry/graphics/MenuRenderer.java @@ -29,7 +29,7 @@ public class MenuRenderer implements Disposable{ private float time = 0f; private float flyerRot = 45f; private int flyers = Mathf.chance(0.2) ? Mathf.random(35) : Mathf.random(15); - private UnitType flyerType = content.units().select(u -> u.hitSize <= 20f && u.flying && u.onTitleScreen && u.region.found()).random(); + private UnitType flyerType = content.units().select(u -> !u.isHidden() && u.hitSize <= 20f && u.flying && u.onTitleScreen && u.region.found()).random(); public MenuRenderer(){ Time.mark(); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index acb3795aff..6c247c50cf 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -642,11 +642,7 @@ public class DesktopInput extends InputHandler{ unit.lookAt(unit.prefRotation()); } - if(omni){ - unit.moveAt(movement); - }else{ - unit.rotateMove(movement); - } + unit.movePref(movement); unit.aim(unit.type.faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y)); unit.controlWeapons(true, player.shooting && !boosted); diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 2480cad5ab..be0de31ffa 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -919,11 +919,7 @@ public class MobileInput extends InputHandler implements GestureListener{ player.boosting = collisions.overlapsTile(rect) || !unit.within(targetPos, 85f); - if(omni){ - unit.moveAt(movement); - }else{ - unit.rotateMove(movement); - } + unit.movePref(movement); //update shooting if not building + not mining if(!player.unit().activelyBuilding() && player.unit().mineTile == null){ diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index c2b3fac347..f9ac8c2f05 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -447,7 +447,7 @@ public class LExecutor{ } } case build -> { - if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block){ + if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block && block.canBeBuilt()){ int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize); int rot = exec.numi(p4); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index ba8927329f..dc4312a2fa 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -77,6 +77,8 @@ public class UnitType extends UnlockableContent{ public Effect fallEffect = Fx.fallSmoke; public Effect fallThrusterEffect = Fx.fallSmoke; public Effect deathExplosionEffect = Fx.dynamicExplosion; + /** Additional sprites that are drawn with the unit. */ + public Seq decals = new Seq<>(); public Seq abilities = new Seq<>(); /** Flags to target based on priority. Null indicates that the closest target should be found. The closest enemy core is used as a fallback. */ public BlockFlag[] targetFlags = {null}; @@ -618,6 +620,18 @@ public class UnitType extends UnlockableContent{ unit.trns(-legOffset.x, -legOffset.y); } + if(decals.size > 0){ + float base = unit.rotation - 90; + for(var d : decals){ + Draw.z(d.layer); + Draw.scl(d.xScale, d.yScale); + Draw.color(d.color); + Draw.rect(d.region, unit.x + Angles.trnsx(base, d.x, d.y), unit.y + Angles.trnsy(base, d.x, d.y), base + d.rotation); + } + Draw.reset(); + Draw.z(z); + } + if(unit.abilities.size > 0){ for(Ability a : unit.abilities){ Draw.reset(); @@ -911,4 +925,5 @@ public class UnitType extends UnlockableContent{ } //endregion + } diff --git a/core/src/mindustry/ui/dialogs/GameOverDialog.java b/core/src/mindustry/ui/dialogs/GameOverDialog.java index 32e593ea0e..8ab6054b6b 100644 --- a/core/src/mindustry/ui/dialogs/GameOverDialog.java +++ b/core/src/mindustry/ui/dialogs/GameOverDialog.java @@ -4,7 +4,6 @@ import arc.*; import mindustry.core.GameState.*; import mindustry.game.EventType.*; import mindustry.game.*; -import mindustry.type.*; import static mindustry.Vars.*; @@ -52,6 +51,7 @@ public class GameOverDialog extends BaseDialog{ t.margin(13f); t.left().defaults().left(); t.add(Core.bundle.format("stat.wave", state.stats.wavesLasted)).row(); + t.add(Core.bundle.format("stat.unitsCreated", state.stats.unitsCreated)).row(); t.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed)).row(); t.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt)).row(); t.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed)).row(); @@ -59,17 +59,6 @@ public class GameOverDialog extends BaseDialog{ if(control.saves.getCurrent() != null){ t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime())).row(); } - if(state.isCampaign() && !state.stats.itemsDelivered.isEmpty()){ - t.add("@stat.delivered").row(); - for(Item item : content.items()){ - if(state.stats.itemsDelivered.get(item, 0) > 0){ - t.table(items -> { - items.add(" [lightgray]" + state.stats.itemsDelivered.get(item, 0)); - items.image(item.uiIcon).size(8 * 3).pad(4); - }).left().row(); - } - } - } if(state.isCampaign() && net.client()){ t.add("@gameover.waiting").padTop(20f).row(); diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 07dad51d9b..fbd6fa2ee9 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -540,7 +540,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ //sector notifications & search c.top().right(); - c.defaults().width(280f); + c.defaults().width(290f); c.button(bundle.get("sectorlist") + (attacked == 0 ? "" : "\n[red]⚠[lightgray] " + bundle.format("sectorlist.attacked", "[red]" + attacked + "[]")), @@ -588,6 +588,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ for(Sector sec : all){ if(sec.hasBase() && (searchText.isEmpty() || sec.name().toLowerCase().contains(searchText.toLowerCase()))){ con.button(t -> { + t.marginRight(10f); t.left(); t.defaults().growX(); diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index 8efa0f740e..66ec8f64d7 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -301,6 +301,8 @@ public class SettingsMenuDialog extends Dialog{ control.setInput(new DesktopInput()); input.setUseKeyboard(true); } + }else{ + Core.settings.put("keyboard", false); } } //the issue with touchscreen support on desktop is that: diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index d77e85e94d..278744c44e 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -303,7 +303,7 @@ public class ConstructBlock extends Block{ int accumulated = (int)(accumulator[i]); //get amount if(clampedAmount > 0 && accumulated > 0){ //if it's positive, add it to the core - if(core != null && requirements[i].item.unlockedNow()){ //only accept items that are unlocked + if(core != null && requirements[i].item.unlockedNowHost()){ //only accept items that are unlocked int accepting = Math.min(accumulated, core.storageCapacity - core.items.get(requirements[i].item)); //transfer items directly, as this is not production. core.items.add(requirements[i].item, accepting); diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 87b84dc58c..39bc9c949c 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -109,13 +109,15 @@ public class PowerNode extends PowerBlock{ Core.bundle.format("bar.powerbalance", ((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + UI.formatAmount((long)(entity.power.graph.getPowerBalance() * 60)))), () -> Pal.powerBar, - () -> Mathf.clamp(entity.power.graph.getLastPowerProduced() / entity.power.graph.getLastPowerNeeded()))); + () -> Mathf.clamp(entity.power.graph.getLastPowerProduced() / entity.power.graph.getLastPowerNeeded()) + )); bars.add("batteries", entity -> new Bar(() -> Core.bundle.format("bar.powerstored", (UI.formatAmount((long)entity.power.graph.getLastPowerStored())), UI.formatAmount((long)entity.power.graph.getLastCapacity())), () -> Pal.powerBar, - () -> Mathf.clamp(entity.power.graph.getLastPowerStored() / entity.power.graph.getLastCapacity()))); + () -> Mathf.clamp(entity.power.graph.getLastPowerStored() / entity.power.graph.getLastCapacity()) + )); bars.add("connections", entity -> new Bar(() -> Core.bundle.format("bar.powerlines", entity.power.links.size, maxNodes), diff --git a/core/src/mindustry/world/blocks/sandbox/PowerVoid.java b/core/src/mindustry/world/blocks/sandbox/PowerVoid.java index 93427b7e02..15fb0ac574 100644 --- a/core/src/mindustry/world/blocks/sandbox/PowerVoid.java +++ b/core/src/mindustry/world/blocks/sandbox/PowerVoid.java @@ -9,6 +9,7 @@ public class PowerVoid extends PowerBlock{ super(name); consumes.power(Float.MAX_VALUE); envEnabled = Env.any; + enableDrawStatus = false; } @Override diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index b8ee614f50..0d84db2fb5 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -126,7 +126,7 @@ public class Reconstructor extends UnitBlock{ var upgrade = upgrade(pay.unit.type); if(upgrade != null){ - if(!upgrade.unlockedNow()){ + if(!upgrade.unlockedNowHost()){ //flash "not researched" pay.showOverlay(Icon.tree); } @@ -137,7 +137,7 @@ public class Reconstructor extends UnitBlock{ } } - return upgrade != null && upgrade.unlockedNow() && !upgrade.isBanned(); + return upgrade != null && upgrade.unlockedNowHost() && !upgrade.isBanned(); } @Override @@ -232,7 +232,7 @@ public class Reconstructor extends UnitBlock{ if(payload == null) return null; UnitType t = upgrade(payload.unit.type); - return t != null && t.unlockedNow() ? t : null; + return t != null && t.unlockedNowHost() ? t : null; } public boolean constructing(){ @@ -241,7 +241,7 @@ public class Reconstructor extends UnitBlock{ public boolean hasUpgrade(UnitType type){ UnitType t = upgrade(type); - return t != null && t.unlockedNow() && !type.isBanned(); + return t != null && t.unlockedNowHost() && !type.isBanned(); } public UnitType upgrade(UnitType type){ diff --git a/core/src/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/mindustry/world/consumers/ConsumeItemFilter.java index b4346d0c6e..bc81cc9201 100644 --- a/core/src/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/mindustry/world/consumers/ConsumeItemFilter.java @@ -43,7 +43,6 @@ public class ConsumeItemFilter extends Consume{ @Override public void update(Building entity){ - } @Override diff --git a/servers_v7.json b/servers_v7.json index 0f33a7c392..8b26864eb3 100644 --- a/servers_v7.json +++ b/servers_v7.json @@ -13,7 +13,7 @@ }, { "name": "Omega", - "address": ["yeet.mindustry.me:2345", "yeet.mindustry.me:2076", "yeet.mindustry.me:2222","yeet.mindustry.me:6567", "yeet.mindustry.me:2054", "yeet.mindustry.me:3512"] + "address": ["yeet.mindustry.me:6567", "yeet.mindustry.me:2345", "n3.mindustry.me:4444","n2.mindustry.me:4040", "n2.mindustry.me:4002", "n2.mindustry.me:4001"] }, { "name": "MeowLand",