diff --git a/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java b/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java index 7a552ead20..341b26df3a 100644 --- a/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java +++ b/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java @@ -193,7 +193,7 @@ public class EntityIO{ st("$L = $L($T.$L($L, $L, alpha))", name, field.annotation(SyncField.class).clamped() ? "arc.math.Mathf.clamp" : "", Mathf.class, field.annotation(SyncField.class).value() ? "lerp" : "slerp", lastName, targetName); } - ncont("else"); //no meaningful data has arrived yet + ncont("else if(lastUpdated != 0)"); //check if no meaningful data has arrived yet //write values directly to targets for(Svar field : fields){ diff --git a/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java b/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java index 97c6fb0b2c..3350d0e226 100644 --- a/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java +++ b/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java @@ -566,6 +566,14 @@ public class EntityProcess extends BaseProcessor{ //write the groups groupsBuilder.addMethod(groupInit.build()); + MethodSpec.Builder groupClear = MethodSpec.methodBuilder("clear").addModifiers(Modifier.PUBLIC, Modifier.STATIC); + for(GroupDefinition group : groupDefs){ + groupClear.addStatement("$L.clear()", group.name); + } + + //write clear + groupsBuilder.addMethod(groupClear.build()); + //add method for resizing all necessary groups MethodSpec.Builder groupResize = MethodSpec.methodBuilder("resize") .addParameter(TypeName.FLOAT, "x").addParameter(TypeName.FLOAT, "y").addParameter(TypeName.FLOAT, "w").addParameter(TypeName.FLOAT, "h") diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 64e39aa5ab..abeeab6575 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -163,7 +163,7 @@ public class Logic implements ApplicationListener{ //fire change event, since it was technically changed Events.fire(new StateChangeEvent(prev, State.menu)); - Groups.all.clear(); + Groups.clear(); Time.clear(); Events.fire(new ResetEvent()); diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index 317e74cbbb..25d80e6194 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -343,7 +343,7 @@ public class NetClient implements ApplicationListener{ @Remote(variants = Variant.both) public static void worldDataBegin(){ - Groups.all.clear(); + Groups.clear(); netClient.removed.clear(); logic.reset(); @@ -361,6 +361,7 @@ public class NetClient implements ApplicationListener{ @Remote(variants = Variant.one) public static void setPosition(float x, float y){ + player.unit().set(x, y); player.set(x, y); } @@ -517,7 +518,7 @@ public class NetClient implements ApplicationListener{ quiet = false; lastSent = 0; - Groups.all.clear(); + Groups.clear(); ui.chatfrag.clearMessages(); } @@ -566,13 +567,14 @@ public class NetClient implements ApplicationListener{ Unit unit = player.dead() ? Nulls.unit : player.unit(); Call.clientShapshot(lastSent++, + player.dead(), unit.x, unit.y, player.unit().aimX(), player.unit().aimY(), unit.rotation, unit instanceof Mechc ? ((Mechc)unit).baseRotation() : 0, unit.vel.x, unit.vel.y, player.miner().mineTile(), - control.input.isBoosting, control.input.isShooting, ui.chatfrag.shown(), + player.boosting, player.shooting, ui.chatfrag.shown(), requests, Core.camera.position.x, Core.camera.position.y, Core.camera.width * viewScale, Core.camera.height * viewScale); diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 119c4d7cb3..d3c3f38cff 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -529,6 +529,7 @@ public class NetServer implements ApplicationListener{ public static void clientShapshot( Player player, int snapshotID, + boolean dead, float x, float y, float pointerX, float pointerY, float rotation, float baseRotation, @@ -538,23 +539,24 @@ public class NetServer implements ApplicationListener{ @Nullable BuildPlan[] requests, float viewX, float viewY, float viewWidth, float viewHeight ){ - NetConnection connection = player.con; - if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return; + NetConnection con = player.con; + if(con == null || snapshotID < con.lastRecievedClientSnapshot) return; boolean verifyPosition = !player.dead() && netServer.admins.getStrict() && headless; - if(connection.lastRecievedClientTime == 0) connection.lastRecievedClientTime = Time.millis() - 16; + if(con.lastRecievedClientTime == 0) con.lastRecievedClientTime = Time.millis() - 16; - connection.viewX = viewX; - connection.viewY = viewY; - connection.viewWidth = viewWidth; - connection.viewHeight = viewHeight; + con.viewX = viewX; + con.viewY = viewY; + con.viewWidth = viewWidth; + con.viewHeight = viewHeight; //disable shooting when a mech flies if(!player.dead() && player.unit().isFlying() && player.unit() instanceof Mechc){ shooting = false; } + //TODO these need to be assigned elsewhere player.mouseX = pointerX; player.mouseY = pointerY; player.typing = chatting; @@ -582,7 +584,7 @@ public class NetServer implements ApplicationListener{ continue; }else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.rotation() == req.rotation)){ continue; - }else if(connection.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so + }else if(con.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so continue; }else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server action.block = req.block; @@ -591,33 +593,39 @@ public class NetServer implements ApplicationListener{ })){ //force the player to remove this request if that's not the case Call.removeQueueBlock(player.con, req.x, req.y, req.breaking); - connection.rejectedRequests.add(req); + con.rejectedRequests.add(req); continue; } player.builder().plans().addLast(req); } } - connection.rejectedRequests.clear(); + con.rejectedRequests.clear(); if(!player.dead()){ Unit unit = player.unit(); - unit.vel().set(xVelocity, yVelocity).limit(unit.type().speed); - long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime); - float maxSpeed = player.dead() ? Float.MAX_VALUE : player.unit().type().speed; + unit.vel.set(xVelocity, yVelocity).limit(unit.type().speed); + long elapsed = Time.timeSinceMillis(con.lastRecievedClientTime); + float maxSpeed = player.unit().type().speed; float maxMove = elapsed / 1000f * 60f * maxSpeed * 1.1f; - if(connection.lastUnit != unit && !player.dead()){ - connection.lastUnit = unit; - connection.lastPosition.set(unit); + if(con.lastUnit != unit){ + con.lastUnit = unit; + con.lastPosition.set(unit); } - vector.set(x, y).sub(connection.lastPosition); + //if the player think they're dead their position should be ignored + if(dead){ + x = unit.x; + y = unit.y; + } + + vector.set(x, y).sub(con.lastPosition); vector.limit(maxMove); - float prevx = unit.x(), prevy = unit.y(); - unit.set(connection.lastPosition); + float prevx = unit.x, prevy = unit.y; + unit.set(con.lastPosition); if(!unit.isFlying()){ unit.move(vector.x, vector.y); }else{ @@ -625,30 +633,24 @@ public class NetServer implements ApplicationListener{ } //set last position after movement - connection.lastPosition.set(unit); - float newx = unit.x(), newy = unit.y(); + con.lastPosition.set(unit); + float newx = unit.x, newy = unit.y; if(!verifyPosition){ unit.set(prevx, prevy); newx = x; newy = y; - }else if(!Mathf.within(x, y, newx, newy, correctDist)){ + }else if(!Mathf.within(x, y, newx, newy, correctDist) && !dead){ Call.setPosition(player.con, newx, newy); //teleport and correct position when necessary } - //reset player to previous synced position so it gets interpolated - //the server does not interpolate - if(!headless){ - unit.set(prevx, prevy); - } - //write sync data to the buffer fbuffer.limit(20); fbuffer.position(0); //now, put the new position, rotation and baserotation into the buffer so it can be read + //TODO this is terrible if(unit instanceof Mechc) fbuffer.put(baseRotation); //base rotation is optional - fbuffer.put(unit.elevation()); fbuffer.put(rotation); //rotation is always there fbuffer.put(newx); fbuffer.put(newy); @@ -661,8 +663,8 @@ public class NetServer implements ApplicationListener{ player.y = y; } - connection.lastRecievedClientSnapshot = snapshotID; - connection.lastRecievedClientTime = Time.millis(); + con.lastRecievedClientSnapshot = snapshotID; + con.lastRecievedClientTime = Time.millis(); } @Remote(targets = Loc.client, called = Loc.server) diff --git a/core/src/mindustry/entities/EntityGroup.java b/core/src/mindustry/entities/EntityGroup.java index 80d01ea9cd..f9c6d55316 100644 --- a/core/src/mindustry/entities/EntityGroup.java +++ b/core/src/mindustry/entities/EntityGroup.java @@ -166,6 +166,9 @@ public class EntityGroup implements Iterable{ int idx = array.indexOf(type, true); if(idx != -1){ array.remove(idx); + if(map != null){ + map.remove(type.id()); + } //fix iteration index when removing if(index >= idx){ diff --git a/core/src/mindustry/entities/GroupDefs.java b/core/src/mindustry/entities/GroupDefs.java index 95c456026d..3d2dcc1580 100644 --- a/core/src/mindustry/entities/GroupDefs.java +++ b/core/src/mindustry/entities/GroupDefs.java @@ -4,7 +4,7 @@ import mindustry.annotations.Annotations.*; import mindustry.gen.*; class GroupDefs{ - @GroupDef(value = Entityc.class, mapping = true) G all; + @GroupDef(value = Entityc.class) G all; @GroupDef(value = Playerc.class, mapping = true) G player; @GroupDef(value = Bulletc.class, spatial = true, collide = true) G bullet; @GroupDef(value = Unitc.class, spatial = true, mapping = true) G unit; diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index f1c5d81735..3948c608c5 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -3,6 +3,7 @@ package mindustry.entities; import arc.func.*; import arc.math.geom.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.world.*; @@ -21,6 +22,12 @@ public class Units{ unit.killed(); } + @Remote(called = Loc.server) + public static void unitDespawn(Unit unit){ + Fx.unitDespawn.at(unit.x, unit.y, 0, unit); + unit.remove(); + } + /** @return whether a new instance of a unit of this team can be created. */ public static boolean canCreate(Team team){ return teamIndex.count(team) < getCap(team); diff --git a/core/src/mindustry/entities/comp/BlockUnitComp.java b/core/src/mindustry/entities/comp/BlockUnitComp.java index 5adec13c6a..4ae698db2a 100644 --- a/core/src/mindustry/entities/comp/BlockUnitComp.java +++ b/core/src/mindustry/entities/comp/BlockUnitComp.java @@ -1,10 +1,12 @@ package mindustry.entities.comp; +import arc.graphics.g2d.*; import mindustry.annotations.Annotations.*; import mindustry.game.*; import mindustry.gen.*; +import mindustry.ui.*; -import static mindustry.Vars.tilesize; +import static mindustry.Vars.*; @Component abstract class BlockUnitComp implements Unitc{ @@ -29,6 +31,12 @@ abstract class BlockUnitComp implements Unitc{ } } + @Replace + @Override + public TextureRegion icon(){ + return tile.block.icon(Cicon.full); + } + @Override public void killed(){ tile.kill(); diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index d6d67c21bf..64667334e9 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -28,7 +28,7 @@ abstract class BuilderComp implements Unitc{ @Import float x, y, rotation; - Queue plans = new Queue<>(); + @SyncLocal Queue plans = new Queue<>(); transient boolean building = true; @Override diff --git a/core/src/mindustry/entities/comp/DecalComp.java b/core/src/mindustry/entities/comp/DecalComp.java index fa2cad2bfa..6db6b58f53 100644 --- a/core/src/mindustry/entities/comp/DecalComp.java +++ b/core/src/mindustry/entities/comp/DecalComp.java @@ -19,7 +19,7 @@ abstract class DecalComp implements Drawc, Timedc, Rotc, Posc{ public void draw(){ Draw.z(Layer.scorch); - Draw.mixcol(color, 1f); + Draw.mixcol(color, color.a); Draw.alpha(1f - Mathf.curve(fin(), 0.98f)); Draw.rect(region, x, y, rotation); Draw.reset(); diff --git a/core/src/mindustry/entities/comp/EntityComp.java b/core/src/mindustry/entities/comp/EntityComp.java index a0082ec9d5..3e49ea01ce 100644 --- a/core/src/mindustry/entities/comp/EntityComp.java +++ b/core/src/mindustry/entities/comp/EntityComp.java @@ -32,6 +32,10 @@ abstract class EntityComp{ return ((Object)this) == player || ((Object)this) instanceof Unitc && ((Unitc)((Object)this)).controller() == player; } + boolean isRemote(){ + return ((Object)this) instanceof Unitc && ((Unitc)((Object)this)).isPlayer() && !isLocal(); + } + boolean isNull(){ return false; } diff --git a/core/src/mindustry/entities/comp/FlyingComp.java b/core/src/mindustry/entities/comp/FlyingComp.java index fa4999ab3d..202ac6d4b5 100644 --- a/core/src/mindustry/entities/comp/FlyingComp.java +++ b/core/src/mindustry/entities/comp/FlyingComp.java @@ -17,7 +17,7 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{ @Import float x, y; @Import Vec2 vel; - @SyncField(value = true, clamped = true) @SyncLocal float elevation; + @SyncLocal float elevation; private transient boolean wasFlying; transient float drownTime; transient float splashTimer; diff --git a/core/src/mindustry/entities/comp/MinerComp.java b/core/src/mindustry/entities/comp/MinerComp.java index 9e83ece02e..781d9ebb83 100644 --- a/core/src/mindustry/entities/comp/MinerComp.java +++ b/core/src/mindustry/entities/comp/MinerComp.java @@ -22,7 +22,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{ @Import UnitType type; transient float mineTimer; - @Nullable Tile mineTile; + @Nullable @SyncLocal Tile mineTile; public boolean canMine(Item item){ return type.mineTier >= item.hardness; diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 4c11266019..8caf31c46c 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -12,8 +12,8 @@ import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.core.*; import mindustry.entities.units.*; -import mindustry.game.*; import mindustry.game.EventType.*; +import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.net.Administration.*; @@ -37,10 +37,10 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra transient @Nullable NetConnection con; @ReadOnly Team team = Team.sharded; + @SyncLocal boolean admin, typing, shooting, boosting; + @SyncLocal float mouseX, mouseY; String name = "noname"; - boolean admin, typing, shooting, boosting; Color color = new Color(); - float mouseX, mouseY; transient float deathTimer; transient String lastText = ""; @@ -63,9 +63,10 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra } public TextureRegion icon(){ + //display default icon for dead players if(dead()) return core() == null ? UnitTypes.alpha.icon(Cicon.full) : ((CoreBlock)core().block).unitType.icon(Cicon.full); - return unit.type().icon(Cicon.full); + return unit.icon(); } public void reset(){ @@ -78,6 +79,11 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra } } + @Override + public boolean isValidController(){ + return isAdded(); + } + @Replace public float clipSize(){ return unit.isNull() ? 20 : unit.type().hitsize * 2f; @@ -125,6 +131,14 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra } + @Override + public void remove(){ + //clear unit upon removal + if(!unit.isNull()){ + clearUnit(); + } + } + public void team(Team team){ this.team = team; unit.team(team); diff --git a/core/src/mindustry/entities/comp/SyncComp.java b/core/src/mindustry/entities/comp/SyncComp.java index 550c2e8363..0fd3d06cae 100644 --- a/core/src/mindustry/entities/comp/SyncComp.java +++ b/core/src/mindustry/entities/comp/SyncComp.java @@ -22,8 +22,19 @@ abstract class SyncComp implements Entityc{ @Override public void update(){ - if(Vars.net.client() && !isLocal()){ + //interpolate the player if: + //- this is a client and the entity is everything except the local player + //- this is a server and the entity is a remote player + if((Vars.net.client() && !isLocal()) || isRemote()){ interpolate(); } } + + @Override + public void remove(){ + //notify client of removal + if(Vars.net.client()){ + Vars.netClient.addRemovedEntity(id()); + } + } } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 621477185e..2363ea3a08 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -1,6 +1,7 @@ package mindustry.entities.comp; import arc.*; +import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; import arc.scene.ui.layout.*; @@ -233,11 +234,15 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I //remove units spawned by the core if(spawnedByCore && !isPlayer()){ - Fx.unitDespawn.at(x, y, 0, this); - remove(); + Call.unitDespawn(base()); } } + /** @return a preview icon for this unit. */ + public TextureRegion icon(){ + return type.icon(Cicon.full); + } + /** Actually destroys the unit, removing it and creating explosions. **/ public void destroy(){ float explosiveness = 2f + item().explosiveness * stack().amount; diff --git a/core/src/mindustry/entities/units/UnitController.java b/core/src/mindustry/entities/units/UnitController.java index 3b3eaa0342..63aec52ee3 100644 --- a/core/src/mindustry/entities/units/UnitController.java +++ b/core/src/mindustry/entities/units/UnitController.java @@ -6,6 +6,10 @@ public interface UnitController{ void unit(Unit unit); Unit unit(); + default boolean isValidController(){ + return true; + } + default void command(UnitCommand command){ } diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 7ae6820a15..40708b4586 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -221,7 +221,7 @@ public class DesktopInput extends InputHandler{ } if(Core.input.keyRelease(Binding.select)){ - isShooting = false; + player.shooting = false; } if(state.isGame() && Core.input.keyTap(Binding.minimap) && !scene.hasDialog() && !(scene.getKeyboardFocus() instanceof TextField)){ @@ -248,8 +248,8 @@ public class DesktopInput extends InputHandler{ mode = none; } - if(isShooting && !canShoot()){ - isShooting = false; + if(player.shooting && !canShoot()){ + player.shooting = false; } if(isPlacing() && player.isBuilder()){ @@ -464,10 +464,10 @@ public class DesktopInput extends InputHandler{ //only begin shooting if there's no cursor event if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().plans().size == 0 || !player.builder().isBuilding()) && !droppingItem && !tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){ - isShooting = shouldShoot; + player.shooting = shouldShoot; } }else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine - isShooting = shouldShoot; + player.shooting = shouldShoot; } }else if(Core.input.keyTap(Binding.deselect) && isPlacing()){ block = null; @@ -575,7 +575,7 @@ public class DesktopInput extends InputHandler{ movement.set(xa, ya).nor().scl(speed); float mouseAngle = Angles.mouseAngle(unit.x(), unit.y()); - boolean aimCursor = omni && isShooting && unit.type().hasWeapons() && unit.type().faceTarget && !boosted && unit.type().rotateShooting; + boolean aimCursor = omni && player.shooting && unit.type().hasWeapons() && unit.type().faceTarget && !boosted && unit.type().rotateShooting; if(aimCursor){ unit.lookAt(mouseAngle); @@ -595,10 +595,11 @@ public class DesktopInput extends InputHandler{ } 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, isShooting && !boosted); + unit.controlWeapons(true, player.shooting && !boosted); - isBoosting = Core.input.keyDown(Binding.boost) && !movement.isZero(); - player.boosting(isBoosting); + player.boosting = Core.input.keyDown(Binding.boost) && !movement.isZero(); + player.mouseX = unit.aimX(); + player.mouseY = unit.aimY(); //TODO netsync this if(unit instanceof Payloadc){ diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 8254e2ba64..9538d3df3c 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -58,7 +58,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ public int rotation; public boolean droppingItem; public Group uiGroup; - public boolean isShooting, isBuilding = true, buildWasAutoPaused = false, isBoosting = false; + public boolean isBuilding = true, buildWasAutoPaused = false; public @Nullable UnitType controlledType; protected @Nullable Schematic lastSchematic; @@ -249,7 +249,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } public void update(){ - player.typing(ui.chatfrag.shown()); + player.typing = ui.chatfrag.shown(); if(player.isBuilder()){ player.builder().building(isBuilding); diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index df4c3f0935..75c468f1fd 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -454,7 +454,7 @@ public class MobileInput extends InputHandler implements GestureListener{ lastLineY = tileY; }else if(!tryTapPlayer(worldx, worldy) && Core.settings.getBool("keyboard")){ //shoot on touch down when in keyboard mode - isShooting = true; + player.shooting = true; } } @@ -589,11 +589,11 @@ public class MobileInput extends InputHandler implements GestureListener{ if(Core.settings.getBool("keyboard")){ if(Core.input.keyRelease(Binding.select)){ - isShooting = false; + player.shooting = false; } - if(isShooting && !canShoot()){ - isShooting = false; + if(player.shooting && !canShoot()){ + player.shooting = false; } } diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 11b170de44..2e88a1bb71 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -170,7 +170,7 @@ public class TypeIO{ } public static T readEntity(Reads read){ - return (T)Groups.all.getByID(read.i()); + return (T)Groups.sync.getByID(read.i()); } public static void writeBuilding(Writes write, Building tile){ diff --git a/core/src/mindustry/net/NetworkIO.java b/core/src/mindustry/net/NetworkIO.java index 257fc35b07..f4b4d3a61f 100644 --- a/core/src/mindustry/net/NetworkIO.java +++ b/core/src/mindustry/net/NetworkIO.java @@ -27,7 +27,7 @@ public class NetworkIO{ stream.writeInt(state.wave); stream.writeFloat(state.wavetime); - stream.writeInt(player.id()); + stream.writeInt(player.id); player.write(Writes.get(stream)); SaveIO.getSaveWriter().writeContentHeader(stream); @@ -47,11 +47,11 @@ public class NetworkIO{ state.wave = stream.readInt(); state.wavetime = stream.readFloat(); - Groups.all.clear(); + Groups.clear(); int id = stream.readInt(); player.reset(); player.read(Reads.get(stream)); - player.id(id); + player.id = id; player.add(); SaveIO.getSaveWriter().readContentHeader(stream); diff --git a/core/src/mindustry/world/blocks/BuildBlock.java b/core/src/mindustry/world/blocks/BuildBlock.java index e49f1cdf64..53fc4bcc54 100644 --- a/core/src/mindustry/world/blocks/BuildBlock.java +++ b/core/src/mindustry/world/blocks/BuildBlock.java @@ -59,9 +59,9 @@ public class BuildBlock extends Block{ @Remote(called = Loc.server) public static void constructFinish(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){ if(tile == null) return; - float healthf = tile.build.healthf(); + float healthf = tile.build == null ? 1f : tile.build.healthf(); tile.setBlock(block, team, rotation); - tile.build.health(block.health * healthf); + tile.build.health = block.health * healthf; //last builder was this local client player, call placed() if(!headless && builderID == player.unit().id()){ if(!skipConfig){