This commit is contained in:
Ngọc Lam
2020-11-30 15:58:43 +07:00
committed by GitHub
25 changed files with 90 additions and 60 deletions

View File

@@ -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.* **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.* **Crash report**: *The contents of relevant crash report files. REQUIRED if you are reporting a crash.*

View File

@@ -47,6 +47,8 @@ public class Vars implements Loadable{
public static final int bufferSize = 8192; public static final int bufferSize = 8192;
/** global charset, since Android doesn't support the Charsets class */ /** global charset, since Android doesn't support the Charsets class */
public static final Charset charset = Charset.forName("UTF-8"); public static final Charset charset = Charset.forName("UTF-8");
/** mods suggested for import */
public static final String[] suggestedMods = {""};
/** main application name, capitalized */ /** main application name, capitalized */
public static final String appName = "Mindustry"; public static final String appName = "Mindustry";
/** URL for itch.io donations. */ /** URL for itch.io donations. */
@@ -56,7 +58,7 @@ public class Vars implements Loadable{
/** URL for sending crash reports to */ /** URL for sending crash reports to */
public static final String crashReportURL = "http://192.99.169.18/report"; public static final String crashReportURL = "http://192.99.169.18/report";
/** URL the links to the wiki's modding guide.*/ /** 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. */ /** 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"; 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. */ /** URL to the JSON file containing all the BE servers. Only queried in BE. */

View File

@@ -13,6 +13,7 @@ import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.storage.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -115,7 +116,7 @@ public class Pathfinder implements Runnable{
} }
return PathTile.get( 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.getTeamID(),
tile.solid(), tile.solid(),
tile.floor().isLiquid, tile.floor().isLiquid,
@@ -458,7 +459,7 @@ public class Pathfinder implements Runnable{
/** costs of getting to a specific tile */ /** costs of getting to a specific tile */
public int[][] weights; public int[][] weights;
/** search IDs of each position - the highest, most recent search is prioritized and overwritten */ /** 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 */ /** search frontier, these are Pos objects */
IntQueue frontier = new IntQueue(); IntQueue frontier = new IntQueue();
/** all target positions; these positions have a cost of 0, and must be synchronized on! */ /** all target positions; these positions have a cost of 0, and must be synchronized on! */

View File

@@ -1657,6 +1657,7 @@ public class UnitTypes implements ContentList{
recoil = 3f; recoil = 3f;
occlusion = 12f; occlusion = 12f;
ejectEffect = Fx.casing3; ejectEffect = Fx.casing3;
shootSound = Sounds.shootBig;
shots = 3; shots = 3;
shotDelay = 4f; shotDelay = 4f;

View File

@@ -340,7 +340,7 @@ public class Control implements ApplicationListener, Loadable{
state.rules.waves = true; state.rules.waves = true;
//reset win wave?? //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 there's still an enemy base left, fix it
if(state.rules.attackMode){ if(state.rules.attackMode){

View File

@@ -258,11 +258,11 @@ public class UI implements ApplicationListener, Loadable{
TextField field = cont.field(def, t -> {}).size(330f, 50f).get(); TextField field = cont.field(def, t -> {}).size(330f, 50f).get();
field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c)); field.setFilter((f, c) -> field.getText().length() < textLength && filter.acceptChar(f, c));
buttons.defaults().size(120, 54).pad(4); buttons.defaults().size(120, 54).pad(4);
buttons.button("@cancel", this::hide);
buttons.button("@ok", () -> { buttons.button("@ok", () -> {
confirmed.get(field.getText()); confirmed.get(field.getText());
hide(); hide();
}).disabled(b -> field.getText().isEmpty()); }).disabled(b -> field.getText().isEmpty());
buttons.button("@cancel", this::hide);
keyDown(KeyCode.enter, () -> { keyDown(KeyCode.enter, () -> {
String text = field.getText(); String text = field.getText();
if(!text.isEmpty()){ if(!text.isEmpty()){

View File

@@ -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) -> { 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); Tile tile = world.tile(wx, wy);
if(tile != null && tile.block().insulated){ if(tile != null && tile.block().insulated && tile.team() != team){
bhit = true; bhit = true;
//snap it instead of removing //snap it instead of removing
lines.get(lines.size -1).set(wx * tilesize, wy * tilesize); lines.get(lines.size -1).set(wx * tilesize, wy * tilesize);

View File

@@ -30,7 +30,7 @@ public class RepairFieldAbility extends Ability{
Units.nearby(unit.team, unit.x, unit.y, range, other -> { Units.nearby(unit.team, unit.x, unit.y, range, other -> {
if(other.damaged()){ if(other.damaged()){
healEffect.at(unit); healEffect.at(other);
wasHealed = true; wasHealed = true;
} }
other.heal(amount); other.heal(amount);

View File

@@ -16,11 +16,13 @@ abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{
@Override @Override
public void update(){ public void update(){
//repel unit out of bounds if(!net.client() || isLocal()){
if(x < 0) vel.x += (-x/warpDst); //repel unit out of bounds
if(y < 0) vel.y += (-y/warpDst); if(x < 0) vel.x += (-x/warpDst);
if(x > world.unitWidth()) vel.x -= (x - world.unitWidth())/warpDst; if(y < 0) vel.y += (-y/warpDst);
if(y > world.unitHeight()) vel.y -= (y - world.unitHeight())/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 //clamp position if not flying
if(isGrounded()){ if(isGrounded()){

View File

@@ -11,6 +11,7 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.type.*; import mindustry.type.*;
@@ -28,6 +29,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
@Import float x, y, rotation; @Import float x, y, rotation;
@Import UnitType type; @Import UnitType type;
@Import Team team;
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1); @SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
@SyncLocal transient boolean updateBuilding = true; @SyncLocal transient boolean updateBuilding = true;
@@ -75,27 +77,27 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
Tile tile = world.tile(current.x, current.y); Tile tile = world.tile(current.x, current.y);
if(!(tile.block() instanceof ConstructBlock)){ 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)); boolean hasAll = infinite || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item));
if(hasAll){ 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{ }else{
current.stuck = true; current.stuck = true;
} }
}else if(!current.initialized && current.breaking && Build.validBreak(team(), current.x, current.y)){ }else if(!current.initialized && current.breaking && Build.validBreak(team, current.x, current.y)){
Call.beginBreak(team(), current.x, current.y); Call.beginBreak(self(), team, current.x, current.y);
}else{ }else{
plans.removeFirst(); plans.removeFirst();
return; return;
} }
}else if(tile.team() != team()){ }else if(tile.team() != team){
plans.removeFirst(); plans.removeFirst();
return; return;
} }
if(tile.build instanceof ConstructBuild && !current.initialized){ 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; current.initialized = true;
} }
@@ -128,7 +130,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{
control.input.drawBreaking(request); control.input.drawBreaking(request);
}else{ }else{
request.block.drawRequest(request, control.input.allRequests(), 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. */ /** @return whether this request should be skipped, in favor of the next one. */
boolean shouldSkip(BuildPlan request, @Nullable Building core){ boolean shouldSkip(BuildPlan request, @Nullable Building core){
//requests that you have at least *started* are considered //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); 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);
} }

View File

@@ -90,8 +90,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
public float prefRotation(){ public float prefRotation(){
if(activelyBuilding()){ if(activelyBuilding()){
return angleTo(buildPlan()); return angleTo(buildPlan());
}else if(mineTile() != null){ }else if(mineTile != null){
return angleTo(mineTile()); return angleTo(mineTile);
}else if(moving()){ }else if(moving()){
return vel().angle(); return vel().angle();
} }
@@ -310,7 +310,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f); drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f);
//apply knockback based on spawns //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; float relativeSize = state.rules.dropZoneRadius + hitSize/2f + 1f;
for(Tile spawn : spawner.getSpawns()){ for(Tile spawn : spawner.getSpawns()){
if(within(spawn.worldx(), spawn.worldy(), relativeSize)){ if(within(spawn.worldx(), spawn.worldy(), relativeSize)){

View File

@@ -278,11 +278,13 @@ public class EventType{
public static class BlockBuildBeginEvent{ public static class BlockBuildBeginEvent{
public final Tile tile; public final Tile tile;
public final Team team; public final Team team;
public final @Nullable Unit unit;
public final boolean breaking; 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.tile = tile;
this.team = team; this.team = team;
this.unit = unit;
this.breaking = breaking; this.breaking = breaking;
} }
} }
@@ -310,10 +312,10 @@ public class EventType{
public static class BuildSelectEvent{ public static class BuildSelectEvent{
public final Tile tile; public final Tile tile;
public final Team team; public final Team team;
public final Builderc builder; public final Unit builder;
public final boolean breaking; 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.tile = tile;
this.team = team; this.team = team;
this.builder = builder; this.builder = builder;

View File

@@ -225,9 +225,11 @@ public class Universe{
if(sector.isBeingPlayed()){ if(sector.isBeingPlayed()){
state.rules.winWave = waveMax; state.rules.winWave = waveMax;
state.rules.waves = true; state.rules.waves = true;
state.rules.attackMode = false;
}else{ }else{
sector.info.winWave = waveMax; sector.info.winWave = waveMax;
sector.info.waves = true; sector.info.waves = true;
sector.info.attack = false;
sector.saveInfo(); sector.saveInfo();
} }

View File

@@ -37,6 +37,7 @@ public class PlanetRenderer implements Disposable{
public final VertexBatch3D batch = new VertexBatch3D(20000, false, true, 0); public final VertexBatch3D batch = new VertexBatch3D(20000, false, true, 0);
public float zoom = 1f; public float zoom = 1f;
public float orbitAlpha = 1f;
private final Mesh[] outlines = new Mesh[10]; private final Mesh[] outlines = new Mesh[10];
public final PlaneBatch3D projector = new PlaneBatch3D(); public final PlaneBatch3D projector = new PlaneBatch3D();
@@ -168,7 +169,7 @@ public class PlanetRenderer implements Disposable{
Vec3 center = planet.parent.position; Vec3 center = planet.parent.position;
float radius = planet.orbitRadius; float radius = planet.orbitRadius;
int points = (int)(radius * 10); 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); batch.flush(Gl.lineLoop);
} }

View File

@@ -629,8 +629,8 @@ public class DesktopInput extends InputHandler{
unit.moveAt(movement); unit.moveAt(movement);
}else{ }else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && ground){ if(!movement.isZero()){
unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed); unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1));
} }
} }

View File

@@ -769,7 +769,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override @Override
public boolean pan(float x, float y, float deltaX, float deltaY){ 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(); float scale = Core.camera.width / Core.graphics.getWidth();
deltaX *= scale; deltaX *= scale;
@@ -836,7 +836,7 @@ public class MobileInput extends InputHandler implements GestureListener{
if(type == null) return; if(type == null) return;
boolean omni = unit.type.omniMovement; boolean omni = unit.type.omniMovement;
boolean legs = unit.isGrounded(); boolean ground = unit.isGrounded();
boolean allowHealing = type.canHeal; boolean allowHealing = type.canHeal;
boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team && boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team &&
((Building)target).damaged() && target.within(unit, type.range); ((Building)target).damaged() && target.within(unit, type.range);
@@ -908,8 +908,8 @@ public class MobileInput extends InputHandler implements GestureListener{
unit.moveAt(movement); unit.moveAt(movement);
}else{ }else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && legs){ if(!movement.isZero()){
unit.vel.rotateTo(movement.angle(), type.rotateSpeed); unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1));
} }
} }

View File

@@ -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 //read extra default waves
if(value.has("waves")){ if(value.has("waves")){
JsonValue waves = value.remove("waves"); JsonValue waves = value.remove("waves");

View File

@@ -19,7 +19,7 @@ import mindustry.world.blocks.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public abstract class Weather extends UnlockableContent{ public class Weather extends UnlockableContent{
/** Default duration of this weather event in ticks. */ /** Default duration of this weather event in ticks. */
public float duration = 10f * Time.toMinutes; public float duration = 10f * Time.toMinutes;
public float opacityMultiplier = 1f; public float opacityMultiplier = 1f;

View File

@@ -102,12 +102,16 @@ public class ModsDialog extends BaseDialog{
t.button("@mod.import.github", Icon.github, bstyle, () -> { t.button("@mod.import.github", Icon.github, bstyle, () -> {
dialog.hide(); 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 -> { ui.showTextInput("@mod.import.github", "", 64, modString.isEmpty() ? suggested : modString, text -> {
Core.settings.put("lastmod", text); if(!modString.isEmpty() || !Structs.eq(suggested, text)){
Core.settings.put("lastmod", text);
}
ui.loadfrag.show(); 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("6.0", text, e1 -> {
githubImport("master", text, e2 -> { githubImport("master", text, e2 -> {
githubImport("main", text, e3 -> { githubImport("main", text, e3 -> {

View File

@@ -409,6 +409,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
@Override @Override
public void draw(){ public void draw(){
planets.orbitAlpha = selectAlpha;
planets.render(PlanetDialog.this); planets.render(PlanetDialog.this);
if(Core.scene.getDialog() == PlanetDialog.this){ if(Core.scene.getDialog() == PlanetDialog.this){
Core.scene.setScrollFocus(PlanetDialog.this); Core.scene.setScrollFocus(PlanetDialog.this);
@@ -711,6 +712,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
stable.table(t -> { stable.table(t -> {
t.add("@sectors.resources").padRight(4); t.add("@sectors.resources").padRight(4);
for(UnlockableContent c : sector.info.resources){ 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); t.image(c.icon(Cicon.small)).padRight(3).size(Cicon.small.size);
} }
}).padLeft(10f).fillX().row(); }).padLeft(10f).fillX().row();

View File

@@ -20,7 +20,7 @@ public class Build{
private static final IntSet tmp = new IntSet(); private static final IntSet tmp = new IntSet();
@Remote(called = Loc.server) @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)){ if(!validBreak(team, x, y)){
return; return;
} }
@@ -40,14 +40,14 @@ public class Build{
tile.setBlock(sub, team, rotation); tile.setBlock(sub, team, rotation);
tile.<ConstructBuild>bc().setDeconstruct(previous); tile.<ConstructBuild>bc().setDeconstruct(previous);
tile.build.health = tile.build.maxHealth * prevPercent; 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, unit, true)));
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true)));
} }
/** Places a ConstructBlock at this location. */ /** Places a ConstructBlock at this location. */
@Remote(called = Loc.server) @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)){ if(!validPlace(result, team, x, y, rotation)){
return; return;
} }
@@ -57,6 +57,15 @@ public class Build{
//just in case //just in case
if(tile == null) return; 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 previous = tile.block();
Block sub = ConstructBlock.get(result.size); Block sub = ConstructBlock.get(result.size);
Seq<Building> prevBuild = new Seq<>(9); Seq<Building> prevBuild = new Seq<>(9);
@@ -76,10 +85,11 @@ public class Build{
build.setConstruct(previous.size == sub.size ? previous : Blocks.air, result); build.setConstruct(previous.size == sub.size ? previous : Blocks.air, result);
build.prevBuild = prevBuild; build.prevBuild = prevBuild;
if(unit != null && unit.isPlayer()) build.lastAccessed = unit.getPlayer().name;
result.placeBegan(tile, previous); 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. */ /** Returns whether a tile can be placed at this location by this team. */

View File

@@ -4,7 +4,7 @@ import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import mindustry.world.*; 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 class OverlayFloor extends Floor{
public OverlayFloor(String name){ public OverlayFloor(String name){

View File

@@ -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{
}
}

View File

@@ -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