WIP payload deconstructor
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/assets-raw/sprites/blocks/payload/payload-deconstructor.png
Normal file
BIN
core/assets-raw/sprites/blocks/payload/payload-deconstructor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -392,3 +392,4 @@
|
|||||||
63341=beryllic-boulder|block-beryllic-boulder-ui
|
63341=beryllic-boulder|block-beryllic-boulder-ui
|
||||||
63340=carbon-boulder|block-carbon-boulder-ui
|
63340=carbon-boulder|block-carbon-boulder-ui
|
||||||
63339=carbon-stone|block-carbon-stone-ui
|
63339=carbon-stone|block-carbon-stone-ui
|
||||||
|
63338=payload-deconstructor|block-payload-deconstructor-ui
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class Blocks implements ContentList{
|
|||||||
repairPoint, repairTurret, resupplyPoint,
|
repairPoint, repairTurret, resupplyPoint,
|
||||||
|
|
||||||
//payloads
|
//payloads
|
||||||
payloadConveyor, payloadRouter, payloadPropulsionTower,
|
payloadConveyor, payloadRouter, payloadPropulsionTower, payloadDeconstructor, blockForge, blockLoader, blockUnloader,
|
||||||
|
|
||||||
//logic
|
//logic
|
||||||
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank,
|
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank,
|
||||||
@@ -105,10 +105,7 @@ public class Blocks implements ContentList{
|
|||||||
launchPad, payloadLaunchPad, interplanetaryAccelerator,
|
launchPad, payloadLaunchPad, interplanetaryAccelerator,
|
||||||
|
|
||||||
//nuclear?
|
//nuclear?
|
||||||
nuclearWarhead, warheadAssembler, ballisticSilo, //TODO
|
nuclearWarhead, warheadAssembler, ballisticSilo //TODO
|
||||||
|
|
||||||
//misc experimental
|
|
||||||
blockForge, blockLoader, blockUnloader
|
|
||||||
;
|
;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2206,6 +2203,35 @@ public class Blocks implements ContentList{
|
|||||||
consumes.power(6f);
|
consumes.power(6f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
payloadDeconstructor = new PayloadDeconstructor("payload-deconstructor"){{
|
||||||
|
requirements(Category.units, with(Items.graphite, 30, Items.silicon, 30, Items.copper, 30));
|
||||||
|
itemCapacity = 200;
|
||||||
|
consumes.power(1f);
|
||||||
|
size = 5;
|
||||||
|
deconstructSpeed = 2f;
|
||||||
|
}};
|
||||||
|
|
||||||
|
blockForge = new BlockForge("block-forge"){{
|
||||||
|
requirements(Category.units, BuildVisibility.debugOnly, with(Items.thorium, 100));
|
||||||
|
hasPower = true;
|
||||||
|
consumes.power(2f);
|
||||||
|
size = 3;
|
||||||
|
}};
|
||||||
|
|
||||||
|
blockLoader = new BlockLoader("block-loader"){{
|
||||||
|
requirements(Category.units, BuildVisibility.debugOnly, with(Items.thorium, 100));
|
||||||
|
hasPower = true;
|
||||||
|
consumes.power(2f);
|
||||||
|
size = 3;
|
||||||
|
}};
|
||||||
|
|
||||||
|
blockUnloader = new BlockUnloader("block-unloader"){{
|
||||||
|
requirements(Category.units, BuildVisibility.debugOnly, with(Items.thorium, 100));
|
||||||
|
hasPower = true;
|
||||||
|
consumes.power(2f);
|
||||||
|
size = 3;
|
||||||
|
}};
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region sandbox
|
//region sandbox
|
||||||
|
|
||||||
@@ -2390,30 +2416,6 @@ public class Blocks implements ContentList{
|
|||||||
size = 6;
|
size = 6;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//endregion
|
|
||||||
//region experimental
|
|
||||||
|
|
||||||
blockForge = new BlockForge("block-forge"){{
|
|
||||||
requirements(Category.units, BuildVisibility.debugOnly, with(Items.thorium, 100));
|
|
||||||
hasPower = true;
|
|
||||||
consumes.power(2f);
|
|
||||||
size = 3;
|
|
||||||
}};
|
|
||||||
|
|
||||||
blockLoader = new BlockLoader("block-loader"){{
|
|
||||||
requirements(Category.units, BuildVisibility.debugOnly, with(Items.thorium, 100));
|
|
||||||
hasPower = true;
|
|
||||||
consumes.power(2f);
|
|
||||||
size = 3;
|
|
||||||
}};
|
|
||||||
|
|
||||||
blockUnloader = new BlockUnloader("block-unloader"){{
|
|
||||||
requirements(Category.units, BuildVisibility.debugOnly, with(Items.thorium, 100));
|
|
||||||
hasPower = true;
|
|
||||||
consumes.power(2f);
|
|
||||||
size = 3;
|
|
||||||
}};
|
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,21 @@ public class ItemSeq implements Iterable<ItemStack>, JsonSerializable{
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemStack[] toArray(){
|
||||||
|
int count = 0;
|
||||||
|
for(int value : values){
|
||||||
|
if(value != 0) count++;
|
||||||
|
}
|
||||||
|
ItemStack[] result = new ItemStack[count];
|
||||||
|
int index = 0;
|
||||||
|
for(int i = 0; i < values.length; i++){
|
||||||
|
if(values[i] != 0){
|
||||||
|
result[index ++] = new ItemStack(Vars.content.item(i), values[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void min(int number){
|
public void min(int number){
|
||||||
for(Item item : Vars.content.items()){
|
for(Item item : Vars.content.items()){
|
||||||
set(item, Math.min(get(item), number));
|
set(item, Math.min(get(item), number));
|
||||||
@@ -90,6 +105,12 @@ public class ItemSeq implements Iterable<ItemStack>, JsonSerializable{
|
|||||||
itemModule.each(this::add);
|
itemModule.each(this::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void add(ItemStack[] stacks){
|
||||||
|
for(var s : stacks){
|
||||||
|
add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void add(ItemSeq seq){
|
public void add(ItemSeq seq){
|
||||||
seq.each(this::add);
|
seq.each(this::add);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,9 @@ public class UnitType extends UnlockableContent{
|
|||||||
softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion;
|
softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion;
|
||||||
public TextureRegion[] wreckRegions;
|
public TextureRegion[] wreckRegions;
|
||||||
|
|
||||||
|
protected float maxBuildTime = -1f;
|
||||||
protected @Nullable ItemStack[] cachedRequirements;
|
protected @Nullable ItemStack[] cachedRequirements;
|
||||||
|
protected @Nullable ItemStack[] totalRequirements;
|
||||||
|
|
||||||
public UnitType(String name){
|
public UnitType(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -460,25 +462,70 @@ public class UnitType extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the time required to build this unit, as a maximum value that takes into account reconstructors */
|
||||||
|
public float getBuildTime(){
|
||||||
|
getTotalRequirements();
|
||||||
|
return maxBuildTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return all items needed to build this unit, including reconstructor steps. */
|
||||||
|
public ItemStack[] getTotalRequirements(){
|
||||||
|
if(totalRequirements == null){
|
||||||
|
UnitType[] ret = {null};
|
||||||
|
float[] timeret = {0f};
|
||||||
|
ItemStack[] result = getRequirements(ret, timeret);
|
||||||
|
|
||||||
|
//prevents stack overflow if requirements are circular and result != null
|
||||||
|
totalRequirements = ItemStack.empty;
|
||||||
|
|
||||||
|
if(result != null){
|
||||||
|
maxBuildTime = timeret[0];
|
||||||
|
ItemSeq total = new ItemSeq();
|
||||||
|
|
||||||
|
total.add(result);
|
||||||
|
if(ret[0] != null){
|
||||||
|
total.add(ret[0].getTotalRequirements());
|
||||||
|
maxBuildTime = Math.max(ret[0].maxBuildTime, maxBuildTime);
|
||||||
|
}
|
||||||
|
totalRequirements = total.toArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalRequirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return item requirements based on reconstructors or factories found; returns previous unit in array if provided */
|
||||||
|
public @Nullable ItemStack[] getRequirements(@Nullable UnitType[] prevReturn, @Nullable float[] timeReturn){
|
||||||
|
var rec = (Reconstructor)content.blocks().find(b -> b instanceof Reconstructor re && re.upgrades.contains(u -> u[1] == this));
|
||||||
|
|
||||||
|
if(rec != null && rec.consumes.has(ConsumeType.item) && rec.consumes.get(ConsumeType.item) instanceof ConsumeItems ci){
|
||||||
|
if(prevReturn != null){
|
||||||
|
prevReturn[0] = rec.upgrades.find(u -> u[1] == this)[0];
|
||||||
|
}
|
||||||
|
if(timeReturn != null){
|
||||||
|
timeReturn[0] = rec.constructTime;
|
||||||
|
}
|
||||||
|
return ci.items;
|
||||||
|
}else{
|
||||||
|
var factory = (UnitFactory)content.blocks().find(u -> u instanceof UnitFactory uf && uf.plans.contains(p -> p.unit == this));
|
||||||
|
if(factory != null){
|
||||||
|
|
||||||
|
var plan = factory.plans.find(p -> p.unit == this);
|
||||||
|
if(timeReturn != null){
|
||||||
|
timeReturn[0] = plan.time;
|
||||||
|
}
|
||||||
|
return plan.requirements;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack[] researchRequirements(){
|
public ItemStack[] researchRequirements(){
|
||||||
if(cachedRequirements != null){
|
if(cachedRequirements != null){
|
||||||
return cachedRequirements;
|
return cachedRequirements;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack[] stacks = null;
|
ItemStack[] stacks = getRequirements(null, null);
|
||||||
|
|
||||||
//calculate costs based on reconstructors or factories found
|
|
||||||
Block rec = content.blocks().find(b -> b instanceof Reconstructor re && re.upgrades.contains(u -> u[1] == this));
|
|
||||||
|
|
||||||
if(rec != null && rec.consumes.has(ConsumeType.item) && rec.consumes.get(ConsumeType.item) instanceof ConsumeItems ci){
|
|
||||||
stacks = ci.items;
|
|
||||||
}else{
|
|
||||||
UnitFactory factory = (UnitFactory)content.blocks().find(u -> u instanceof UnitFactory uf && uf.plans.contains(p -> p.unit == this));
|
|
||||||
if(factory != null){
|
|
||||||
stacks = factory.plans.find(p -> p.unit == this).requirements;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stacks != null){
|
if(stacks != null){
|
||||||
ItemStack[] out = new ItemStack[stacks.length];
|
ItemStack[] out = new ItemStack[stacks.length];
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import arc.util.io.*;
|
|||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -33,6 +34,16 @@ public class BuildPayload implements Payload{
|
|||||||
build.dropped();
|
build.dropped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack[] requirements(){
|
||||||
|
return build.block.requirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float buildTime(){
|
||||||
|
return build.block.buildCost;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float x(){
|
public float x(){
|
||||||
return build.x;
|
return build.x;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.util.*;
|
|||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -25,6 +26,12 @@ public interface Payload extends Position{
|
|||||||
float x();
|
float x();
|
||||||
float y();
|
float y();
|
||||||
|
|
||||||
|
/** @return the items needed to make this payload; may be empty. */
|
||||||
|
ItemStack[] requirements();
|
||||||
|
|
||||||
|
/** @return the time taken to build this payload. */
|
||||||
|
float buildTime();
|
||||||
|
|
||||||
/** @return whether this payload was dumped. */
|
/** @return whether this payload was dumped. */
|
||||||
default boolean dump(){
|
default boolean dump(){
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
package mindustry.world.blocks.payloads;
|
||||||
|
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import arc.util.io.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
|
public class PayloadDeconstructor extends PayloadBlock{
|
||||||
|
public float deconstructSpeed = 2f;
|
||||||
|
|
||||||
|
public PayloadDeconstructor(String name){
|
||||||
|
super(name);
|
||||||
|
|
||||||
|
outputsPayload = false;
|
||||||
|
acceptsPayload = true;
|
||||||
|
update = true;
|
||||||
|
rotate = false;
|
||||||
|
size = 5;
|
||||||
|
payloadSpeed = 1f;
|
||||||
|
//make sure to display large units.
|
||||||
|
clipSize = 120;
|
||||||
|
hasItems = true;
|
||||||
|
hasPower = true;
|
||||||
|
itemCapacity = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextureRegion[] icons(){
|
||||||
|
return new TextureRegion[]{region, topRegion};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PayloadDeconstructorBuild extends PayloadBlockBuild<Payload>{
|
||||||
|
public @Nullable Payload deconstructing;
|
||||||
|
public @Nullable float[] accum;
|
||||||
|
public float progress;
|
||||||
|
public float time, speedScl;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(){
|
||||||
|
Draw.rect(region, x, y);
|
||||||
|
|
||||||
|
//draw input
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
if(blends(i)){
|
||||||
|
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.z(Layer.blockOver);
|
||||||
|
drawPayload();
|
||||||
|
if(deconstructing != null){
|
||||||
|
deconstructing.set(x + payVector.x, y + payVector.y, payRotation);
|
||||||
|
|
||||||
|
Draw.z(Layer.blockOver);
|
||||||
|
//deconstructing.draw();
|
||||||
|
|
||||||
|
//TODO shadow
|
||||||
|
Draw.draw(Layer.blockOver, () -> {
|
||||||
|
Drawf.construct(x, y, deconstructing.icon(), Pal.remove, 0f, 1f - progress, speedScl, time);
|
||||||
|
Draw.color(Pal.remove);
|
||||||
|
Draw.alpha(speedScl);
|
||||||
|
|
||||||
|
Lines.lineAngleCenter(x + Mathf.sin(time, 20f, Vars.tilesize / 2f * block.size - 2f), y, 90, block.size * Vars.tilesize - 4f);
|
||||||
|
|
||||||
|
Draw.reset();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.rect(topRegion, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePayload(Building source, Payload payload){
|
||||||
|
super.handlePayload(source, payload);
|
||||||
|
accum = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptPayload(Building source, Payload payload){
|
||||||
|
return deconstructing == null && super.acceptPayload(source, payload) && payload.requirements().length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTile(){
|
||||||
|
//always dump items
|
||||||
|
dumpAccumulate();
|
||||||
|
|
||||||
|
if(deconstructing != null){
|
||||||
|
var reqs = deconstructing.requirements();
|
||||||
|
if(accum == null || reqs.length != accum.length){
|
||||||
|
accum = new float[reqs.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if there is enough space to get the items for deconstruction
|
||||||
|
boolean canProgress = items.total() <= itemCapacity;
|
||||||
|
if(canProgress){
|
||||||
|
for(var ac : accum){
|
||||||
|
if(ac >= 1f){
|
||||||
|
canProgress = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//move progress forward if possible
|
||||||
|
if(canProgress){
|
||||||
|
float shift = edelta() * deconstructSpeed / deconstructing.buildTime();
|
||||||
|
float realShift = Math.min(shift, 1f - progress);
|
||||||
|
|
||||||
|
progress += shift;
|
||||||
|
time += edelta();
|
||||||
|
|
||||||
|
for(int i = 0; i < reqs.length; i++){
|
||||||
|
accum[i] += reqs[i].amount * realShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
speedScl = Mathf.lerpDelta(speedScl, canProgress ? 1f : 0f, 0.1f);
|
||||||
|
|
||||||
|
//transfer items from accumulation buffer into block inventory when they reach integers
|
||||||
|
for(int i = 0; i < reqs.length; i++){
|
||||||
|
int taken = Math.min((int)accum[i], itemCapacity - items.total());
|
||||||
|
if(taken > 0){
|
||||||
|
items.add(reqs[i].item, taken);
|
||||||
|
accum[i] -= taken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//finish deconstruction, prepare for next payload.
|
||||||
|
if(progress >= 1f){
|
||||||
|
//TODO
|
||||||
|
deconstructing = null;
|
||||||
|
accum = null;
|
||||||
|
}
|
||||||
|
}else if(moveInPayload(false) && payload != null && cons.valid()){
|
||||||
|
accum = new float[payload.requirements().length];
|
||||||
|
deconstructing = payload;
|
||||||
|
payload = null;
|
||||||
|
progress = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(Writes write){
|
||||||
|
super.write(write);
|
||||||
|
|
||||||
|
write.f(progress);
|
||||||
|
if(accum != null){
|
||||||
|
write.s(accum.length);
|
||||||
|
for(float v : accum){
|
||||||
|
write.f(v);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
write.s(0);
|
||||||
|
}
|
||||||
|
Payload.write(deconstructing, write);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(Reads read, byte revision){
|
||||||
|
super.read(read, revision);
|
||||||
|
|
||||||
|
progress = read.f();
|
||||||
|
short accums = read.s();
|
||||||
|
if(accums > 0){
|
||||||
|
accum = new float[accums];
|
||||||
|
for(int i = 0; i < accums; i++){
|
||||||
|
accum[i] = read.f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deconstructing = Payload.read(read);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import mindustry.entities.EntityCollisions.*;
|
|||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class UnitPayload implements Payload{
|
public class UnitPayload implements Payload{
|
||||||
public static final float deactiveDuration = 40f;
|
public static final float deactiveDuration = 40f;
|
||||||
@@ -23,6 +24,16 @@ public class UnitPayload implements Payload{
|
|||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack[] requirements(){
|
||||||
|
return unit.type.getTotalRequirements();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float buildTime(){
|
||||||
|
return unit.type.getBuildTime();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(Writes write){
|
public void write(Writes write){
|
||||||
write.b(payloadUnit);
|
write.b(payloadUnit);
|
||||||
|
|||||||
Reference in New Issue
Block a user