Unit assembler progress
This commit is contained in:
@@ -29,6 +29,8 @@ public class CargoAI extends AIController{
|
||||
|
||||
var build = tether.building();
|
||||
|
||||
if(build.items == null) return;
|
||||
|
||||
//empty, approach the loader, even if there's nothing to pick up (units hanging around doing nothing looks bad)
|
||||
if(!unit.hasItem()){
|
||||
moveTo(build, moveRange, moveSmoothing);
|
||||
|
||||
@@ -3312,10 +3312,13 @@ public class Blocks{
|
||||
//endregion
|
||||
//region units - erekir
|
||||
|
||||
//TODO completely unfinished
|
||||
tankAssembler = new UnitAssembler("tank-assembler"){{
|
||||
requirements(Category.units, with(Items.graphite, 10));
|
||||
size = 3;
|
||||
output = UnitTypes.vanquish;
|
||||
requirements = BlockStack.list(Blocks.thoriumWallLarge, 4);
|
||||
droneType = UnitTypes.manifold;
|
||||
requirements = BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2);
|
||||
}};
|
||||
|
||||
//endregion
|
||||
|
||||
@@ -2691,6 +2691,7 @@ public class UnitTypes{
|
||||
itemCapacity = 0;
|
||||
commandLimit = 0;
|
||||
hidden = true;
|
||||
internal = true;
|
||||
}};
|
||||
|
||||
manifold = new UnitType("manifold"){{
|
||||
|
||||
65
core/src/mindustry/type/BlockSeq.java
Normal file
65
core/src/mindustry/type/BlockSeq.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package mindustry.type;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
public class BlockSeq{
|
||||
private ObjectIntMap<Block> blocks = new ObjectIntMap<>();
|
||||
|
||||
public void add(Block block){
|
||||
blocks.increment(block);
|
||||
}
|
||||
|
||||
public void add(Block block, int amount){
|
||||
blocks.increment(block, amount);
|
||||
}
|
||||
|
||||
public void remove(Block block){
|
||||
add(block, -1);
|
||||
}
|
||||
|
||||
public void remove(Block block, int amount){
|
||||
add(block, -amount);
|
||||
}
|
||||
|
||||
public void remove(Seq<BlockStack> stacks){
|
||||
stacks.each(b -> remove(b.block, b.amount));
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
blocks.clear();
|
||||
}
|
||||
|
||||
public int get(Block block){
|
||||
return blocks.get(block);
|
||||
}
|
||||
|
||||
public boolean contains(Seq<BlockStack> stacks){
|
||||
return !stacks.contains(b -> get(b.block) < b.amount);
|
||||
}
|
||||
|
||||
public boolean contains(Block block, int amount){
|
||||
return get(block) >= amount;
|
||||
}
|
||||
|
||||
public boolean contains(BlockStack stack){
|
||||
return get(stack.block) >= stack.amount;
|
||||
}
|
||||
|
||||
public void write(Writes write){
|
||||
write.s(blocks.size);
|
||||
for(var entry : blocks.entries()){
|
||||
write.s(entry.key.id);
|
||||
write.i(entry.value);
|
||||
}
|
||||
}
|
||||
|
||||
public void read(Reads read){
|
||||
short amount = read.s();
|
||||
for(int i = 0; i < amount; i++){
|
||||
blocks.put(Vars.content.block(read.s()), read.i());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,6 +156,7 @@ public class UnitType extends UnlockableContent{
|
||||
public boolean singleTarget = false;
|
||||
public boolean forceMultiTarget = false;
|
||||
public boolean hidden = false;
|
||||
public boolean internal = false;
|
||||
|
||||
//for crawlers
|
||||
public int segments = 0;
|
||||
|
||||
@@ -44,4 +44,8 @@ public class ItemImage extends Stack{
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public ItemImage(BlockStack stack){
|
||||
this(stack.block.uiIcon, stack.amount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public class BuildTurret extends BaseTurret{
|
||||
//this is super hacky, but since blocks are initialized before units it does not run into init/concurrent modification issues
|
||||
unitType = new UnitType("turret-unit-" + name){{
|
||||
hidden = true;
|
||||
internal = true;
|
||||
speed = 0f;
|
||||
hitSize = 0f;
|
||||
health = 1;
|
||||
|
||||
@@ -124,6 +124,11 @@ public class Duct extends Block implements Autotiler{
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void payloadDraw(){
|
||||
Draw.rect(fullIcon, x, y);
|
||||
}
|
||||
|
||||
protected void drawAt(float x, float y, int bits, float rotation, SliceMode slice){
|
||||
Draw.z(Layer.blockUnder);
|
||||
Draw.rect(sliced(botRegions[bits], slice), x, y, rotation);
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package mindustry.world.blocks.units;
|
||||
|
||||
import arc.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.blocks.payloads.*;
|
||||
import mindustry.world.consumers.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@@ -20,13 +27,13 @@ import static mindustry.Vars.*;
|
||||
* 3.
|
||||
* */
|
||||
public class UnitAssembler extends PayloadBlock{
|
||||
public int areaSize = 10;
|
||||
public int areaSize = 11;
|
||||
public UnitType droneType;
|
||||
public int dronesCreated = 4;
|
||||
|
||||
//TODO should be different for every tier.
|
||||
public Seq<BlockStack> requirements = new Seq<>();
|
||||
public UnitType output = UnitTypes.vanquish;
|
||||
public UnitType output;
|
||||
|
||||
public UnitAssembler(String name){
|
||||
super(name);
|
||||
@@ -48,21 +55,62 @@ public class UnitAssembler extends PayloadBlock{
|
||||
Tmp.r1.x += Geometry.d4x(rotation) * len;
|
||||
Tmp.r1.y += Geometry.d4y(rotation) * len;
|
||||
|
||||
//TODO better visuals here?
|
||||
//TODO better visuals here? dashLine looks bad
|
||||
Drawf.dashRect(valid ? Pal.accent : Pal.remove, Tmp.r1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBars(){
|
||||
super.setBars();
|
||||
|
||||
//TODO progress bar
|
||||
//bars.add("progress", (UnitAssemblerBuild e) -> new Bar("bar.progress", Pal.ammo, e::fraction));
|
||||
|
||||
bars.add("units", (UnitAssemblerBuild e) ->
|
||||
new Bar(() ->
|
||||
Core.bundle.format("bar.unitcap",
|
||||
Fonts.getUnicodeStr(output.name),
|
||||
e.team.data().countType(output),
|
||||
Units.getStringCap(e.team)
|
||||
),
|
||||
() -> Pal.power,
|
||||
() -> (float)e.team.data().countType(output) / Units.getCap(e.team)
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
|
||||
Draw.rect(region, plan.drawx(), plan.drawy());
|
||||
//Draw.rect(outRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
|
||||
Draw.rect(topRegion, plan.drawx(), plan.drawy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
consumes.add(new ConsumePayloads(requirements, (UnitAssemblerBuild build) -> build.blocks));
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
public class UnitAssemblerBuild extends PayloadBlockBuild<BuildPayload>{
|
||||
public Seq<Unit> units = new Seq<>();
|
||||
public BlockSeq blocks = new BlockSeq();
|
||||
|
||||
//TODO how should payloads be stored? counts of blocks? intmap? references?
|
||||
//public Seq<BuildPayload> payloads = new Seq<>();
|
||||
//TODO progress
|
||||
//TODO how should payloads be stored exactly? counts of blocks? intmap? references?
|
||||
|
||||
public Vec2 getUnitSpawn(){
|
||||
float len = tilesize * (areaSize + size)/2f;
|
||||
float unitX = x + Geometry.d4x(rotation) * len, unitY = y + Geometry.d4y(rotation) * len;
|
||||
return Tmp.v4.set(unitX, unitY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
units.removeAll(u -> !u.isAdded() || u.dead);
|
||||
|
||||
if(consValid() && units.size < dronesCreated){
|
||||
//units annoying, disabled for now
|
||||
if(false && efficiency() > 0 && units.size < dronesCreated){
|
||||
//TODO build animation? distribute spawning?
|
||||
var unit = droneType.create(team);
|
||||
if(unit instanceof BuildingTetherc bt){
|
||||
@@ -76,29 +124,88 @@ public class UnitAssembler extends PayloadBlock{
|
||||
units.add(unit);
|
||||
}
|
||||
|
||||
//TODO units should move stuff into position
|
||||
|
||||
//TODO check if area is occupied
|
||||
|
||||
Vec2 spawn = getUnitSpawn();
|
||||
|
||||
//check if all requirements are met
|
||||
if(consValid() & Units.canCreate(team, output)){
|
||||
|
||||
//TODO ???? should this even be part of a trigger
|
||||
consume();
|
||||
|
||||
//TODO actually just goes poof
|
||||
var unit = output.create(team);
|
||||
unit.set(spawn.x + Mathf.range(0.001f), spawn.y + Mathf.range(0.001f));
|
||||
unit.rotation = 90f;
|
||||
unit.add();
|
||||
|
||||
Fx.spawn.at(unit);
|
||||
|
||||
blocks.clear();
|
||||
}
|
||||
|
||||
//TODO drones need to indicate that they are in position and actually play an animation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(region, x, y);
|
||||
//Draw.rect(outRegion, x, y, rotdeg());
|
||||
|
||||
Draw.z(Layer.blockOver);
|
||||
|
||||
//payRotation = rotdeg();
|
||||
//drawPayload();
|
||||
|
||||
Draw.z(Layer.blockOver + 0.1f);
|
||||
|
||||
Draw.rect(topRegion, x, y);
|
||||
|
||||
Vec2 spawn = getUnitSpawn();
|
||||
|
||||
//TODO which layer?
|
||||
Draw.z(Layer.power - 1f);
|
||||
|
||||
Draw.mixcol(Pal.accent, 1f);
|
||||
Draw.alpha(0.4f + Mathf.absin(10f, 0.2f));
|
||||
Draw.rect(output.fullIcon, spawn.x, spawn.y);
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePayload(Building source, Payload payload){
|
||||
//super.handlePayload(source, payload);
|
||||
|
||||
blocks.add(((BuildPayload)payload).block());
|
||||
|
||||
//payloads.add((BuildPayload)payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptPayload(Building source, Payload payload){
|
||||
return payload instanceof BuildPayload bp && requirements.contains(b -> b.block == bp.block());
|
||||
return payload instanceof BuildPayload bp && requirements.contains(b -> b.block == bp.block() && blocks.get(bp.block()) < b.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Writes write){
|
||||
super.write(write);
|
||||
|
||||
//blocks.write(write);
|
||||
|
||||
//TODO save:
|
||||
//- unit IDs
|
||||
//- progress
|
||||
//- payloads in position (should they have positions?)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Reads read, byte revision){
|
||||
super.read(read, revision);
|
||||
|
||||
//blocks.read(read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ConsumeItems extends Consume{
|
||||
int i = 0;
|
||||
for(var stack : items){
|
||||
c.add(new ReqImage(new ItemImage(stack.item.uiIcon, stack.amount),
|
||||
() -> build.items != null && build.items.has(stack.item, stack.amount))).padRight(8);
|
||||
() -> build.items.has(stack.item, stack.amount))).padRight(8);
|
||||
if(++i % 4 == 0) c.row();
|
||||
}
|
||||
}).left();
|
||||
|
||||
62
core/src/mindustry/world/consumers/ConsumePayloads.java
Normal file
62
core/src/mindustry/world/consumers/ConsumePayloads.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package mindustry.world.consumers;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
public class ConsumePayloads extends Consume{
|
||||
//TODO bad, should be part of Building + dynamic
|
||||
protected Func<Building, BlockSeq> inventory;
|
||||
|
||||
public Seq<BlockStack> payloads;
|
||||
|
||||
public <T extends Building> ConsumePayloads(Seq<BlockStack> payloads, Func<T, BlockSeq> inventory){
|
||||
this.payloads = payloads;
|
||||
this.inventory = (Func<Building, BlockSeq>)inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean valid(Building build){
|
||||
return inventory.get(build).contains(payloads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Building build){
|
||||
inventory.get(build).remove(payloads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Stats stats){
|
||||
//TODO
|
||||
|
||||
for(var stack : payloads){
|
||||
stats.add(Stat.input, t -> {
|
||||
t.add(new ItemImage(stack));
|
||||
t.add(stack.block.localizedName).padLeft(4).padRight(4);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(Building build, Table table){
|
||||
var inv = inventory.get(build);
|
||||
|
||||
table.table(c -> {
|
||||
int i = 0;
|
||||
for(var stack : payloads){
|
||||
c.add(new ReqImage(new ItemImage(stack.block.uiIcon, stack.amount),
|
||||
() -> inv.contains(stack.block, stack.amount))).padRight(8);
|
||||
if(++i % 4 == 0) c.row();
|
||||
}
|
||||
}).left();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsumeType type(){
|
||||
return ConsumeType.payload;
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,6 @@ package mindustry.world.consumers;
|
||||
public enum ConsumeType{
|
||||
item,
|
||||
power,
|
||||
liquid
|
||||
liquid,
|
||||
payload
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user