mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-12-15 15:20:57 -08:00
Merged Unit & Builder components / Cleanup
This commit is contained in:
parent
8280166485
commit
527be41e32
38 changed files with 152 additions and 125 deletions
|
|
@ -1,10 +1,13 @@
|
|||
#Maps entity names to IDs. Autogenerated.
|
||||
|
||||
alpha=0
|
||||
arkyid=29
|
||||
atrax=1
|
||||
beta=30
|
||||
block=2
|
||||
corvus=24
|
||||
flare=3
|
||||
gamma=31
|
||||
mace=4
|
||||
mega=5
|
||||
mindustry.entities.comp.BuildingComp=6
|
||||
|
|
@ -26,6 +29,8 @@ oct=26
|
|||
poly=18
|
||||
pulsar=19
|
||||
quad=23
|
||||
quasar=32
|
||||
risso=20
|
||||
spiroct=21
|
||||
toxopid=33
|
||||
vela=25
|
||||
1
annotations/src/main/resources/revisions/alpha/0.json
Normal file
1
annotations/src/main/resources/revisions/alpha/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/arkyid/0.json
Normal file
1
annotations/src/main/resources/revisions/arkyid/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/beta/0.json
Normal file
1
annotations/src/main/resources/revisions/beta/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/block/4.json
Normal file
1
annotations/src/main/resources/revisions/block/4.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/corvus/4.json
Normal file
1
annotations/src/main/resources/revisions/corvus/4.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/flare/4.json
Normal file
1
annotations/src/main/resources/revisions/flare/4.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/gamma/0.json
Normal file
1
annotations/src/main/resources/revisions/gamma/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/mace/4.json
Normal file
1
annotations/src/main/resources/revisions/mace/4.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/mono/3.json
Normal file
1
annotations/src/main/resources/revisions/mono/3.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/pulsar/0.json
Normal file
1
annotations/src/main/resources/revisions/pulsar/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/quasar/0.json
Normal file
1
annotations/src/main/resources/revisions/quasar/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/risso/4.json
Normal file
1
annotations/src/main/resources/revisions/risso/4.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
1
annotations/src/main/resources/revisions/toxopid/0.json
Normal file
1
annotations/src/main/resources/revisions/toxopid/0.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}
|
||||
|
|
@ -1279,6 +1279,7 @@ liquid.slag.description = Refined in separators into constituent metals, or spra
|
|||
liquid.oil.description = Used in advanced material production and as incendiary ammunition.
|
||||
liquid.cryofluid.description = Used as coolant in reactors, turrets and factories.
|
||||
|
||||
block.resupply-point.description = Resupplies nearby units with copper ammunition. Not compatible with units that require battery power.
|
||||
block.armored-conveyor.description = Moves items forward. Does not accept inputs from the sides.
|
||||
block.illuminator.description = Emits light.
|
||||
block.message.description = Stores a message for communication between allies.
|
||||
|
|
|
|||
|
|
@ -14,21 +14,20 @@ import static mindustry.Vars.*;
|
|||
public class BuilderAI extends AIController{
|
||||
float buildRadius = 1500;
|
||||
boolean found = false;
|
||||
@Nullable Builderc following;
|
||||
@Nullable Unit following;
|
||||
|
||||
@Override
|
||||
public void updateMovement(){
|
||||
Builderc builder = (Builderc)unit;
|
||||
|
||||
if(builder.moving()){
|
||||
builder.lookAt(builder.vel().angle());
|
||||
if(unit.moving()){
|
||||
unit.lookAt(unit.vel.angle());
|
||||
}
|
||||
|
||||
if(target != null && shouldShoot()){
|
||||
unit.lookAt(target);
|
||||
}
|
||||
|
||||
builder.updateBuilding(true);
|
||||
unit.updateBuilding = true;
|
||||
|
||||
if(following != null){
|
||||
//try to follow and mimic someone
|
||||
|
|
@ -36,18 +35,18 @@ public class BuilderAI extends AIController{
|
|||
//validate follower
|
||||
if(!following.isValid() || !following.activelyBuilding()){
|
||||
following = null;
|
||||
builder.plans().clear();
|
||||
unit.plans.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
//set to follower's first build plan, whatever that is
|
||||
builder.plans().clear();
|
||||
builder.plans().addFirst(following.buildPlan());
|
||||
unit.plans.clear();
|
||||
unit.plans.addFirst(following.buildPlan());
|
||||
}
|
||||
|
||||
if(builder.buildPlan() != null){
|
||||
if(unit.buildPlan() != null){
|
||||
//approach request if building
|
||||
BuildPlan req = builder.buildPlan();
|
||||
BuildPlan req = unit.buildPlan();
|
||||
|
||||
boolean valid =
|
||||
(req.tile().build instanceof ConstructBuild && req.tile().<ConstructBuild>bc().cblock == req.block) ||
|
||||
|
|
@ -60,7 +59,7 @@ public class BuilderAI extends AIController{
|
|||
moveTo(req.tile(), buildingRange - 20f);
|
||||
}else{
|
||||
//discard invalid request
|
||||
builder.plans().removeFirst();
|
||||
unit.plans.removeFirst();
|
||||
}
|
||||
}else{
|
||||
|
||||
|
|
@ -71,8 +70,8 @@ public class BuilderAI extends AIController{
|
|||
Units.nearby(unit.team, unit.x, unit.y, buildRadius, u -> {
|
||||
if(found) return;
|
||||
|
||||
if(u instanceof Builderc b && u != unit && b.activelyBuilding()){
|
||||
BuildPlan plan = b.buildPlan();
|
||||
if(u.canBuild() && u != unit && u.activelyBuilding()){
|
||||
BuildPlan plan = u.buildPlan();
|
||||
|
||||
Building build = world.build(plan.x, plan.y);
|
||||
if(build instanceof ConstructBuild cons){
|
||||
|
|
@ -80,7 +79,7 @@ public class BuilderAI extends AIController{
|
|||
|
||||
//make sure you can reach the request in time
|
||||
if(dist / unit.speed() < cons.buildCost * 0.9f){
|
||||
following = b;
|
||||
following = u;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +97,7 @@ public class BuilderAI extends AIController{
|
|||
blocks.removeFirst();
|
||||
}else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid.
|
||||
//add build request.
|
||||
builder.addBuild(new BuildPlan(block.x, block.y, block.rotation, content.block(block.block), block.config));
|
||||
unit.addBuild(new BuildPlan(block.x, block.y, block.rotation, content.block(block.block), block.config));
|
||||
//shift build plan to tail so next unit builds something else.
|
||||
blocks.addLast(blocks.removeFirst());
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -59,13 +59,13 @@ public class FormationAI extends AIController implements FormationMember{
|
|||
unit.moveAt(realtarget.sub(unit).limit(speed));
|
||||
}
|
||||
|
||||
if(unit instanceof Minerc mine && leader instanceof Minerc com){
|
||||
if(com.mineTile() != null && mine.validMine(com.mineTile())){
|
||||
mine.mineTile(com.mineTile());
|
||||
if(unit.canMine() && leader.canMine()){
|
||||
if(leader.mineTile != null && unit.validMine(leader.mineTile)){
|
||||
unit.mineTile(leader.mineTile);
|
||||
|
||||
CoreBuild core = unit.team.core();
|
||||
|
||||
if(core != null && com.mineTile().drop() != null && unit.within(core, unit.type.range) && !unit.acceptsItem(com.mineTile().drop())){
|
||||
if(core != null && leader.mineTile.drop() != null && unit.within(core, unit.type.range) && !unit.acceptsItem(leader.mineTile.drop())){
|
||||
if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){
|
||||
Call.transferItemTo(unit.stack.item, unit.stack.amount, unit.x, unit.y, core);
|
||||
|
||||
|
|
@ -73,13 +73,13 @@ public class FormationAI extends AIController implements FormationMember{
|
|||
}
|
||||
}
|
||||
}else{
|
||||
mine.mineTile(null);
|
||||
unit.mineTile(null);
|
||||
}
|
||||
}
|
||||
|
||||
if(unit instanceof Builderc build && leader instanceof Builderc com && com.activelyBuilding()){
|
||||
build.clearBuilding();
|
||||
build.addBuild(com.buildPlan());
|
||||
if(unit.canBuild() && leader.canBuild() && leader.activelyBuilding()){
|
||||
unit.clearBuilding();
|
||||
leader.addBuild(unit.buildPlan());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,9 +92,7 @@ public class LogicAI extends AIController{
|
|||
}
|
||||
}
|
||||
case stop -> {
|
||||
if(unit instanceof Builderc build){
|
||||
build.clearBuilding();
|
||||
}
|
||||
unit.clearBuilding();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,21 +17,21 @@ public class MinerAI extends AIController{
|
|||
protected void updateMovement(){
|
||||
Building core = unit.closestCore();
|
||||
|
||||
if(!(unit instanceof Minerc miner) || core == null) return;
|
||||
if(!(unit.canMine()) || core == null) return;
|
||||
|
||||
if(miner.mineTile() != null && !miner.mineTile().within(unit, unit.type.range)){
|
||||
miner.mineTile(null);
|
||||
if(unit.mineTile != null && !unit.mineTile.within(unit, unit.type.range)){
|
||||
unit.mineTile(null);
|
||||
}
|
||||
|
||||
if(mining){
|
||||
if(timer.get(timerTarget2, 60 * 4) || targetItem == null){
|
||||
targetItem = unit.team.data().mineItems.min(i -> indexer.hasOre(i) && miner.canMine(i), i -> core.items.get(i));
|
||||
targetItem = unit.team.data().mineItems.min(i -> indexer.hasOre(i) && unit.canMine(i), i -> core.items.get(i));
|
||||
}
|
||||
|
||||
//core full of the target item, do nothing
|
||||
if(targetItem != null && core.acceptStack(targetItem, 1, unit) == 0){
|
||||
unit.clearItem();
|
||||
miner.mineTile(null);
|
||||
unit.mineTile(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ public class MinerAI extends AIController{
|
|||
moveTo(ore, unit.type.range / 2f, 20f);
|
||||
|
||||
if(unit.within(ore, unit.type.range)){
|
||||
miner.mineTile(ore);
|
||||
unit.mineTile = ore;
|
||||
}
|
||||
|
||||
if(ore.block() != Blocks.air){
|
||||
|
|
@ -56,7 +56,7 @@ public class MinerAI extends AIController{
|
|||
}
|
||||
}
|
||||
}else{
|
||||
miner.mineTile(null);
|
||||
unit.mineTile = null;
|
||||
|
||||
if(unit.stack.amount == 0){
|
||||
mining = true;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,13 @@ import static mindustry.Vars.*;
|
|||
public class UnitTypes implements ContentList{
|
||||
//region definitions
|
||||
|
||||
//(the wall of shame - should fix the legacy stuff eventually...)
|
||||
|
||||
//mech
|
||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
||||
|
||||
//mech + builder + miner
|
||||
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class}) UnitType nova, pulsar, quasar;
|
||||
//mech
|
||||
public static @EntityDef(value = {Unitc.class, Mechc.class}, legacy = true) UnitType nova, pulsar, quasar;
|
||||
|
||||
//mech
|
||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType vela;
|
||||
|
|
@ -29,29 +31,29 @@ public class UnitTypes implements ContentList{
|
|||
//legs
|
||||
public static @EntityDef({Unitc.class, Legsc.class}) UnitType corvus, atrax;
|
||||
|
||||
//legs + building
|
||||
public static @EntityDef({Unitc.class, Legsc.class, Builderc.class}) UnitType spiroct, arkyid, toxopid;
|
||||
//legs
|
||||
public static @EntityDef(value = {Unitc.class, Legsc.class}, legacy = true) UnitType spiroct, arkyid, toxopid;
|
||||
|
||||
//air (no special traits)
|
||||
//air
|
||||
public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra;
|
||||
|
||||
//air, legacy mining
|
||||
//air
|
||||
public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono;
|
||||
|
||||
//air + building + mining
|
||||
public static @EntityDef({Unitc.class, Builderc.class}) UnitType poly;
|
||||
//air
|
||||
public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType poly;
|
||||
|
||||
//air + building + mining + payload
|
||||
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class}) UnitType mega;
|
||||
//air + payload
|
||||
public static @EntityDef({Unitc.class, Payloadc.class}) UnitType mega;
|
||||
|
||||
//air + building + payload
|
||||
public static @EntityDef(value = {Unitc.class, Builderc.class, Payloadc.class}, legacy = true) UnitType quad;
|
||||
//air + payload
|
||||
public static @EntityDef(value = {Unitc.class, Payloadc.class}, legacy = true) UnitType quad;
|
||||
|
||||
//air + building + payload
|
||||
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct;
|
||||
//air + payload + ammo distribution
|
||||
public static @EntityDef({Unitc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct;
|
||||
|
||||
//air + building + mining
|
||||
public static @EntityDef({Unitc.class, Builderc.class}) UnitType alpha, beta, gamma;
|
||||
//air
|
||||
public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType alpha, beta, gamma;
|
||||
|
||||
//water
|
||||
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType risso, minke, bryde, sei, omura;
|
||||
|
|
@ -470,7 +472,6 @@ public class UnitTypes implements ContentList{
|
|||
mineTier = 1;
|
||||
hitSize = 29f;
|
||||
health = 18000f;
|
||||
buildSpeed = 1.7f;
|
||||
armor = 9f;
|
||||
landShake = 1.5f;
|
||||
rotateSpeed = 1.5f;
|
||||
|
|
@ -700,6 +701,7 @@ public class UnitTypes implements ContentList{
|
|||
rippleScale = 2f;
|
||||
legSpeed = 0.2f;
|
||||
ammoType = AmmoTypes.power;
|
||||
buildSpeed = 1f;
|
||||
|
||||
legSplashDamage = 32;
|
||||
legSplashRange = 30;
|
||||
|
|
@ -802,6 +804,7 @@ public class UnitTypes implements ContentList{
|
|||
rippleScale = 3f;
|
||||
legSpeed = 0.19f;
|
||||
ammoType = AmmoTypes.powerHigh;
|
||||
buildSpeed = 1f;
|
||||
|
||||
legSplashDamage = 80;
|
||||
legSplashRange = 60;
|
||||
|
|
|
|||
|
|
@ -571,13 +571,13 @@ public class NetClient implements ApplicationListener{
|
|||
BuildPlan[] requests = null;
|
||||
if(player.isBuilder()){
|
||||
//limit to 10 to prevent buffer overflows
|
||||
int usedRequests = Math.min(player.builder().plans().size, 10);
|
||||
int usedRequests = Math.min(player.unit().plans().size, 10);
|
||||
|
||||
int totalLength = 0;
|
||||
|
||||
//prevent buffer overflow by checking config length
|
||||
for(int i = 0; i < usedRequests; i++){
|
||||
BuildPlan plan = player.builder().plans().get(i);
|
||||
BuildPlan plan = player.unit().plans().get(i);
|
||||
if(plan.config instanceof byte[] b){
|
||||
int length = b.length;
|
||||
totalLength += length;
|
||||
|
|
@ -591,7 +591,7 @@ public class NetClient implements ApplicationListener{
|
|||
|
||||
requests = new BuildPlan[usedRequests];
|
||||
for(int i = 0; i < usedRequests; i++){
|
||||
requests[i] = player.builder().plans().get(i);
|
||||
requests[i] = player.unit().plans().get(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -607,7 +607,7 @@ public class NetClient implements ApplicationListener{
|
|||
unit.rotation,
|
||||
unit instanceof Mechc m ? m.baseRotation() : 0,
|
||||
unit.vel.x, unit.vel.y,
|
||||
player.unit().mineTile(),
|
||||
player.unit().mineTile,
|
||||
player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding,
|
||||
requests,
|
||||
Core.camera.position.x, Core.camera.position.y,
|
||||
|
|
|
|||
|
|
@ -600,8 +600,8 @@ public class NetServer implements ApplicationListener{
|
|||
player.unit().aim(pointerX, pointerY);
|
||||
|
||||
if(player.isBuilder()){
|
||||
player.builder().clearBuilding();
|
||||
player.builder().updateBuilding(building);
|
||||
player.unit().clearBuilding();
|
||||
player.unit().updateBuilding(building);
|
||||
|
||||
if(requests != null){
|
||||
for(BuildPlan req : requests){
|
||||
|
|
@ -625,7 +625,7 @@ public class NetServer implements ApplicationListener{
|
|||
con.rejectedRequests.add(req);
|
||||
continue;
|
||||
}
|
||||
player.builder().plans().addLast(req);
|
||||
player.unit().plans().addLast(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import mindustry.entities.units.*;
|
|||
import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.blocks.ConstructBlock.*;
|
||||
|
|
@ -22,17 +23,22 @@ import java.util.*;
|
|||
import static mindustry.Vars.*;
|
||||
|
||||
@Component
|
||||
abstract class BuilderComp implements Unitc{
|
||||
abstract class BuilderComp implements Posc, Teamc, Rotc{
|
||||
static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()};
|
||||
|
||||
@Import float x, y, rotation;
|
||||
@Import UnitType type;
|
||||
|
||||
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
|
||||
@SyncLocal transient boolean updateBuilding = true;
|
||||
|
||||
public boolean canBuild(){
|
||||
return type.buildSpeed > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(!updateBuilding) return;
|
||||
if(!updateBuilding || !canBuild()) return;
|
||||
|
||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
|
||||
boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources;
|
||||
|
|
@ -102,9 +108,9 @@ abstract class BuilderComp implements Unitc{
|
|||
ConstructBuild entity = tile.bc();
|
||||
|
||||
if(current.breaking){
|
||||
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier);
|
||||
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier);
|
||||
}else{
|
||||
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier, current.config);
|
||||
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier, current.config);
|
||||
}
|
||||
|
||||
current.stuck = Mathf.equal(current.progress, entity.progress);
|
||||
|
|
@ -161,6 +167,8 @@ abstract class BuilderComp implements Unitc{
|
|||
|
||||
/** Add another build requests to the queue, if it doesn't exist there yet. */
|
||||
void addBuild(BuildPlan place, boolean tail){
|
||||
if(!canBuild()) return;
|
||||
|
||||
BuildPlan replace = null;
|
||||
for(BuildPlan request : plans){
|
||||
if(request.x == place.x && request.y == place.y){
|
||||
|
|
@ -196,9 +204,8 @@ abstract class BuilderComp implements Unitc{
|
|||
return plans.size == 0 ? null : plans.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
if(!isBuilding() || !updateBuilding) return;
|
||||
if(!isBuilding() || !updateBuilding || !canBuild()) return;
|
||||
|
||||
//TODO check correctness
|
||||
Draw.z(Layer.flyingUnit);
|
||||
|
|
|
|||
|
|
@ -1122,7 +1122,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||
|
||||
/** Returns whether or not a hand cursor should be shown over this block. */
|
||||
public Cursor getCursor(){
|
||||
return block.configurable ? SystemCursor.hand : SystemCursor.arrow;
|
||||
return block.configurable && team == player.team() ? SystemCursor.hand : SystemCursor.arrow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
|
|||
}
|
||||
|
||||
boolean mining(){
|
||||
return mineTile != null && !(((Object)this) instanceof Builderc b && b.activelyBuilding());
|
||||
return mineTile != null && !this.<Unit>self().activelyBuilding();
|
||||
}
|
||||
|
||||
public boolean validMine(Tile tile, boolean checkDst){
|
||||
|
|
@ -44,6 +44,10 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
|
|||
return validMine(tile, true);
|
||||
}
|
||||
|
||||
public boolean canMine(){
|
||||
return type.mineSpeed > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
Building core = closestCore();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||
transient float textFadeTime;
|
||||
|
||||
public boolean isBuilder(){
|
||||
return unit instanceof Builderc;
|
||||
return unit.canBuild();
|
||||
}
|
||||
|
||||
public @Nullable CoreBuild closestCore(){
|
||||
|
|
@ -160,10 +160,6 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||
return unit;
|
||||
}
|
||||
|
||||
public Builderc builder(){
|
||||
return !(unit instanceof Builderc) ? Nulls.builder : (Builderc)unit;
|
||||
}
|
||||
|
||||
public void unit(Unit unit){
|
||||
if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead.");
|
||||
if(this.unit == unit) return;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import mindustry.world.blocks.payloads.*;
|
|||
import static mindustry.Vars.*;
|
||||
|
||||
@Component(base = true)
|
||||
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc{
|
||||
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{
|
||||
|
||||
@Import boolean hovering, dead;
|
||||
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed;
|
||||
|
|
@ -88,8 +88,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||
|
||||
/** @return where the unit wants to look at. */
|
||||
public float prefRotation(){
|
||||
if(this instanceof Builderc builder && builder.activelyBuilding()){
|
||||
return angleTo(builder.buildPlan());
|
||||
if(activelyBuilding()){
|
||||
return angleTo(buildPlan());
|
||||
}else if(mineTile() != null){
|
||||
return angleTo(mineTile());
|
||||
}else if(moving()){
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class OverlayRenderer{
|
|||
if(player.dead()) return;
|
||||
|
||||
if(player.isBuilder()){
|
||||
player.builder().drawBuildRequests();
|
||||
player.unit().drawBuildRequests();
|
||||
}
|
||||
|
||||
input.drawBottom();
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public class DesktopInput extends InputHandler{
|
|||
group.fill(t -> {
|
||||
t.bottom();
|
||||
t.visible(() -> {
|
||||
t.color.a = Mathf.lerpDelta(t.color.a, player.builder().isBuilding() ? 1f : 0f, 0.15f);
|
||||
t.color.a = Mathf.lerpDelta(t.color.a, player.unit().isBuilding() ? 1f : 0f, 0.15f);
|
||||
|
||||
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && t.color.a > 0.01f;
|
||||
});
|
||||
|
|
@ -290,7 +290,7 @@ public class DesktopInput extends InputHandler{
|
|||
cursorType = cursor.build.getCursor();
|
||||
}
|
||||
|
||||
if(isPlacing() || !selectRequests.isEmpty()){
|
||||
if((isPlacing() && player.isBuilder()) || !selectRequests.isEmpty()){
|
||||
cursorType = SystemCursor.hand;
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ public class DesktopInput extends InputHandler{
|
|||
int rawCursorX = World.toTile(Core.input.mouseWorld().x), rawCursorY = World.toTile(Core.input.mouseWorld().y);
|
||||
|
||||
// automatically pause building if the current build queue is empty
|
||||
if(Core.settings.getBool("buildautopause") && isBuilding && !player.builder().isBuilding()){
|
||||
if(Core.settings.getBool("buildautopause") && isBuilding && !player.unit().isBuilding()){
|
||||
isBuilding = false;
|
||||
buildWasAutoPaused = true;
|
||||
}
|
||||
|
|
@ -388,7 +388,7 @@ public class DesktopInput extends InputHandler{
|
|||
}
|
||||
|
||||
if(Core.input.keyTap(Binding.clear_building)){
|
||||
player.builder().clearBuilding();
|
||||
player.unit().clearBuilding();
|
||||
}
|
||||
|
||||
if(Core.input.keyTap(Binding.schematic_select) && !Core.scene.hasKeyboard() && mode != breaking){
|
||||
|
|
@ -480,8 +480,8 @@ public class DesktopInput extends InputHandler{
|
|||
deleting = true;
|
||||
}else if(selected != null){
|
||||
//only begin shooting if there's no cursor event
|
||||
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !player.builder().activelyBuilding() && !droppingItem &&
|
||||
!tryBeginMine(selected) && player.unit().mineTile() == null && !Core.scene.hasKeyboard()){
|
||||
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !player.unit().activelyBuilding() && !droppingItem &&
|
||||
!tryBeginMine(selected) && player.unit().mineTile == null && !Core.scene.hasKeyboard()){
|
||||
player.shooting = shouldShoot;
|
||||
}
|
||||
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
|
||||
|
|
@ -506,7 +506,7 @@ public class DesktopInput extends InputHandler{
|
|||
if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){
|
||||
BuildPlan req = getRequest(cursorX, cursorY);
|
||||
if(req != null && req.breaking){
|
||||
player.builder().plans().remove(req);
|
||||
player.unit().plans().remove(req);
|
||||
}
|
||||
}else{
|
||||
deleting = false;
|
||||
|
|
@ -547,7 +547,7 @@ public class DesktopInput extends InputHandler{
|
|||
|
||||
if(sreq != null){
|
||||
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
|
||||
player.builder().plans().remove(sreq, true);
|
||||
player.unit().plans().remove(sreq, true);
|
||||
}
|
||||
sreq = null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
|
||||
@Remote(variants = Variant.one)
|
||||
public static void removeQueueBlock(int x, int y, boolean breaking){
|
||||
player.builder().removeBuild(x, y, breaking);
|
||||
player.unit().removeBuild(x, y, breaking);
|
||||
}
|
||||
|
||||
@Remote(targets = Loc.both, called = Loc.server)
|
||||
|
|
@ -383,7 +383,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
|
||||
public Eachable<BuildPlan> allRequests(){
|
||||
return cons -> {
|
||||
for(BuildPlan request : player.builder().plans()) cons.get(request);
|
||||
for(BuildPlan request : player.unit().plans()) cons.get(request);
|
||||
for(BuildPlan request : selectRequests) cons.get(request);
|
||||
for(BuildPlan request : lineRequests) cons.get(request);
|
||||
};
|
||||
|
|
@ -401,7 +401,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
player.typing = ui.chatfrag.shown();
|
||||
|
||||
if(player.isBuilder()){
|
||||
player.builder().updateBuilding(isBuilding);
|
||||
player.unit().updateBuilding(isBuilding);
|
||||
}
|
||||
|
||||
if(player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && player.unit().ammo <= 0){
|
||||
|
|
@ -653,7 +653,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
return r2.overlaps(r1);
|
||||
};
|
||||
|
||||
for(BuildPlan req : player.builder().plans()){
|
||||
for(BuildPlan req : player.unit().plans()){
|
||||
if(test.get(req)) return req;
|
||||
}
|
||||
|
||||
|
|
@ -678,7 +678,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
Draw.color(Pal.remove);
|
||||
Lines.stroke(1f);
|
||||
|
||||
for(BuildPlan req : player.builder().plans()){
|
||||
for(BuildPlan req : player.unit().plans()){
|
||||
if(req.breaking) continue;
|
||||
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
||||
drawBreaking(req);
|
||||
|
|
@ -740,7 +740,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
for(BuildPlan req : requests){
|
||||
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
|
||||
BuildPlan copy = req.copy();
|
||||
player.builder().addBuild(copy);
|
||||
player.unit().addBuild(copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -804,7 +804,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
//remove build requests
|
||||
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
|
||||
|
||||
Iterator<BuildPlan> it = player.builder().plans().iterator();
|
||||
Iterator<BuildPlan> it = player.unit().plans().iterator();
|
||||
while(it.hasNext()){
|
||||
BuildPlan req = it.next();
|
||||
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
|
||||
|
|
@ -1044,7 +1044,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
}
|
||||
|
||||
public boolean canShoot(){
|
||||
return block == null && !onConfigurable() && !isDroppingItem() && !player.builder().activelyBuilding() &&
|
||||
return block == null && !onConfigurable() && !isDroppingItem() && !player.unit().activelyBuilding() &&
|
||||
!(player.unit() instanceof Mechc && player.unit().isFlying());
|
||||
}
|
||||
|
||||
|
|
@ -1090,7 +1090,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
}
|
||||
|
||||
public boolean validPlace(int x, int y, Block type, int rotation, BuildPlan ignore){
|
||||
for(BuildPlan req : player.builder().plans()){
|
||||
for(BuildPlan req : player.unit().plans()){
|
||||
if(req != ignore
|
||||
&& !req.breaking
|
||||
&& req.block.bounds(req.x, req.y, Tmp.r1).overlaps(type.bounds(x, y, Tmp.r2))
|
||||
|
|
@ -1108,15 +1108,15 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
public void placeBlock(int x, int y, Block block, int rotation){
|
||||
BuildPlan req = getRequest(x, y);
|
||||
if(req != null){
|
||||
player.builder().plans().remove(req);
|
||||
player.unit().plans().remove(req);
|
||||
}
|
||||
player.builder().addBuild(new BuildPlan(x, y, rotation, block, block.nextConfig()));
|
||||
player.unit().addBuild(new BuildPlan(x, y, rotation, block, block.nextConfig()));
|
||||
}
|
||||
|
||||
public void breakBlock(int x, int y){
|
||||
Tile tile = world.tile(x, y);
|
||||
if(tile != null && tile.build != null) tile = tile.build.tile;
|
||||
player.builder().addBuild(new BuildPlan(tile.x, tile.y));
|
||||
player.unit().addBuild(new BuildPlan(tile.x, tile.y));
|
||||
}
|
||||
|
||||
public void drawArrow(Block block, int x, int y, int rotation){
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
}
|
||||
}
|
||||
|
||||
for(BuildPlan req : player.builder().plans()){
|
||||
for(BuildPlan req : player.unit().plans()){
|
||||
Tile other = world.tile(req.x, req.y);
|
||||
|
||||
if(other == null || req.breaking) continue;
|
||||
|
|
@ -219,10 +219,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
BuildPlan copy = request.copy();
|
||||
|
||||
if(other == null){
|
||||
player.builder().addBuild(copy);
|
||||
player.unit().addBuild(copy);
|
||||
}else if(!other.breaking && other.x == request.x && other.y == request.y && other.block.size == request.block.size){
|
||||
player.builder().plans().remove(other);
|
||||
player.builder().addBuild(copy);
|
||||
player.unit().plans().remove(other);
|
||||
player.unit().addBuild(copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -245,10 +245,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
Boolp schem = () -> lastSchematic != null && !selectRequests.isEmpty();
|
||||
|
||||
group.fill(t -> {
|
||||
t.visible(() -> (player.builder().isBuilding() || block != null || mode == breaking || !selectRequests.isEmpty()) && !schem.get());
|
||||
t.visible(() -> (player.unit().isBuilding() || block != null || mode == breaking || !selectRequests.isEmpty()) && !schem.get());
|
||||
t.bottom().left();
|
||||
t.button("@cancel", Icon.cancel, () -> {
|
||||
player.builder().clearBuilding();
|
||||
player.unit().clearBuilding();
|
||||
selectRequests.clear();
|
||||
mode = none;
|
||||
block = null;
|
||||
|
|
@ -914,7 +914,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||
}
|
||||
|
||||
//update shooting if not building + not mining
|
||||
if(!player.builder().isBuilding() && player.unit().mineTile() == null){
|
||||
if(!player.unit().isBuilding() && player.unit().mineTile == null){
|
||||
|
||||
//autofire targeting
|
||||
if(manualShooting){
|
||||
|
|
|
|||
|
|
@ -321,13 +321,8 @@ public class LExecutor{
|
|||
((LogicAI)unit.controller()).controller = exec.building(varThis);
|
||||
|
||||
//clear old state
|
||||
if(unit instanceof Minerc miner){
|
||||
miner.mineTile(null);
|
||||
}
|
||||
|
||||
if(unit instanceof Builderc builder){
|
||||
builder.clearBuilding();
|
||||
}
|
||||
unit.mineTile = null;
|
||||
unit.clearBuilding();
|
||||
|
||||
return (LogicAI)unit.controller();
|
||||
}
|
||||
|
|
@ -357,12 +352,8 @@ public class LExecutor{
|
|||
|
||||
//stop mining/building
|
||||
if(type == LUnitControl.stop){
|
||||
if(unit instanceof Minerc miner){
|
||||
miner.mineTile(null);
|
||||
}
|
||||
if(unit instanceof Builderc build){
|
||||
build.clearBuilding();
|
||||
}
|
||||
unit.mineTile = null;
|
||||
unit.clearBuilding();
|
||||
}
|
||||
}
|
||||
case within -> {
|
||||
|
|
@ -390,8 +381,8 @@ public class LExecutor{
|
|||
}
|
||||
case mine -> {
|
||||
Tile tile = world.tileWorld(x1, y1);
|
||||
if(unit instanceof Minerc miner){
|
||||
miner.mineTile(miner.validMine(tile) ? tile : null);
|
||||
if(unit.canMine()){
|
||||
unit.mineTile = unit.validMine(tile) ? tile : null;
|
||||
}
|
||||
}
|
||||
case payDrop -> {
|
||||
|
|
@ -432,12 +423,12 @@ public class LExecutor{
|
|||
}
|
||||
}
|
||||
case build -> {
|
||||
if(unit instanceof Builderc builder && exec.obj(p3) instanceof Block block){
|
||||
if(unit.canBuild() && exec.obj(p3) instanceof Block block){
|
||||
int x = World.toTile(x1), y = World.toTile(y1);
|
||||
int rot = exec.numi(p4);
|
||||
|
||||
//reset state of last request when necessary
|
||||
if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || builder.plans().isEmpty()){
|
||||
if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || unit.plans.isEmpty()){
|
||||
ai.plan.progress = 0;
|
||||
ai.plan.initialized = false;
|
||||
ai.plan.stuck = false;
|
||||
|
|
@ -446,11 +437,11 @@ public class LExecutor{
|
|||
ai.plan.set(x, y, rot, block);
|
||||
ai.plan.config = exec.obj(p5) instanceof Content c ? c : null;
|
||||
|
||||
builder.clearBuilding();
|
||||
unit.clearBuilding();
|
||||
|
||||
if(ai.plan.tile() != null){
|
||||
builder.updateBuilding(true);
|
||||
builder.addBuild(ai.plan);
|
||||
unit.updateBuilding = true;
|
||||
unit.addBuild(ai.plan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ public class UnitType extends UnlockableContent{
|
|||
public int ammoCapacity = -1;
|
||||
public AmmoType ammoType = AmmoTypes.copper;
|
||||
public int mineTier = -1;
|
||||
public float buildSpeed = 1f, mineSpeed = 1f;
|
||||
public float buildSpeed = -1f, mineSpeed = 1f;
|
||||
public Sound mineSound = Sounds.minebeam;
|
||||
public float mineSoundVolume = 0.6f;
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ public class UnitType extends UnlockableContent{
|
|||
stats.addPercent(Stat.mineSpeed, mineSpeed);
|
||||
stats.add(Stat.mineTier, new BlockFilterValue(b -> b instanceof Floor f && f.itemDrop != null && f.itemDrop.hardness <= mineTier && !f.playerUnmineable));
|
||||
}
|
||||
if(inst instanceof Builderc){
|
||||
if(buildSpeed > 0){
|
||||
stats.addPercent(Stat.buildSpeed, buildSpeed);
|
||||
}
|
||||
if(inst instanceof Payloadc){
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public class PlacementFragment extends Fragment{
|
|||
Block tryRecipe = tile == null ? null : tile.block instanceof ConstructBlock ? ((ConstructBuild)tile).cblock : tile.block;
|
||||
Object tryConfig = tile == null ? null : tile.config();
|
||||
|
||||
for(BuildPlan req : player.builder().plans()){
|
||||
for(BuildPlan req : player.unit().plans()){
|
||||
if(!req.breaking && req.block.bounds(req.x, req.y, Tmp.r1).contains(Core.input.mouseWorld())){
|
||||
tryRecipe = req.block;
|
||||
tryConfig = req.config;
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ public class ConstructBlock extends Block{
|
|||
if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){
|
||||
control.input.isBuilding = true;
|
||||
}
|
||||
player.builder().addBuild(new BuildPlan(tile.x, tile.y, rotation, cblock, lastConfig), false);
|
||||
player.unit().addBuild(new BuildPlan(tile.x, tile.y, rotation, cblock, lastConfig), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public interface Payload{
|
|||
return (T)payload;
|
||||
}else if(type == payloadUnit){
|
||||
byte id = read.b();
|
||||
if(EntityMapping.map(id) == null) throw new RuntimeException("No type with ID " + id + " found.");
|
||||
Unit unit = (Unit)EntityMapping.map(id).get();
|
||||
unit.read(read);
|
||||
return (T)new UnitPayload(unit);
|
||||
|
|
|
|||
|
|
@ -433,6 +433,15 @@ public class ApplicationTests{
|
|||
assertEquals(256, world.height());
|
||||
}
|
||||
|
||||
@Test
|
||||
void load114Save(){
|
||||
resetWorld();
|
||||
SaveIO.load(Core.files.internal("114.msav"));
|
||||
|
||||
assertEquals(500, world.width());
|
||||
assertEquals(500, world.height());
|
||||
}
|
||||
|
||||
@Test
|
||||
void arrayIterators(){
|
||||
Seq<String> arr = Seq.with("a", "b" , "c", "d", "e", "f");
|
||||
|
|
|
|||
BIN
tests/src/test/resources/114.msav
Normal file
BIN
tests/src/test/resources/114.msav
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue