diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 4c8606ea07..a948e0b3bb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -17,7 +17,9 @@ assignees: '' **Link(s) to mod(s) used**: *The mod repositories or zip files that are related to the issue, if applicable.* -**Save file**: *The (zipped) save file you were playing on when the bug happened. THIS IS REQUIRED FOR ANY ISSUE HAPPENING IN-GAME, REGARDLESS OF WHETHER YOU THINK IT HAPPENS EVERYWHERE. DO NOT DELETE OR OMIT THIS LINE UNLESS YOU ARE SURE THAT THE ISSUE DOES NOT HAPPEN IN-GAME.* +**Save file**: *The (zipped) save file you were playing on when the bug happened. THIS IS REQUIRED FOR ANY ISSUE HAPPENING IN-GAME OR IN MULTIPLAYER, REGARDLESS OF WHETHER YOU THINK IT HAPPENS EVERYWHERE. DO NOT DELETE OR OMIT THIS LINE UNLESS YOU ARE SURE THAT THE ISSUE DOES NOT HAPPEN IN-GAME.* + +If you remove the line above without reading it properly and understanding what it means, I will reap your soul. Even if you're playing on someone's server, you can still save the game to a slot. **Crash report**: *The contents of relevant crash report files. REQUIRED if you are reporting a crash.* diff --git a/core/assets/maps/planetaryTerminal.msav b/core/assets/maps/planetaryTerminal.msav index f5a7df9a00..7c45ebfca2 100644 Binary files a/core/assets/maps/planetaryTerminal.msav and b/core/assets/maps/planetaryTerminal.msav differ diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index d0995ca3a8..d5b9778f67 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -47,6 +47,8 @@ public class Vars implements Loadable{ public static final int bufferSize = 8192; /** global charset, since Android doesn't support the Charsets class */ public static final Charset charset = Charset.forName("UTF-8"); + /** mods suggested for import */ + public static final String[] suggestedMods = {""}; /** main application name, capitalized */ public static final String appName = "Mindustry"; /** URL for itch.io donations. */ @@ -56,7 +58,7 @@ public class Vars implements Loadable{ /** URL for sending crash reports to */ public static final String crashReportURL = "http://192.99.169.18/report"; /** URL the links to the wiki's modding guide.*/ - public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/"; + public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/"; /** URL to the JSON file containing all the global, public servers. Not queried in BE. */ public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json"; /** URL to the JSON file containing all the BE servers. Only queried in BE. */ diff --git a/core/src/mindustry/ai/Pathfinder.java b/core/src/mindustry/ai/Pathfinder.java index 392481b3ac..c5b03f40bd 100644 --- a/core/src/mindustry/ai/Pathfinder.java +++ b/core/src/mindustry/ai/Pathfinder.java @@ -13,6 +13,7 @@ import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.world.*; +import mindustry.world.blocks.storage.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -115,7 +116,7 @@ public class Pathfinder implements Runnable{ } return PathTile.get( - tile.build == null || !tile.solid() ? 0 : Math.min((int)(tile.build.health / 40), 80), + tile.build == null || !tile.solid() || tile.block() instanceof CoreBlock ? 0 : Math.min((int)(tile.build.health / 40), 80), tile.getTeamID(), tile.solid(), tile.floor().isLiquid, @@ -458,7 +459,7 @@ public class Pathfinder implements Runnable{ /** costs of getting to a specific tile */ public int[][] weights; /** search IDs of each position - the highest, most recent search is prioritized and overwritten */ - int[][] searches; + public int[][] searches; /** search frontier, these are Pos objects */ IntQueue frontier = new IntQueue(); /** all target positions; these positions have a cost of 0, and must be synchronized on! */ diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index ca74a26868..e053a8ee65 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1657,6 +1657,7 @@ public class UnitTypes implements ContentList{ recoil = 3f; occlusion = 12f; ejectEffect = Fx.casing3; + shootSound = Sounds.shootBig; shots = 3; shotDelay = 4f; diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 4f4f45bd64..c67572d559 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -340,7 +340,7 @@ public class Control implements ApplicationListener, Loadable{ state.rules.waves = true; //reset win wave?? - state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : 40; + state.rules.winWave = state.rules.attackMode ? -1 : sector.preset != null ? sector.preset.captureWave : state.rules.winWave > state.wave ? state.rules.winWave : 40; //if there's still an enemy base left, fix it if(state.rules.attackMode){ diff --git a/core/src/mindustry/core/UI.java b/core/src/mindustry/core/UI.java index 4437bb4d48..3b7504be6d 100644 --- a/core/src/mindustry/core/UI.java +++ b/core/src/mindustry/core/UI.java @@ -258,11 +258,11 @@ public class UI implements ApplicationListener, Loadable{ TextField field = cont.field(def, t -> {}).size(330f, 50f).get(); field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c)); buttons.defaults().size(120, 54).pad(4); + buttons.button("@cancel", this::hide); buttons.button("@ok", () -> { confirmed.get(field.getText()); hide(); }).disabled(b -> field.getText().isEmpty()); - buttons.button("@cancel", this::hide); keyDown(KeyCode.enter, () -> { String text = field.getText(); if(!text.isEmpty()){ diff --git a/core/src/mindustry/entities/Lightning.java b/core/src/mindustry/entities/Lightning.java index 61f42f2e72..ce5a3f97da 100644 --- a/core/src/mindustry/entities/Lightning.java +++ b/core/src/mindustry/entities/Lightning.java @@ -53,7 +53,7 @@ public class Lightning{ world.raycastEach(World.toTile(from.getX()), World.toTile(from.getY()), World.toTile(to.getX()), World.toTile(to.getY()), (wx, wy) -> { Tile tile = world.tile(wx, wy); - if(tile != null && tile.block().insulated){ + if(tile != null && tile.block().insulated && tile.team() != team){ bhit = true; //snap it instead of removing lines.get(lines.size -1).set(wx * tilesize, wy * tilesize); diff --git a/core/src/mindustry/entities/abilities/RepairFieldAbility.java b/core/src/mindustry/entities/abilities/RepairFieldAbility.java index 8df0a96e2c..9e2890589a 100644 --- a/core/src/mindustry/entities/abilities/RepairFieldAbility.java +++ b/core/src/mindustry/entities/abilities/RepairFieldAbility.java @@ -30,7 +30,7 @@ public class RepairFieldAbility extends Ability{ Units.nearby(unit.team, unit.x, unit.y, range, other -> { if(other.damaged()){ - healEffect.at(unit); + healEffect.at(other); wasHealed = true; } other.heal(amount); diff --git a/core/src/mindustry/entities/comp/BoundedComp.java b/core/src/mindustry/entities/comp/BoundedComp.java index c266ae3e51..c02d34a760 100644 --- a/core/src/mindustry/entities/comp/BoundedComp.java +++ b/core/src/mindustry/entities/comp/BoundedComp.java @@ -16,11 +16,13 @@ abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{ @Override public void update(){ - //repel unit out of bounds - if(x < 0) vel.x += (-x/warpDst); - if(y < 0) vel.y += (-y/warpDst); - if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst; - if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst; + if(!net.client() || isLocal()){ + //repel unit out of bounds + if(x < 0) vel.x += (-x/warpDst); + if(y < 0) vel.y += (-y/warpDst); + if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst; + if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/warpDst; + } //clamp position if not flying if(isGrounded()){ diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index a1e218c05a..b39ed5baef 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -11,6 +11,7 @@ import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; +import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; @@ -28,6 +29,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ @Import float x, y, rotation; @Import UnitType type; + @Import Team team; @SyncLocal Queue plans = new Queue<>(1); @SyncLocal transient boolean updateBuilding = true; @@ -75,27 +77,27 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ Tile tile = world.tile(current.x, current.y); if(!(tile.block() instanceof ConstructBlock)){ - if(!current.initialized && !current.breaking && Build.validPlace(current.block, team(), current.x, current.y, current.rotation)){ + if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){ boolean hasAll = infinite || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item)); if(hasAll){ - Call.beginPlace(current.block, team(), current.x, current.y, current.rotation); + Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation); }else{ current.stuck = true; } - }else if(!current.initialized && current.breaking && Build.validBreak(team(), current.x, current.y)){ - Call.beginBreak(team(), current.x, current.y); + }else if(!current.initialized && current.breaking && Build.validBreak(team, current.x, current.y)){ + Call.beginBreak(self(), team, current.x, current.y); }else{ plans.removeFirst(); return; } - }else if(tile.team() != team()){ + }else if(tile.team() != team){ plans.removeFirst(); return; } if(tile.build instanceof ConstructBuild && !current.initialized){ - Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team(), (Builderc)this, current.breaking))); + Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team, self(), current.breaking))); current.initialized = true; } @@ -128,7 +130,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ control.input.drawBreaking(request); }else{ request.block.drawRequest(request, control.input.allRequests(), - Build.validPlace(request.block, team(), request.x, request.y, request.rotation) || control.input.requestMatches(request)); + Build.validPlace(request.block, team, request.x, request.y, request.rotation) || control.input.requestMatches(request)); } } @@ -138,7 +140,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ /** @return whether this request should be skipped, in favor of the next one. */ boolean shouldSkip(BuildPlan request, @Nullable Building core){ //requests that you have at least *started* are considered - if(state.rules.infiniteResources || team().rules().infiniteResources || request.breaking || core == null) return false; + if(state.rules.infiniteResources || team.rules().infiniteResources || request.breaking || core == null) return false; return (request.stuck && !core.items.has(request.block.requirements)) || (Structs.contains(request.block.requirements, i -> !core.items.has(i.item) && Mathf.round(i.amount * state.rules.buildCostMultiplier) > 0) && !request.initialized); } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 3854876873..b2f81d5526 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -90,8 +90,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I public float prefRotation(){ if(activelyBuilding()){ return angleTo(buildPlan()); - }else if(mineTile() != null){ - return angleTo(mineTile()); + }else if(mineTile != null){ + return angleTo(mineTile); }else if(moving()){ return vel().angle(); } @@ -310,7 +310,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f); //apply knockback based on spawns - if(team != state.rules.waveTeam && state.hasSpawns()){ + if(team != state.rules.waveTeam && state.hasSpawns() && (!net.client() || isLocal())){ float relativeSize = state.rules.dropZoneRadius + hitSize/2f + 1f; for(Tile spawn : spawner.getSpawns()){ if(within(spawn.worldx(), spawn.worldy(), relativeSize)){ diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index f0aa3278b2..3fd2826cb5 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -278,11 +278,13 @@ public class EventType{ public static class BlockBuildBeginEvent{ public final Tile tile; public final Team team; + public final @Nullable Unit unit; public final boolean breaking; - public BlockBuildBeginEvent(Tile tile, Team team, boolean breaking){ + public BlockBuildBeginEvent(Tile tile, Team team, Unit unit, boolean breaking){ this.tile = tile; this.team = team; + this.unit = unit; this.breaking = breaking; } } @@ -310,10 +312,10 @@ public class EventType{ public static class BuildSelectEvent{ public final Tile tile; public final Team team; - public final Builderc builder; + public final Unit builder; public final boolean breaking; - public BuildSelectEvent(Tile tile, Team team, Builderc builder, boolean breaking){ + public BuildSelectEvent(Tile tile, Team team, Unit builder, boolean breaking){ this.tile = tile; this.team = team; this.builder = builder; diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index 0aa1407879..3d12e5ec5f 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -225,9 +225,11 @@ public class Universe{ if(sector.isBeingPlayed()){ state.rules.winWave = waveMax; state.rules.waves = true; + state.rules.attackMode = false; }else{ sector.info.winWave = waveMax; sector.info.waves = true; + sector.info.attack = false; sector.saveInfo(); } diff --git a/core/src/mindustry/graphics/g3d/PlanetRenderer.java b/core/src/mindustry/graphics/g3d/PlanetRenderer.java index 46fcef4edf..95a2abd9e7 100644 --- a/core/src/mindustry/graphics/g3d/PlanetRenderer.java +++ b/core/src/mindustry/graphics/g3d/PlanetRenderer.java @@ -37,6 +37,7 @@ public class PlanetRenderer implements Disposable{ public final VertexBatch3D batch = new VertexBatch3D(20000, false, true, 0); public float zoom = 1f; + public float orbitAlpha = 1f; private final Mesh[] outlines = new Mesh[10]; public final PlaneBatch3D projector = new PlaneBatch3D(); @@ -168,7 +169,7 @@ public class PlanetRenderer implements Disposable{ Vec3 center = planet.parent.position; float radius = planet.orbitRadius; int points = (int)(radius * 10); - Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray)); + Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray.write(Tmp.c1).a(orbitAlpha))); batch.flush(Gl.lineLoop); } diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index ddc84131ba..ad0e6b32f9 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -629,8 +629,8 @@ public class DesktopInput extends InputHandler{ unit.moveAt(movement); }else{ unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); - if(!movement.isZero() && ground){ - unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed); + if(!movement.isZero()){ + unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1)); } } diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 8baf077073..5d0284abf7 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -769,7 +769,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public boolean pan(float x, float y, float deltaX, float deltaY){ - if(Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false; + if(Core.scene == null || Core.scene.hasDialog() || Core.settings.getBool("keyboard")) return false; float scale = Core.camera.width / Core.graphics.getWidth(); deltaX *= scale; @@ -836,7 +836,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(type == null) return; boolean omni = unit.type.omniMovement; - boolean legs = unit.isGrounded(); + boolean ground = unit.isGrounded(); boolean allowHealing = type.canHeal; boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team && ((Building)target).damaged() && target.within(unit, type.range); @@ -908,8 +908,8 @@ public class MobileInput extends InputHandler implements GestureListener{ unit.moveAt(movement); }else{ unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); - if(!movement.isZero() && legs){ - unit.vel.rotateTo(movement.angle(), type.rotateSpeed); + if(!movement.isZero()){ + unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1)); } } diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 4cd9d704f5..e95639ed2e 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -309,6 +309,10 @@ public class ContentParser{ } + if(value.has("controller")){ + unit.defaultController = make(resolve(value.getString("controller"), "mindustry.ai.type")); + } + //read extra default waves if(value.has("waves")){ JsonValue waves = value.remove("waves"); diff --git a/core/src/mindustry/type/Weather.java b/core/src/mindustry/type/Weather.java index bb6b444746..8c9bdb0b60 100644 --- a/core/src/mindustry/type/Weather.java +++ b/core/src/mindustry/type/Weather.java @@ -19,7 +19,7 @@ import mindustry.world.blocks.*; import static mindustry.Vars.*; -public abstract class Weather extends UnlockableContent{ +public class Weather extends UnlockableContent{ /** Default duration of this weather event in ticks. */ public float duration = 10f * Time.toMinutes; public float opacityMultiplier = 1f; diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 866c3460e4..63b94b277b 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -102,12 +102,16 @@ public class ModsDialog extends BaseDialog{ t.button("@mod.import.github", Icon.github, bstyle, () -> { dialog.hide(); + var modString = Core.settings.getString("lastmod", ""); + var suggested = Structs.random(suggestedMods); - ui.showTextInput("@mod.import.github", "", 64, Core.settings.getString("lastmod", "Anuken/ExampleMod"), text -> { - Core.settings.put("lastmod", text); + ui.showTextInput("@mod.import.github", "", 64, modString.isEmpty() ? suggested : modString, text -> { + if(!modString.isEmpty() || !Structs.eq(suggested, text)){ + Core.settings.put("lastmod", text); + } ui.loadfrag.show(); - //Try to download the 6.0 branch first, but if it doesn't exist try master. + //Try to download the 6.0 branch first, but if it doesn't exist, try master. githubImport("6.0", text, e1 -> { githubImport("master", text, e2 -> { githubImport("main", text, e3 -> { diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 121fb41d57..3db6350619 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -409,6 +409,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ @Override public void draw(){ + planets.orbitAlpha = selectAlpha; planets.render(PlanetDialog.this); if(Core.scene.getDialog() == PlanetDialog.this){ Core.scene.setScrollFocus(PlanetDialog.this); @@ -711,6 +712,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ stable.table(t -> { t.add("@sectors.resources").padRight(4); for(UnlockableContent c : sector.info.resources){ + if(c == null) continue; //apparently this is possible. t.image(c.icon(Cicon.small)).padRight(3).size(Cicon.small.size); } }).padLeft(10f).fillX().row(); diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index 70e6bb653b..2355dd8118 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -20,7 +20,7 @@ public class Build{ private static final IntSet tmp = new IntSet(); @Remote(called = Loc.server) - public static void beginBreak(Team team, int x, int y){ + public static void beginBreak(@Nullable Unit unit, Team team, int x, int y){ if(!validBreak(team, x, y)){ return; } @@ -40,14 +40,14 @@ public class Build{ tile.setBlock(sub, team, rotation); tile.bc().setDeconstruct(previous); tile.build.health = tile.build.maxHealth * prevPercent; + if(unit != null && unit.isPlayer()) tile.build.lastAccessed = unit.getPlayer().name; - - Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true))); + Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, unit, true))); } /** Places a ConstructBlock at this location. */ @Remote(called = Loc.server) - public static void beginPlace(Block result, Team team, int x, int y, int rotation){ + public static void beginPlace(@Nullable Unit unit, Block result, Team team, int x, int y, int rotation){ if(!validPlace(result, team, x, y, rotation)){ return; } @@ -57,6 +57,15 @@ public class Build{ //just in case if(tile == null) return; + //auto-rotate the block to the correct orientation and bail out + if(tile.team() == team && tile.block == result && tile.build != null){ + if(unit != null && unit.isPlayer()) tile.build.lastAccessed = unit.getPlayer().name; + tile.build.rotation = Mathf.mod(rotation, 4); + tile.build.updateProximity(); + tile.build.noSleep(); + return; + } + Block previous = tile.block(); Block sub = ConstructBlock.get(result.size); Seq prevBuild = new Seq<>(9); @@ -76,10 +85,11 @@ public class Build{ build.setConstruct(previous.size == sub.size ? previous : Blocks.air, result); build.prevBuild = prevBuild; + if(unit != null && unit.isPlayer()) build.lastAccessed = unit.getPlayer().name; result.placeBegan(tile, previous); - Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, false))); + Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, unit, false))); } /** Returns whether a tile can be placed at this location by this team. */ diff --git a/core/src/mindustry/world/blocks/environment/OverlayFloor.java b/core/src/mindustry/world/blocks/environment/OverlayFloor.java index 4c57943aed..c20eccceaf 100644 --- a/core/src/mindustry/world/blocks/environment/OverlayFloor.java +++ b/core/src/mindustry/world/blocks/environment/OverlayFloor.java @@ -4,7 +4,7 @@ import arc.graphics.g2d.*; import arc.math.*; import mindustry.world.*; -/**A type of floor that is overlaid on top of over floors.*/ +/**A type of floor that is overlaid on top of other floors.*/ public class OverlayFloor extends Floor{ public OverlayFloor(String name){ diff --git a/core/src/mindustry/world/blocks/units/ControlCenter.java b/core/src/mindustry/world/blocks/units/ControlCenter.java deleted file mode 100644 index ab99470b93..0000000000 --- a/core/src/mindustry/world/blocks/units/ControlCenter.java +++ /dev/null @@ -1,16 +0,0 @@ -package mindustry.world.blocks.units; - -import mindustry.gen.*; -import mindustry.world.*; - -public class ControlCenter extends Block{ - - public ControlCenter(String name){ - super(name); - update = true; - } - - public class ControlCenterBuild extends Building{ - - } -} diff --git a/fastlane/metadata/android/en-US/changelogs/29733.txt b/fastlane/metadata/android/en-US/changelogs/29733.txt new file mode 100644 index 0000000000..da6bfa3221 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29733.txt @@ -0,0 +1,11 @@ +The final beta build. + +- Updated link to wiki modding guide, now points to new wiki +- Fixed weaving missiles consistently moving off to one direction +- Fixed units shooting fast bullets on servers in certain conditions +- Fixed some crashes +- Made construction of rotated blocks free/instant (i.e. equivalent to manually rotating it) + +Campaign: +- Better production calculation system +- Fixed deconstruction counting as production