diff --git a/README.md b/README.md index 109bc42fdb..878649989b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ See [CONTRIBUTING](CONTRIBUTING.md). Bleeding-edge builds are generated automatically for every commit. You can see them [here](https://github.com/Anuken/MindustryBuilds/releases). If you'd rather compile on your own, follow these instructions. -First, make sure you have [JDK 14](https://adoptopenjdk.net/) installed. Open a terminal in the root directory, `cd` to the Mindustry folder and run the following commands: +First, make sure you have [JDK 14](https://adoptopenjdk.net/) installed. **Other JDK versions will not work.** Open a terminal in the Mindustry directory and run the following commands: ### Windows diff --git a/android/src/mindustry/android/AndroidLauncher.java b/android/src/mindustry/android/AndroidLauncher.java index 69543be82e..1b0402da69 100644 --- a/android/src/mindustry/android/AndroidLauncher.java +++ b/android/src/mindustry/android/AndroidLauncher.java @@ -15,7 +15,6 @@ import arc.func.*; import arc.scene.ui.layout.*; import arc.util.*; import dalvik.system.*; -import io.anuke.mindustry.*; import mindustry.*; import mindustry.game.Saves.*; import mindustry.io.*; @@ -232,7 +231,7 @@ public class AndroidLauncher extends AndroidApplication{ super.onResume(); //TODO enable once GPGS is set up on the GP console - if(false && BuildConfig.FLAVOR.equals("gp")){ + if(false && getPackageName().endsWith(".gp")){ try{ if(gpService == null){ serviceClass = Class.forName("mindustry.android.GPGameService"); diff --git a/annotations/src/main/java/mindustry/annotations/remote/CallGenerator.java b/annotations/src/main/java/mindustry/annotations/remote/CallGenerator.java index 00ac5fabac..e21b015a34 100644 --- a/annotations/src/main/java/mindustry/annotations/remote/CallGenerator.java +++ b/annotations/src/main/java/mindustry/annotations/remote/CallGenerator.java @@ -30,6 +30,9 @@ public class CallGenerator{ TypeSpec.Builder packet = TypeSpec.classBuilder(ent.packetClassName) .addModifiers(Modifier.PUBLIC); + //temporary data to deserialize later + packet.addField(FieldSpec.builder(byte[].class, "DATA", Modifier.PRIVATE).initializer("NODATA").build()); + packet.superclass(tname("mindustry.net.Packet")); //return the correct priority @@ -41,8 +44,8 @@ public class CallGenerator{ } //implement read & write methods - packet.addMethod(makeWriter(ent, serializer)); - packet.addMethod(makeReader(ent, serializer)); + makeWriter(packet, ent, serializer); + makeReader(packet, ent, serializer); //generate handlers if(ent.where.isClient){ @@ -87,7 +90,7 @@ public class CallGenerator{ JavaFile.builder(packageName, spec).build().writeTo(BaseProcessor.filer); } - private static MethodSpec makeWriter(MethodEntry ent, ClassSerializer serializer){ + private static void makeWriter(TypeSpec.Builder typespec, MethodEntry ent, ClassSerializer serializer){ MethodSpec.Builder builder = MethodSpec.methodBuilder("write") .addParameter(Writes.class, "WRITE") .addModifiers(Modifier.PUBLIC).addAnnotation(Override.class); @@ -132,13 +135,27 @@ public class CallGenerator{ } } - return builder.build(); + typespec.addMethod(builder.build()); } - private static MethodSpec makeReader(MethodEntry ent, ClassSerializer serializer){ - MethodSpec.Builder builder = MethodSpec.methodBuilder("read") + private static void makeReader(TypeSpec.Builder typespec, MethodEntry ent, ClassSerializer serializer){ + MethodSpec.Builder readbuilder = MethodSpec.methodBuilder("read") .addParameter(Reads.class, "READ") + .addParameter(int.class, "LENGTH") .addModifiers(Modifier.PUBLIC).addAnnotation(Override.class); + + //read only into temporary data buffer + readbuilder.addStatement("DATA = READ.b(LENGTH)"); + + typespec.addMethod(readbuilder.build()); + + MethodSpec.Builder builder = MethodSpec.methodBuilder("handled") + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class); + + //make sure data is present, begin reading it if so + builder.addStatement("BAIS.setBytes(DATA)"); + Seq params = ent.element.params(); //go through each parameter @@ -185,7 +202,7 @@ public class CallGenerator{ } } - return builder.build(); + typespec.addMethod(builder.build()); } /** Creates a specific variant for a method entry. */ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 0f1a658539..5a329a668a 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1034,16 +1034,17 @@ public class Blocks implements ContentList{ duct = new Duct("duct"){{ requirements(Category.distribution, BuildVisibility.debugOnly, with(Items.graphite, 5, Items.copper, 5)); - speed = 5f; + speed = 4f; }}; ductRouter = new DuctRouter("duct-router"){{ requirements(Category.distribution, BuildVisibility.debugOnly, with(Items.graphite, 10, Items.copper, 5)); - speed = 5f; + speed = 4f; }}; ductBridge = new DuctBridge("duct-bridge"){{ requirements(Category.distribution, BuildVisibility.debugOnly, with(Items.graphite, 20, Items.copper, 15)); + speed = 4f; }}; //endregion @@ -1900,7 +1901,7 @@ public class Blocks implements ContentList{ requirements(Category.units, with(Items.copper, 150, Items.lead, 130, Items.metaglass, 120)); plans = Seq.with( new UnitPlan(UnitTypes.risso, 60f * 45f, with(Items.silicon, 20, Items.metaglass, 35)), - new UnitPlan(UnitTypes.retusa, 60f * 60f, with(Items.silicon, 15, Items.metaglass, 25, Items.titanium, 20)) + new UnitPlan(UnitTypes.retusa, 60f * 50f, with(Items.silicon, 15, Items.metaglass, 25, Items.titanium, 20)) ); size = 3; consumes.power(1.2f); @@ -1942,7 +1943,8 @@ public class Blocks implements ContentList{ new UnitType[]{UnitTypes.poly, UnitTypes.mega}, new UnitType[]{UnitTypes.minke, UnitTypes.bryde}, new UnitType[]{UnitTypes.pulsar, UnitTypes.quasar}, - new UnitType[]{UnitTypes.atrax, UnitTypes.spiroct} + new UnitType[]{UnitTypes.atrax, UnitTypes.spiroct}, + new UnitType[]{UnitTypes.oxynoe, UnitTypes.cyerce} ); }}; @@ -1963,7 +1965,8 @@ public class Blocks implements ContentList{ new UnitType[]{UnitTypes.fortress, UnitTypes.scepter}, new UnitType[]{UnitTypes.bryde, UnitTypes.sei}, new UnitType[]{UnitTypes.mega, UnitTypes.quad}, - new UnitType[]{UnitTypes.quasar, UnitTypes.vela} + new UnitType[]{UnitTypes.quasar, UnitTypes.vela}, + new UnitType[]{UnitTypes.cyerce, UnitTypes.aegires} ); }}; @@ -1984,7 +1987,8 @@ public class Blocks implements ContentList{ new UnitType[]{UnitTypes.scepter, UnitTypes.reign}, new UnitType[]{UnitTypes.sei, UnitTypes.omura}, new UnitType[]{UnitTypes.quad, UnitTypes.oct}, - new UnitType[]{UnitTypes.vela, UnitTypes.corvus} + new UnitType[]{UnitTypes.vela, UnitTypes.corvus}, + new UnitType[]{UnitTypes.aegires, UnitTypes.navanax} ); }}; diff --git a/core/src/mindustry/graphics/Shaders.java b/core/src/mindustry/graphics/Shaders.java index 75d61a2178..089e2e5ddb 100644 --- a/core/src/mindustry/graphics/Shaders.java +++ b/core/src/mindustry/graphics/Shaders.java @@ -48,12 +48,12 @@ public class Shaders{ tar = new SurfaceShader("tar"); slag = new SurfaceShader("slag"); space = new SpaceShader("space"); - caustics = new SurfaceShader("caustics"){ - @Override - public String textureName(){ - return "caustics"; - } - }; + //caustics = new SurfaceShader("caustics"){ + // @Override + // public String textureName(){ + // return "caustics"; + // } + //}; planet = new PlanetShader(); planetGrid = new PlanetGridShader(); atmosphere = new AtmosphereShader(); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 3746dae72e..8b5346fce0 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -238,7 +238,7 @@ public class DesktopInput extends InputHandler{ if(!player.dead() && !state.isPaused() && !scene.hasField()){ updateMovement(player.unit()); - if(Core.input.keyDown(Binding.respawn)){ + if(Core.input.keyTap(Binding.respawn)){ Call.unitClear(player); controlledType = null; } diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index d037a0d351..792d242851 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -856,8 +856,7 @@ public class MobileInput extends InputHandler implements GestureListener{ boolean omni = unit.type.omniMovement; boolean allowHealing = type.canHeal; - boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team && - ((Building)target).damaged() && target.within(unit, type.range); + boolean validHealTarget = allowHealing && target instanceof Building b && b.isValid() && target.team() == unit.team && b.damaged() && target.within(unit, type.range); boolean boosted = (unit instanceof Mechc && unit.isFlying()); //reset target if: @@ -912,13 +911,8 @@ public class MobileInput extends InputHandler implements GestureListener{ unit.vel.approachDelta(Vec2.ZERO, unit.speed() * type.accel / 2f); } - float expansion = 3f; - unit.hitbox(rect); - rect.x -= expansion; - rect.y -= expansion; - rect.width += expansion * 2f; - rect.height += expansion * 2f; + rect.grow(6f); player.boosting = collisions.overlapsTile(rect) || !unit.within(targetPos, 85f); @@ -927,7 +921,7 @@ public class MobileInput extends InputHandler implements GestureListener{ }else{ unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); if(!movement.isZero()){ - unit.vel.rotateTo(movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1)); + unit.rotation = Angles.moveToward(unit.rotation, movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1)); } } diff --git a/core/src/mindustry/maps/SectorDamage.java b/core/src/mindustry/maps/SectorDamage.java index 4e1b5a5242..786074c3dd 100644 --- a/core/src/mindustry/maps/SectorDamage.java +++ b/core/src/mindustry/maps/SectorDamage.java @@ -3,7 +3,6 @@ package mindustry.maps; import arc.math.*; import arc.math.geom.*; import arc.struct.*; -import arc.util.*; import mindustry.ai.*; import mindustry.content.*; import mindustry.entities.*; @@ -186,7 +185,6 @@ public class SectorDamage{ Tile start = spawns.first(); - Time.mark(); var field = pathfinder.getField(state.rules.waveTeam, Pathfinder.costGround, Pathfinder.fieldCore); Seq path = new Seq<>(); boolean found = false; diff --git a/core/src/mindustry/net/ArcNetProvider.java b/core/src/mindustry/net/ArcNetProvider.java index a18c8d57de..a81376d189 100644 --- a/core/src/mindustry/net/ArcNetProvider.java +++ b/core/src/mindustry/net/ArcNetProvider.java @@ -385,7 +385,6 @@ public class ArcNetProvider implements NetProvider{ return readFramework(byteBuffer); }else{ //read length int, followed by compressed lz4 data - //TODO not thread safe!!! Packet packet = Net.newPacket(id); var buffer = decompressBuffer.get(); int length = byteBuffer.getShort() & 0xffff; @@ -396,7 +395,7 @@ public class ArcNetProvider implements NetProvider{ buffer.position(0).limit(length); buffer.put(byteBuffer.array(), byteBuffer.position(), length); buffer.position(0); - packet.read(reads.get()); + packet.read(reads.get(), length); //move read packets forward byteBuffer.position(byteBuffer.position() + buffer.position()); }else{ @@ -405,7 +404,7 @@ public class ArcNetProvider implements NetProvider{ buffer.position(0); buffer.limit(length); - packet.read(reads.get()); + packet.read(reads.get(), length); //move buffer forward based on bytes read by decompressor byteBuffer.position(byteBuffer.position() + read); } diff --git a/core/src/mindustry/net/Net.java b/core/src/mindustry/net/Net.java index 689834c07b..2279c955c0 100644 --- a/core/src/mindustry/net/Net.java +++ b/core/src/mindustry/net/Net.java @@ -257,6 +257,7 @@ public class Net{ * Call to handle a packet being received for the client. */ public void handleClientReceived(Packet object){ + object.handled(); if(object instanceof StreamBegin b){ streams.put(b.id, currentStream = new StreamBuilder(b)); @@ -291,6 +292,8 @@ public class Net{ * Call to handle a packet being received for the server. */ public void handleServerReceived(NetConnection connection, Packet object){ + object.handled(); + try{ //handle object normally if(serverListeners.get(object.getClass()) != null){ diff --git a/core/src/mindustry/net/Packet.java b/core/src/mindustry/net/Packet.java index a6200547cc..e49b18c572 100644 --- a/core/src/mindustry/net/Packet.java +++ b/core/src/mindustry/net/Packet.java @@ -2,7 +2,14 @@ package mindustry.net; import arc.util.io.*; +import java.io.*; + public abstract class Packet{ + //internally used by generated code + protected static final byte[] NODATA = {}; + protected static final ReusableByteInStream BAIS = new ReusableByteInStream(); + protected static final Reads READ = new Reads(new DataInputStream(BAIS)); + //these are constants because I don't want to bother making an enum to mirror the annotation enum /** Does not get handled unless client is connected. */ @@ -15,6 +22,12 @@ public abstract class Packet{ public void read(Reads read){} public void write(Writes write){} + public void read(Reads read, int length){ + read(read); + } + + public void handled(){} + public int getPriority(){ return priorityNormal; } diff --git a/core/src/mindustry/net/Packets.java b/core/src/mindustry/net/Packets.java index a1cd13670c..10e607ec50 100644 --- a/core/src/mindustry/net/Packets.java +++ b/core/src/mindustry/net/Packets.java @@ -2,7 +2,6 @@ package mindustry.net; import arc.*; import arc.struct.*; -import arc.util.*; import arc.util.io.*; import arc.util.serialization.*; import mindustry.core.*; @@ -131,8 +130,6 @@ public class Packets{ crc.update(Base64Coder.decode(uuid), 0, b.length); buffer.l(crc.getValue()); - Log.info("CRC value sent: @", Long.toHexString(crc.getValue())); - buffer.b(mobile ? (byte)1 : 0); buffer.i(color); buffer.b((byte)mods.size); diff --git a/core/src/mindustry/world/blocks/distribution/DuctBridge.java b/core/src/mindustry/world/blocks/distribution/DuctBridge.java index e040f83879..10d3c287e6 100644 --- a/core/src/mindustry/world/blocks/distribution/DuctBridge.java +++ b/core/src/mindustry/world/blocks/distribution/DuctBridge.java @@ -25,7 +25,7 @@ public class DuctBridge extends Block{ public @Load("@-dir") TextureRegion dirRegion; public int range = 4; - public float moveDelay = 5f; + public float speed = 5f; public DuctBridge(String name){ super(name); @@ -116,12 +116,12 @@ public class DuctBridge extends Block{ link.occupied[rotation % 4] = this; if(items.any() && link.items.total() < link.block.itemCapacity){ progress += edelta(); - while(progress > moveDelay){ + while(progress > speed){ Item next = items.take(); if(next != null && link.items.total() < link.block.itemCapacity){ link.handleItem(this, next); } - progress -= moveDelay; + progress -= speed; } } } diff --git a/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java b/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java index 7e1697f401..523edb9654 100644 --- a/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java @@ -57,6 +57,14 @@ public class PayloadConveyor extends Block{ stats.add(Stat.payloadCapacity, (payloadLimit), StatUnit.blocksSquared); } + @Override + public void init(){ + super.init(); + + //increase clip size for oversize loads + clipSize = Math.max(clipSize, size * tilesize * 2.1f); + } + public class PayloadConveyorBuild extends Building{ public @Nullable Payload item; public float progress, itemRotation, animation; diff --git a/core/src/mindustry/world/blocks/payloads/PayloadSource.java b/core/src/mindustry/world/blocks/payloads/PayloadSource.java index aa6a5c9a6c..68bf32e744 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadSource.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadSource.java @@ -27,6 +27,8 @@ public class PayloadSource extends PayloadBlock{ hasPower = true; rotate = true; configurable = true; + //make sure to display large units. + clipSize = 120; config(Block.class, (PayloadSourceBuild build, Block block) -> { if(canProduce(block) && build.block != block){ @@ -45,6 +47,13 @@ public class PayloadSource extends PayloadBlock{ build.scl = 0f; } }); + + configClear((PayloadSourceBuild build) -> { + build.block = null; + build.unit = null; + build.payload = null; + build.scl = 0f; + }); } @Override diff --git a/core/src/mindustry/world/blocks/payloads/PayloadVoid.java b/core/src/mindustry/world/blocks/payloads/PayloadVoid.java index 434753f0ee..2c8cd68bf2 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadVoid.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadVoid.java @@ -19,6 +19,8 @@ public class PayloadVoid extends PayloadBlock{ update = true; rotate = false; size = 3; + //make sure to display large units. + clipSize = 120; } @Override diff --git a/core/src/mindustry/world/blocks/payloads/UnitPayload.java b/core/src/mindustry/world/blocks/payloads/UnitPayload.java index 2300dba10b..22d11f4b65 100644 --- a/core/src/mindustry/world/blocks/payloads/UnitPayload.java +++ b/core/src/mindustry/world/blocks/payloads/UnitPayload.java @@ -4,10 +4,10 @@ import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; -import arc.math.geom.*; import arc.util.*; import arc.util.io.*; import mindustry.*; +import mindustry.core.*; import mindustry.entities.EntityCollisions.*; import mindustry.entities.*; import mindustry.game.EventType.*; @@ -69,14 +69,12 @@ public class UnitPayload implements Payload{ //check if unit can be dumped here SolidPred solid = unit.solidity(); if(solid != null){ - int tx = unit.tileX(), ty = unit.tileY(); - boolean nearEmpty = !solid.solid(tx, ty); - for(Point2 p : Geometry.d4){ - nearEmpty |= !solid.solid(tx + p.x, ty + p.y); - } + Tmp.v1.trns(unit.rotation, 1f); + + int tx = World.toTile(unit.x + Tmp.v1.x), ty = World.toTile(unit.y + Tmp.v1.y); //cannot dump on solid blocks - if(!nearEmpty) return false; + if(solid.solid(tx, ty)) return false; } //cannnot dump when there's a lot of overlap going on diff --git a/gradle.properties b/gradle.properties index 0d662cd2bc..696bad812c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,4 +8,4 @@ kapt.use.worker.api=true kapt.include.compile.classpath=false # I don't need to use the kotlin stdlib yet, so remove it to prevent extra bloat & method count issues kotlin.stdlib.default.dependency=false -archash=4db7abe679c53dbcef400b65da75247ffa6334d3 +archash=5a9d95001fc988df2681616ebc33152b9c88ea92