Unit assembly system progress
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 304 B |
BIN
core/assets-raw/sprites/blocks/units/basic-assembler-module.png
Normal file
BIN
core/assets-raw/sprites/blocks/units/basic-assembler-module.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -488,3 +488,4 @@
|
|||||||
63218=tungsten-wall-large|block-tungsten-wall-large-ui
|
63218=tungsten-wall-large|block-tungsten-wall-large-ui
|
||||||
63217=tank-assembler|block-tank-assembler-ui
|
63217=tank-assembler|block-tank-assembler-ui
|
||||||
63216=assembly-drone|unit-assembly-drone-ui
|
63216=assembly-drone|unit-assembly-drone-ui
|
||||||
|
63215=basic-assembler-module|block-basic-assembler-module-ui
|
||||||
|
|||||||
Binary file not shown.
@@ -382,7 +382,6 @@ public class Vars implements Loadable{
|
|||||||
try{
|
try{
|
||||||
Writer writer = settings.getDataDirectory().child("last_log.txt").writer(false);
|
Writer writer = settings.getDataDirectory().child("last_log.txt").writer(false);
|
||||||
LogHandler log = Log.logger;
|
LogHandler log = Log.logger;
|
||||||
//ignore it
|
|
||||||
Log.logger = (level, text) -> {
|
Log.logger = (level, text) -> {
|
||||||
log.log(level, text);
|
log.log(level, text);
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ public class Blocks{
|
|||||||
|
|
||||||
//unit - erekir
|
//unit - erekir
|
||||||
tankAssembler,
|
tankAssembler,
|
||||||
|
basicAssemblerModule,
|
||||||
|
|
||||||
//payloads
|
//payloads
|
||||||
//TODO small deconstructor
|
//TODO small deconstructor
|
||||||
@@ -3319,15 +3320,20 @@ public class Blocks{
|
|||||||
tankAssembler = new UnitAssembler("tank-assembler"){{
|
tankAssembler = new UnitAssembler("tank-assembler"){{
|
||||||
requirements(Category.units, with(Items.graphite, 10));
|
requirements(Category.units, with(Items.graphite, 10));
|
||||||
size = 3;
|
size = 3;
|
||||||
output = UnitTypes.vanquish;
|
|
||||||
droneType = UnitTypes.manifold;
|
droneType = UnitTypes.manifold;
|
||||||
requirements = BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2);
|
plans.add(new AssemblerUnitPlan(UnitTypes.vanquish, 60f * 5f, BlockStack.list(Blocks.thoriumWallLarge, 4, Blocks.duct, 2)));
|
||||||
consumes.power(1f);
|
consumes.power(1f);
|
||||||
areaSize = 13;
|
areaSize = 13;
|
||||||
|
|
||||||
droneType = UnitTypes.assemblyDrone;
|
droneType = UnitTypes.assemblyDrone;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
basicAssemblerModule = new UnitAssemblerModule("basic-assembler-module"){{
|
||||||
|
requirements(Category.units, with(Items.graphite, 10));
|
||||||
|
|
||||||
|
size = 3;
|
||||||
|
}};
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region payloads
|
//region payloads
|
||||||
|
|
||||||
|
|||||||
@@ -2439,7 +2439,7 @@ public class UnitTypes{
|
|||||||
layerOffset = 0.0001f;
|
layerOffset = 0.0001f;
|
||||||
reload = 120f;
|
reload = 120f;
|
||||||
shootY = 71f / 4f;
|
shootY = 71f / 4f;
|
||||||
shake = 3f;
|
shake = 4f;
|
||||||
recoil = 4f;
|
recoil = 4f;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
rotateSpeed = 1f;
|
rotateSpeed = 1f;
|
||||||
|
|||||||
@@ -116,6 +116,10 @@ public class Drawf{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void dashLineBasic(float x, float y, float x2, float y2){
|
||||||
|
Lines.dashLine(x, y, x2, y2, (int)(Math.max(Math.abs(x - x2), Math.abs(y - y2)) / tilesize * 2));
|
||||||
|
}
|
||||||
|
|
||||||
public static void dashSquare(Color color, float x, float y, float size){
|
public static void dashSquare(Color color, float x, float y, float size){
|
||||||
dashRect(color, x - size/2f, y - size/2f, size, size);
|
dashRect(color, x - size/2f, y - size/2f, size, size);
|
||||||
}
|
}
|
||||||
@@ -131,6 +135,17 @@ public class Drawf{
|
|||||||
dashLine(color, x, y + height, x, y);
|
dashLine(color, x, y + height, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void dashSquareBasic(float x, float y, float size){
|
||||||
|
dashRectBasic(x - size/2f, y - size/2f, size, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dashRectBasic(float x, float y, float width, float height){
|
||||||
|
dashLineBasic(x, y, x + width, y);
|
||||||
|
dashLineBasic(x + width, y, x + width, y + height);
|
||||||
|
dashLineBasic(x + width, y + height, x, y + height);
|
||||||
|
dashLineBasic( x, y + height, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
public static void target(float x, float y, float rad, Color color){
|
public static void target(float x, float y, float rad, Color color){
|
||||||
target(x, y, rad, 1, color);
|
target(x, y, rad, 1, color);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package mindustry.ui;
|
package mindustry.ui;
|
||||||
|
|
||||||
|
/** @deprecated completely pointless */
|
||||||
|
@Deprecated
|
||||||
public enum IconSize{
|
public enum IconSize{
|
||||||
def(48),
|
def(48),
|
||||||
small(32),
|
small(32),
|
||||||
|
|||||||
@@ -90,6 +90,17 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int relativeTo(float x, float y, float cx, float cy){
|
||||||
|
if(Math.abs(x - cx) > Math.abs(y - cy)){
|
||||||
|
if(x <= cx - 1) return 0;
|
||||||
|
if(x >= cx + 1) return 2;
|
||||||
|
}else{
|
||||||
|
if(y <= cy - 1) return 1;
|
||||||
|
if(y >= cy + 1) return 3;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public byte absoluteRelativeTo(int cx, int cy){
|
public byte absoluteRelativeTo(int cx, int cy){
|
||||||
|
|
||||||
//very straightforward for odd sizes
|
//very straightforward for odd sizes
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package mindustry.world.blocks.units;
|
package mindustry.world.blocks.units;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
@@ -15,7 +17,9 @@ import mindustry.gen.*;
|
|||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.payloads.*;
|
import mindustry.world.blocks.payloads.*;
|
||||||
|
import mindustry.world.blocks.units.UnitAssemblerModule.*;
|
||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
@@ -33,10 +37,7 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
public UnitType droneType = UnitTypes.assemblyDrone;
|
public UnitType droneType = UnitTypes.assemblyDrone;
|
||||||
public int dronesCreated = 4;
|
public int dronesCreated = 4;
|
||||||
|
|
||||||
//TODO should be different for every tier.
|
public Seq<AssemblerUnitPlan> plans = new Seq<>(4);
|
||||||
public float buildTime = 60f * 5f;
|
|
||||||
public Seq<BlockStack> requirements = new Seq<>();
|
|
||||||
public UnitType output;
|
|
||||||
|
|
||||||
public UnitAssembler(String name){
|
public UnitAssembler(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -73,12 +74,12 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
bars.add("units", (UnitAssemblerBuild e) ->
|
bars.add("units", (UnitAssemblerBuild e) ->
|
||||||
new Bar(() ->
|
new Bar(() ->
|
||||||
Core.bundle.format("bar.unitcap",
|
Core.bundle.format("bar.unitcap",
|
||||||
Fonts.getUnicodeStr(output.name),
|
Fonts.getUnicodeStr(e.unit().name),
|
||||||
e.team.data().countType(output),
|
e.team.data().countType(e.unit()),
|
||||||
Units.getStringCap(e.team)
|
Units.getStringCap(e.team)
|
||||||
),
|
),
|
||||||
() -> Pal.power,
|
() -> Pal.power,
|
||||||
() -> (float)e.team.data().countType(output) / Units.getCap(e.team)
|
() -> (float)e.team.data().countType(e.unit()) / Units.getCap(e.team)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,30 +92,166 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
consumes.add(new ConsumePayloads(requirements));
|
consumes.add(new ConsumePayloadDynamic((UnitAssemblerBuild build) -> build.plan().requirements));
|
||||||
|
|
||||||
super.init();
|
super.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStats(){
|
||||||
|
super.setStats();
|
||||||
|
|
||||||
|
stats.add(Stat.output, table -> {
|
||||||
|
Seq<AssemblerUnitPlan> p = plans.select(u -> u.unit.unlockedNow());
|
||||||
|
table.row();
|
||||||
|
for(var plan : p){
|
||||||
|
if(plan.unit.unlockedNow()){
|
||||||
|
table.image(plan.unit.uiIcon).size(8 * 3).padRight(2).right();
|
||||||
|
table.add(plan.unit.localizedName).left();
|
||||||
|
table.add(Strings.autoFixed(plan.time / 60f, 1) + " " + Core.bundle.get("unit.seconds")).color(Color.lightGray).padLeft(12).left();
|
||||||
|
table.row();
|
||||||
|
table.add().right();
|
||||||
|
table.table(t -> {
|
||||||
|
t.left();
|
||||||
|
for(var stack : plan.requirements){
|
||||||
|
t.add(new ItemImage(stack)).padRight(4).padTop(4).left();
|
||||||
|
}
|
||||||
|
}).left().fillX().padLeft(-8 * 3f - 2).padBottom(6).row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AssemblerUnitPlan{
|
||||||
|
public UnitType unit;
|
||||||
|
public Seq<BlockStack> requirements;
|
||||||
|
public float time;
|
||||||
|
|
||||||
|
public AssemblerUnitPlan(UnitType unit, float time, Seq<BlockStack> requirements){
|
||||||
|
this.unit = unit;
|
||||||
|
this.time = time;
|
||||||
|
this.requirements = requirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssemblerUnitPlan(){}
|
||||||
|
}
|
||||||
|
|
||||||
public class UnitAssemblerBuild extends PayloadBlockBuild<BuildPayload>{
|
public class UnitAssemblerBuild extends PayloadBlockBuild<BuildPayload>{
|
||||||
protected IntSeq readUnits = new IntSeq();
|
protected IntSeq readUnits = new IntSeq();
|
||||||
|
|
||||||
public Seq<Unit> units = new Seq<>();
|
public Seq<Unit> units = new Seq<>();
|
||||||
|
public Seq<UnitAssemblerModuleBuild> modules = new Seq<>();
|
||||||
public BlockSeq blocks = new BlockSeq();
|
public BlockSeq blocks = new BlockSeq();
|
||||||
public float progress, warmup;
|
public float progress, warmup;
|
||||||
public float invalidWarmup = 0f;
|
public float invalidWarmup = 0f;
|
||||||
|
public int currentTier = 0;
|
||||||
|
|
||||||
public boolean wasOccupied = false;
|
public boolean wasOccupied = false;
|
||||||
|
|
||||||
//TODO progress
|
|
||||||
//TODO how should payloads be stored exactly? counts of blocks? intmap? references?
|
|
||||||
|
|
||||||
public Vec2 getUnitSpawn(){
|
public Vec2 getUnitSpawn(){
|
||||||
float len = tilesize * (areaSize + size)/2f;
|
float len = tilesize * (areaSize + size)/2f;
|
||||||
float unitX = x + Geometry.d4x(rotation) * len, unitY = y + Geometry.d4y(rotation) * len;
|
float unitX = x + Geometry.d4x(rotation) * len, unitY = y + Geometry.d4y(rotation) * len;
|
||||||
return Tmp.v4.set(unitX, unitY);
|
return Tmp.v4.set(unitX, unitY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean moduleFits(Block other, float ox, float oy, int rotation){
|
||||||
|
float
|
||||||
|
dx = ox + Geometry.d4x(rotation) * (other.size/2 + 1) * tilesize,
|
||||||
|
dy = oy + Geometry.d4y(rotation) * (other.size/2 + 1) * tilesize;
|
||||||
|
|
||||||
|
Vec2 spawn = getUnitSpawn();
|
||||||
|
|
||||||
|
if(Tile.relativeTo(ox, oy, spawn.x, spawn.y) != rotation){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dst = Math.max(Math.abs(dx - spawn.x), Math.abs(dy - spawn.y));
|
||||||
|
return Mathf.equal(dst, tilesize * areaSize / 2f - tilesize/2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateModules(UnitAssemblerModuleBuild build){
|
||||||
|
modules.addUnique(build);
|
||||||
|
checkTier();
|
||||||
|
//TODO tier check
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeModule(UnitAssemblerModuleBuild build){
|
||||||
|
modules.remove(build);
|
||||||
|
checkTier();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkTier(){
|
||||||
|
modules.sort(b -> b.tier());
|
||||||
|
int max = 0;
|
||||||
|
for(int i = 0; i < modules.size; i++){
|
||||||
|
var mod = modules.get(i);
|
||||||
|
if(mod.tier() == max || mod.tier() == max + 1){
|
||||||
|
max = mod.tier();
|
||||||
|
}else{
|
||||||
|
//tier gap, TODO warning?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentTier = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitType unit(){
|
||||||
|
return plan().unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssemblerUnitPlan plan(){
|
||||||
|
//clamp plan pos
|
||||||
|
return plans.get(Math.min(currentTier, plans.size - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawSelect(){
|
||||||
|
for(var module : modules){
|
||||||
|
Drawf.selected(module, Pal.accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO draw area
|
||||||
|
}
|
||||||
|
|
||||||
|
//is this necessary? wastes a lot of space
|
||||||
|
/*
|
||||||
|
@Override
|
||||||
|
public void displayConsumption(Table table){
|
||||||
|
super.displayConsumption(table);
|
||||||
|
table.row();
|
||||||
|
|
||||||
|
table.table(t -> {
|
||||||
|
t.left();
|
||||||
|
for(var mod : modules){
|
||||||
|
//TODO crosses for missing reqs?
|
||||||
|
t.image(mod.block.uiIcon).size(iconMed).padRight(4).padTop(4);
|
||||||
|
}
|
||||||
|
}).fillX().row();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void display(Table table){
|
||||||
|
super.display(table);
|
||||||
|
|
||||||
|
table.row();
|
||||||
|
table.table(t -> {
|
||||||
|
t.left().defaults().left();
|
||||||
|
|
||||||
|
Block prev = null;
|
||||||
|
for(int i = 0; i < modules.size; i++){
|
||||||
|
var mod = modules.get(i);
|
||||||
|
if(prev == mod.block) continue;
|
||||||
|
//TODO crosses for missing reqs?
|
||||||
|
t.image(mod.block.uiIcon).size(iconMed).padRight(4);
|
||||||
|
|
||||||
|
prev = mod.block;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.label(() -> "[accent] -> []" + unit().emoji() + " " + unit().name);
|
||||||
|
}).pad(4).padLeft(0f).fillX().left();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
if(!readUnits.isEmpty()){
|
if(!readUnits.isEmpty()){
|
||||||
@@ -146,8 +283,6 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
|
|
||||||
//TODO units should move stuff into position
|
//TODO units should move stuff into position
|
||||||
|
|
||||||
//TODO check if area is occupied
|
|
||||||
|
|
||||||
Vec2 spawn = getUnitSpawn();
|
Vec2 spawn = getUnitSpawn();
|
||||||
|
|
||||||
//arrange units around perimeter
|
//arrange units around perimeter
|
||||||
@@ -163,16 +298,18 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
|
|
||||||
invalidWarmup = Mathf.lerpDelta(invalidWarmup, wasOccupied ? 1f : 0f, 0.1f);
|
invalidWarmup = Mathf.lerpDelta(invalidWarmup, wasOccupied ? 1f : 0f, 0.1f);
|
||||||
|
|
||||||
|
var plan = plan();
|
||||||
|
|
||||||
//check if all requirements are met
|
//check if all requirements are met
|
||||||
if(!wasOccupied && consValid() && Units.canCreate(team, output)){
|
if(!wasOccupied && consValid() && Units.canCreate(team, plan.unit)){
|
||||||
warmup = Mathf.lerpDelta(warmup, efficiency(), 0.1f);
|
warmup = Mathf.lerpDelta(warmup, efficiency(), 0.1f);
|
||||||
|
|
||||||
if((progress += edelta() * eff / buildTime) >= 1f){
|
if((progress += edelta() * eff / plan.time) >= 1f){
|
||||||
//TODO ???? should this even be part of a trigger
|
//TODO ???? should this even be part of a trigger
|
||||||
consume();
|
consume();
|
||||||
|
|
||||||
//TODO actually just goes poof
|
//TODO actually just goes poof
|
||||||
var unit = output.create(team);
|
var unit = plan.unit.create(team);
|
||||||
unit.set(spawn.x + Mathf.range(0.001f), spawn.y + Mathf.range(0.001f));
|
unit.set(spawn.x + Mathf.range(0.001f), spawn.y + Mathf.range(0.001f));
|
||||||
unit.rotation = 90f;
|
unit.rotation = 90f;
|
||||||
unit.add();
|
unit.add();
|
||||||
@@ -194,6 +331,7 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
Draw.rect(region, x, y);
|
Draw.rect(region, x, y);
|
||||||
//Draw.rect(outRegion, x, y, rotdeg());
|
//Draw.rect(outRegion, x, y, rotdeg());
|
||||||
|
|
||||||
|
//draw input conveyors
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
if(blends(i) && i != rotation){
|
if(blends(i) && i != rotation){
|
||||||
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
||||||
@@ -213,14 +351,17 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
|
|
||||||
Draw.alpha(progress);
|
Draw.alpha(progress);
|
||||||
|
|
||||||
Draw.rect(output.fullIcon, spawn.x, spawn.y);
|
var plan = plan();
|
||||||
|
|
||||||
|
Draw.rect(plan.unit.fullIcon, spawn.x, spawn.y);
|
||||||
|
|
||||||
//TODO which layer?
|
//TODO which layer?
|
||||||
Draw.z(Layer.buildBeam);
|
Draw.z(Layer.buildBeam);
|
||||||
|
|
||||||
|
//draw unit outline
|
||||||
Draw.mixcol(Tmp.c1.set(Pal.accent).lerp(Pal.remove, invalidWarmup), 1f);
|
Draw.mixcol(Tmp.c1.set(Pal.accent).lerp(Pal.remove, invalidWarmup), 1f);
|
||||||
Draw.alpha(0.8f + Mathf.absin(10f, 0.2f));
|
Draw.alpha(0.8f + Mathf.absin(10f, 0.2f));
|
||||||
Draw.rect(output.fullIcon, spawn.x, spawn.y);
|
Draw.rect(plan.unit.fullIcon, spawn.x, spawn.y);
|
||||||
|
|
||||||
Draw.alpha(warmup * Draw.getColor().a);
|
Draw.alpha(warmup * Draw.getColor().a);
|
||||||
int c = 0;
|
int c = 0;
|
||||||
@@ -231,23 +372,32 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
px = unit.x + Angles.trnsx(unit.rotation, unit.type.buildBeamOffset),
|
px = unit.x + Angles.trnsx(unit.rotation, unit.type.buildBeamOffset),
|
||||||
py = unit.y + Angles.trnsy(unit.rotation, unit.type.buildBeamOffset);
|
py = unit.y + Angles.trnsy(unit.rotation, unit.type.buildBeamOffset);
|
||||||
|
|
||||||
Drawf.buildBeam(px, py, spawn.x, spawn.y, output.hitSize/2f);
|
Drawf.buildBeam(px, py, spawn.x, spawn.y, plan.unit.hitSize/2f);
|
||||||
c ++;
|
c ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.z(Layer.overlayUI - 1);
|
Draw.reset();
|
||||||
|
|
||||||
var color = Tmp.c3.set(Pal.accent).lerp(Pal.remove, invalidWarmup).a(efficiency());
|
Draw.z(Layer.buildBeam);
|
||||||
|
|
||||||
//TODO dashes bad
|
float fulls = areaSize * tilesize/2f;
|
||||||
|
|
||||||
float outSize = output.hitSize + 9f;
|
//draw full area
|
||||||
float hs = size * tilesize/2f, ha = outSize/2f;
|
Lines.stroke(2f, Pal.accent);
|
||||||
|
Drawf.dashRectBasic(spawn.x - fulls, spawn.y - fulls, fulls*2f, fulls*2f);
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
//TODO dash rect for output, fades in/out
|
|
||||||
Drawf.dashSquare(color, spawn.x, spawn.y, outSize);
|
|
||||||
|
|
||||||
|
float outSize = plan.unit.hitSize + 9f;
|
||||||
|
float hs = size * tilesize/2f, ha = outSize/2f;
|
||||||
|
|
||||||
|
Lines.stroke(2f, Tmp.c3.set(Pal.accent).lerp(Pal.remove, invalidWarmup).a(efficiency()));
|
||||||
|
|
||||||
|
//draw small square for area
|
||||||
|
//TODO dash rect for output, fades in/out
|
||||||
|
Drawf.dashSquareBasic(spawn.x, spawn.y, outSize);
|
||||||
|
|
||||||
|
/*
|
||||||
for(int i : Mathf.signs){
|
for(int i : Mathf.signs){
|
||||||
Tmp.v1.trns(rotation * 90, hs, hs * i).add(x, y);
|
Tmp.v1.trns(rotation * 90, hs, hs * i).add(x, y);
|
||||||
|
|
||||||
@@ -255,12 +405,20 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
Draw.color();
|
Draw.color();
|
||||||
|
|
||||||
Drawf.dashLine(color, Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y);
|
Drawf.dashLine(color, Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
Draw.reset();
|
||||||
|
|
||||||
|
Draw.z(Layer.overlayUI - 1);
|
||||||
|
|
||||||
|
//TODO dashes bad
|
||||||
|
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkSolid(Vec2 v){
|
public boolean checkSolid(Vec2 v){
|
||||||
|
var output = unit();
|
||||||
return !output.flying && (collisions.overlapsTile(Tmp.r1.setCentered(v.x, v.y, output.hitSize), EntityCollisions::solid) || Units.anyEntities(v.x, v.y, output.hitSize));
|
return !output.flying && (collisions.overlapsTile(Tmp.r1.setCentered(v.x, v.y, output.hitSize), EntityCollisions::solid) || Units.anyEntities(v.x, v.y, output.hitSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +438,8 @@ public class UnitAssembler extends PayloadBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptPayload(Building source, Payload payload){
|
public boolean acceptPayload(Building source, Payload payload){
|
||||||
return payload instanceof BuildPayload bp && requirements.contains(b -> b.block == bp.block() && blocks.get(bp.block()) < b.amount);
|
var plan = plan();
|
||||||
|
return payload instanceof BuildPayload bp && plan.requirements.contains(b -> b.block == bp.block() && blocks.get(bp.block()) < b.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,21 +1,118 @@
|
|||||||
package mindustry.world.blocks.units;
|
package mindustry.world.blocks.units;
|
||||||
|
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.payloads.*;
|
import mindustry.world.blocks.payloads.*;
|
||||||
import mindustry.world.blocks.units.UnitAssembler.*;
|
import mindustry.world.blocks.units.UnitAssembler.*;
|
||||||
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class UnitAssemblerModule extends PayloadBlock{
|
public class UnitAssemblerModule extends PayloadBlock{
|
||||||
|
public int tier = 1;
|
||||||
|
|
||||||
public UnitAssemblerModule(String name){
|
public UnitAssemblerModule(String name){
|
||||||
super(name);
|
super(name);
|
||||||
|
rotate = true;
|
||||||
|
rotateDraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
|
super.drawPlace(x, y, rotation, valid);
|
||||||
|
|
||||||
|
var link = getLink(player.team(), x, y, rotation);
|
||||||
|
if(link != null){
|
||||||
|
link.block.drawPlace(link.tile.x, link.tile.y, link.rotation, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlaceOn(Tile tile, Team team, int rotation){
|
||||||
|
return getLink(team, tile.x, tile.y, rotation) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable UnitAssemblerBuild getLink(Team team, int x, int y, int rotation){
|
||||||
|
var results = Vars.indexer.getFlagged(team, BlockFlag.unitAssembler).<UnitAssemblerBuild>as();
|
||||||
|
|
||||||
|
return results.find(b -> b.moduleFits(this, x * tilesize + offset, y * tilesize + offset, rotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO how does it link?
|
|
||||||
public class UnitAssemblerModuleBuild extends PayloadBlockBuild<BuildPayload>{
|
public class UnitAssemblerModuleBuild extends PayloadBlockBuild<BuildPayload>{
|
||||||
public UnitAssemblerBuild link;
|
public UnitAssemblerBuild link;
|
||||||
|
public int lastChange = -2;
|
||||||
|
|
||||||
|
public void findLink(){
|
||||||
|
if(link != null){
|
||||||
|
link.removeModule(this);
|
||||||
|
}
|
||||||
|
link = getLink(team, tile.x, tile.y, rotation);
|
||||||
|
if(link != null){
|
||||||
|
link.updateModules(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int tier(){
|
||||||
|
return tier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(){
|
||||||
|
Draw.rect(region, x, y);
|
||||||
|
|
||||||
|
//draw input conveyors
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
if(blends(i) && i != rotation){
|
||||||
|
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.z(Layer.blockOver);
|
||||||
|
payRotation = rotdeg();
|
||||||
|
drawPayload();
|
||||||
|
Draw.z(Layer.blockOver + 0.1f);
|
||||||
|
Draw.rect(topRegion, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptPayload(Building source, Payload payload){
|
||||||
|
return link != null && payload == null && link.acceptPayload(source, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawSelect(){
|
||||||
|
//TODO draw area
|
||||||
|
if(link != null){
|
||||||
|
Drawf.selected(link, Pal.accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemoved(){
|
||||||
|
super.onRemoved();
|
||||||
|
|
||||||
|
if(link != null){
|
||||||
|
link.removeModule(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
|
if(lastChange != world.tileChanges){
|
||||||
|
lastChange = world.tileChanges;
|
||||||
|
findLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(moveInPayload()){
|
||||||
|
if(link != null && link.moduleFits(block, x, y, rotation) && link.acceptPayload(this, payload)){
|
||||||
|
link.handlePayload(this, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import mindustry.ui.*;
|
|||||||
public class ConsumeItemDynamic extends Consume{
|
public class ConsumeItemDynamic extends Consume{
|
||||||
public final Func<Building, ItemStack[]> items;
|
public final Func<Building, ItemStack[]> items;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Building> ConsumeItemDynamic(Func<T, ItemStack[]> items){
|
public <T extends Building> ConsumeItemDynamic(Func<T, ItemStack[]> items){
|
||||||
this.items = (Func<Building, ItemStack[]>)items;
|
this.items = (Func<Building, ItemStack[]>)items;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
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 ConsumePayloadDynamic extends Consume{
|
||||||
|
public final Func<Building, Seq<BlockStack>> payloads;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends Building> ConsumePayloadDynamic(Func<T, Seq<BlockStack>> payloads){
|
||||||
|
this.payloads = (Func<Building, Seq<BlockStack>>)payloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean valid(Building build){
|
||||||
|
return build.getBlockPayloads().contains(payloads.get(build));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trigger(Building build){
|
||||||
|
build.getBlockPayloads().remove(payloads.get(build));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void display(Stats stats){
|
||||||
|
//needs to be implemented by the block itself, not enough info to display here
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Building build, Table table){
|
||||||
|
Seq[] current = {payloads.get(build)};
|
||||||
|
|
||||||
|
table.table(cont -> {
|
||||||
|
table.update(() -> {
|
||||||
|
if(current[0] != payloads.get(build)){
|
||||||
|
rebuild(build, cont);
|
||||||
|
current[0] = payloads.get(build);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rebuild(build, cont);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rebuild(Building build, Table table){
|
||||||
|
var inv = build.getBlockPayloads();
|
||||||
|
var pay = payloads.get(build);
|
||||||
|
|
||||||
|
table.table(c -> {
|
||||||
|
int i = 0;
|
||||||
|
for(var stack : pay){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,10 @@ public enum BlockFlag{
|
|||||||
//single-block identifiers
|
//single-block identifiers
|
||||||
launchPad,
|
launchPad,
|
||||||
unitCargoUnloadPoint,
|
unitCargoUnloadPoint,
|
||||||
unitAssembler;
|
unitAssembler,
|
||||||
|
|
||||||
|
/** @deprecated not used anywhere */
|
||||||
|
@Deprecated resupply;
|
||||||
|
|
||||||
public final static BlockFlag[] all = values();
|
public final static BlockFlag[] all = values();
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,4 @@ android.useAndroidX=true
|
|||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
org.gradle.internal.http.socketTimeout=100000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
org.gradle.internal.http.connectionTimeout=100000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
archash=487418bc46
|
archash=224e6c07e0
|
||||||
|
|||||||
Reference in New Issue
Block a user