mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-11-13 07:15:28 +03:00
Multiplayer bugfixes
This commit is contained in:
parent
29e9d064df
commit
2584197a02
@ -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){
|
||||
|
@ -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")
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -166,6 +166,9 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
|
||||
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){
|
||||
|
@ -4,7 +4,7 @@ import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
class GroupDefs<G>{
|
||||
@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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -28,7 +28,7 @@ abstract class BuilderComp implements Unitc{
|
||||
|
||||
@Import float x, y, rotation;
|
||||
|
||||
Queue<BuildPlan> plans = new Queue<>();
|
||||
@SyncLocal Queue<BuildPlan> plans = new Queue<>();
|
||||
transient boolean building = true;
|
||||
|
||||
@Override
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -6,6 +6,10 @@ public interface UnitController{
|
||||
void unit(Unit unit);
|
||||
Unit unit();
|
||||
|
||||
default boolean isValidController(){
|
||||
return true;
|
||||
}
|
||||
|
||||
default void command(UnitCommand command){
|
||||
|
||||
}
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ public class TypeIO{
|
||||
}
|
||||
|
||||
public static <T extends Entityc> 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){
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
Loading…
Reference in New Issue
Block a user