Update.
This commit is contained in:
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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.*
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -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. */
|
||||||
|
|||||||
@@ -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! */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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()){
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()){
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)){
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 -> {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
fastlane/metadata/android/en-US/changelogs/29733.txt
Normal file
11
fastlane/metadata/android/en-US/changelogs/29733.txt
Normal 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
|
||||||
Reference in New Issue
Block a user