diff --git a/core/src/mindustry/ai/types/FormationAI.java b/core/src/mindustry/ai/types/FormationAI.java index f29188f902..49367ae12f 100644 --- a/core/src/mindustry/ai/types/FormationAI.java +++ b/core/src/mindustry/ai/types/FormationAI.java @@ -1,6 +1,7 @@ package mindustry.ai.types; import arc.math.geom.*; +import arc.util.ArcAnnotate.*; import mindustry.*; import mindustry.ai.formations.*; import mindustry.entities.units.*; @@ -10,7 +11,7 @@ public class FormationAI extends AIController implements FormationMember{ public Unitc leader; private Vec3 target = new Vec3(); - private Formation formation; + private @Nullable Formation formation; public FormationAI(Unitc leader, Formation formation){ this.leader = leader; @@ -52,7 +53,9 @@ public class FormationAI extends AIController implements FormationMember{ @Override public void removed(Unitc unit){ - formation.removeMember(this); + if(formation != null){ + formation.removeMember(this); + } } @Override diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index 1d39a5c871..fb0b5f6bf7 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -17,7 +17,7 @@ public class Bullets implements ContentList{ public static BulletType //artillery - artilleryDense, artilleryPlastic, artilleryPlasticFrag, artilleryHoming, artilleryIncendiary, artilleryExplosive, artilleryUnit, + artilleryDense, artilleryPlastic, artilleryPlasticFrag, artilleryHoming, artilleryIncendiary, artilleryExplosive, //flak flakScrap, flakLead, flakPlastic, flakExplosive, flakSurge, flakGlass, glassFrag, @@ -120,19 +120,6 @@ public class Bullets implements ContentList{ statusDuration = 60f; }}; - artilleryUnit = new ArtilleryBulletType(2f, 8, "shell"){{ - hitEffect = Fx.blastExplosion; - knockback = 0.8f; - lifetime = 110f; - bulletWidth = bulletHeight = 14f; - collides = true; - collidesTiles = true; - splashDamageRadius = 20f; - splashDamage = 38f; - backColor = Pal.bulletYellowBack; - frontColor = Pal.bulletYellow; - }}; - glassFrag = new BasicBulletType(3f, 5, "bullet"){{ bulletWidth = 5f; bulletHeight = 12f; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 36aa2ba3e1..8aff8f7f1c 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -209,8 +209,19 @@ public class UnitTypes implements ContentList{ recoil = 4f; shake = 2f; ejectEffect = Fx.shellEjectMedium; - bullet = Bullets.artilleryUnit; shootSound = Sounds.artillery; + bullet = new ArtilleryBulletType(2f, 8, "shell"){{ + hitEffect = Fx.blastExplosion; + knockback = 0.8f; + lifetime = 110f; + bulletWidth = bulletHeight = 14f; + collides = true; + collidesTiles = true; + splashDamageRadius = 20f; + splashDamage = 38f; + backColor = Pal.bulletYellowBack; + frontColor = Pal.bulletYellow; + }}; }}); }}; @@ -569,37 +580,6 @@ public class UnitTypes implements ContentList{ }}); }}; - revenant = new UnitType("revenant", HoverUnit::new){{ - health = 1000; - mass = 5f; - hitsize = 20f; - speed = 0.1f; - maxVelocity = 1f; - drag = 0.01f; - range = 80f; - shootCone = 40f; - flying = true; - //rotateWeapons = true; - engineOffset = 12f; - engineSize = 3f; - rotatespeed = 0.01f; - attackLength = 90f; - baseRotateSpeed = 0.06f; - weapons.add(new Weapon("revenant-missiles"){{ - length = 3f; - reload = 70f; - width = 10f; - shots = 2; - inaccuracy = 2f; - alternate = true; - ejectEffect = Fx.none; - velocityRnd = 0.2f; - spacing = 1f; - shootSound = Sounds.missile; - bullet = Bullets.missileRevenant; - }}); - }}; - lich = new UnitType("lich", HoverUnit::new){{ health = 6000; mass = 20f; @@ -674,47 +654,6 @@ public class UnitTypes implements ContentList{ shootSound = Sounds.shootBig; }}); }}; - - - /* - vanguard = new UnitType("vanguard-ship"){ - float healRange = 60f; - float healReload = 200f; - float healPercent = 10f; - - { - flying = true; - drillTier = 1; - mineSpeed = 4f; - speed = 0.49f; - drag = 0.09f; - health = 200f; - weaponOffsetX = -1; - engineSize = 2.3f; - weaponOffsetY = -1; - engineColor = Pal.lightTrail; - cellTrnsY = 1f; - buildSpeed = 1.2f; - weapons.add(new Weapon("vanguard-gun"){{ - length = 1.5f; - reload = 30f; - alternate = true; - inaccuracy = 6f; - velocityRnd = 0.1f; - ejectEffect = Fx.none; - bullet = new HealBulletType(){{ - healPercent = 3f; - backColor = engineColor; - homingPower = 20f; - bulletHeight = 4f; - bulletWidth = 1.5f; - damage = 3f; - speed = 4f; - lifetime = 40f; - shootEffect = Fx.shootHealYellow; - smokeEffect = hitEffect = despawnEffect = Fx.hitYellowLaser; - }}); - }}; } @Override @@ -735,46 +674,6 @@ public class UnitTypes implements ContentList{ } }; - "alpha "= new UnitType("alpha-mech", false){ - { - drillTier = -1; - speed = 0.5f; - boostSpeed = 0.95f; - itemCapacity = 15; - mass = 0.9f; - health = 150f; - buildSpeed = 0.9f; - weaponOffsetX = 1; - weaponOffsetY = -1; - engineColor = Pal.heal; - - weapons.add(new Weapon("shockgun"){{ - shake = 2f; - length = 0.5f; - reload = 70f; - alternate = true; - recoil = 4f; - width = 5f; - shootSound = Sounds.laser; - - bullet = new LaserBulletType(){{ - damage = 20f; - recoil = 1f; - sideAngle = 45f; - sideWidth = 1f; - sideLength = 70f; - colors = new Color[]{Pal.heal.cpy().a(0.4f), Pal.heal, Color.white}; - }}); - }}; - } - - @Override - public void update(Playerc player){ - player.heal(Time.delta() * 0.09f); - } - - }; - delta = new UnitType("delta-mech", false){ { drillPower = 1; @@ -1041,48 +940,6 @@ public class UnitTypes implements ContentList{ } }; - trident = new UnitType("trident-ship"){ - { - flying = true; - drillPower = 2; - speed = 0.15f; - drag = 0.034f; - mass = 2.5f; - turnCursor = false; - health = 250f; - itemCapacity = 30; - engineColor = Color.valueOf("84f491"); - cellTrnsY = 1f; - buildSpeed = 2.5f; - weapons.add(new Weapon("bomber"){{ - length = 0f; - width = 2f; - reload = 25f; - shots = 2; - shotDelay = 1f; - shots = 8; - alternate = true; - ejectEffect = Fx.none; - velocityRnd = 1f; - inaccuracy = 20f; - ignoreRotation = true; - bullet = new BombBulletType(16f, 25f, "shell"){{ - bulletWidth = 10f; - bulletHeight = 14f; - hitEffect = Fx.flakExplosion; - shootEffect = Fx.none; - smokeEffect = Fx.none; - shootSound = Sounds.artillery; - }}); - }}; - } - - @Override - public boolean canShoot(Playerc player){ - return player.vel().len() > 1.2f; - } - }; - glaive = new UnitType("glaive-ship"){ { flying = true; @@ -1106,8 +963,6 @@ public class UnitTypes implements ContentList{ shootSound = Sounds.shootSnap; }}; } - }; - - starter = vanguard;*/ + };*/ } } diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index a38321807c..ac8c06e5fb 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -641,6 +641,7 @@ public class NetServer implements ApplicationListener{ //now, put the new position, rotation and baserotation into the buffer so it can be read 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); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 9315df8525..ace825f121 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -13,9 +13,6 @@ import arc.scene.ui.layout.*; import arc.util.ArcAnnotate.*; import arc.util.*; import mindustry.*; -import mindustry.ai.formations.*; -import mindustry.ai.formations.patterns.*; -import mindustry.content.*; import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; @@ -583,6 +580,7 @@ public class DesktopInput extends InputHandler{ isBoosting = Core.input.keyDown(Binding.boost) && !movement.isZero(); player.boosting(isBoosting); + //TODO netsync this if(unit instanceof Payloadc){ Payloadc pay = (Payloadc)unit; @@ -604,30 +602,9 @@ public class DesktopInput extends InputHandler{ } if(unit instanceof Commanderc){ - Commanderc commander = (Commanderc)unit; if(Core.input.keyTap(Binding.command)){ - if(commander.isCommanding()){ - commander.clearCommand(); - }else{ - FormationPattern pattern = new SquareFormation(); - Formation formation = new Formation(new Vec3(player.x(), player.y(), player.unit().rotation()), pattern); - formation.slotAssignmentStrategy = new DistanceAssignmentStrategy(pattern); - - units.clear(); - - Fx.commandSend.at(player); - Units.nearby(player.team(), player.x(), player.y(), 200f, u -> { - if(u.isAI()){ - units.add(u); - } - }); - - units.sort(u -> u.dst2(player.unit())); - units.truncate(unit.type().commandLimit); - - commander.command(formation, units); - } + Call.onUnitCommand(player); } } } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index e141dc6277..f9b6ede0e5 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -14,6 +14,8 @@ import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.ArcAnnotate.*; import arc.util.*; +import mindustry.ai.formations.*; +import mindustry.ai.formations.patterns.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.entities.*; @@ -200,6 +202,37 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ player.deathTimer(60f); //for instant respawn } + @Remote(targets = Loc.both, called = Loc.server, forward = true) + public static void onUnitCommand(Playerc player){ + //no free core teleports? + if(!player.dead() || !(player.unit() instanceof Commanderc)) return; + + Commanderc commander = (Commanderc)player.unit(); + + if(commander.isCommanding()){ + commander.clearCommand(); + }else{ + FormationPattern pattern = new SquareFormation(); + Formation formation = new Formation(new Vec3(player.x(), player.y(), player.unit().rotation()), pattern); + formation.slotAssignmentStrategy = new DistanceAssignmentStrategy(pattern); + + units.clear(); + + Fx.commandSend.at(player); + Units.nearby(player.team(), player.x(), player.y(), 200f, u -> { + if(u.isAI()){ + units.add(u); + } + }); + + units.sort(u -> u.dst2(player.unit())); + units.truncate(player.unit().type().commandLimit); + + commander.command(formation, units); + } + + } + public Eachable allRequests(){ return cons -> { for(BuildRequest request : player.builder().requests()) cons.get(request); diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 5d362e73fc..e5c4103091 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -224,8 +224,11 @@ public class TypeIO{ if(control instanceof Playerc){ write.b(0); write.i(((Playerc)control).id()); - }else{ + }else if(control instanceof FormationAI){ write.b(1); + write.i(((FormationAI)control).leader.id()); + }else{ + write.b(2); } } @@ -237,12 +240,15 @@ public class TypeIO{ //local players will cause problems if assigned, since they may not know they are controlling the unit if(player == null || player.isLocal()) return prev; return player; + }else if(type == 1){ + int id = read.i(); + return prev instanceof FormationAI ? prev : new FormationAI(Groups.unit.getByID(id), null); }else{ //there are two cases here: //1: prev controller was not a player, carry on //2: prev controller was a player, so replace this controller with *anything else* //...since AI doesn't update clientside it doesn't matter what - return prev instanceof Playerc ? new GroundAI() : prev; + return (!(prev instanceof AIController) || (prev instanceof FormationAI)) ? new GroundAI() : prev; } } diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index 3559400beb..224ce9af35 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -20,7 +20,7 @@ public class Scripts implements Disposable{ private final Array blacklist = Array.with("net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", "runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system", ".awt", "socket", "classloader", "oracle", "invoke", "arc.events", "java.util.function", "java.util.stream"); - private final Array whitelist = Array.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy"); + private final Array whitelist = Array.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen."); private final Context context; private Scriptable scope; private boolean errored;