WIP branch merging
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 895 B |
BIN
core/assets-raw/sprites/blocks/payload/constructor-top.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
core/assets-raw/sprites/blocks/payload/constructor.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
core/assets-raw/sprites/blocks/payload/deconstructor-top.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
core/assets-raw/sprites/blocks/payload/deconstructor.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
core/assets-raw/sprites/blocks/payload/factory-in-3.png
Normal file
After Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
core/assets-raw/sprites/blocks/payload/factory-out-3.png
Normal file
After Width: | Height: | Size: 609 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
core/assets-raw/sprites/blocks/payload/large-constructor-top.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
core/assets-raw/sprites/blocks/payload/large-constructor.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
core/assets-raw/sprites/blocks/payload/payload-loader-top.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
core/assets-raw/sprites/blocks/payload/payload-loader.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 7.8 KiB |
BIN
core/assets-raw/sprites/blocks/payload/payload-unloader-top.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
core/assets-raw/sprites/blocks/payload/payload-unloader.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 651 B |
@ -1341,10 +1341,16 @@ block.disassembler.name = Disassembler
|
||||
block.silicon-crucible.name = Silicon Crucible
|
||||
block.overdrive-dome.name = Overdrive Dome
|
||||
block.interplanetary-accelerator.name = Interplanetary Accelerator
|
||||
#experimental, may be removed
|
||||
block.block-forge.name = Block Forge
|
||||
block.block-loader.name = Block Loader
|
||||
block.block-unloader.name = Block Unloader
|
||||
block.constructor.name = Constructor
|
||||
block.constructor.description = Fabricates structures up to 2x2 tiles in size.
|
||||
block.large-constructor.name = Large Constructor
|
||||
block.large-constructor.description = Fabricates structures up to 4x4 tiles in size.
|
||||
block.deconstructor.name = Deconstructor
|
||||
block.deconstructor.description = Deconstructs structures and units. Returns 100% of build cost.
|
||||
block.payload-loader.name = Payload Loader
|
||||
block.payload-loader.description = Load liquids and items into blocks.
|
||||
block.payload-unloader.name = Payload Unloader
|
||||
block.payload-unloader.description = Unloads liquids and items from blocks.
|
||||
|
||||
block.switch.name = Switch
|
||||
block.micro-processor.name = Micro Processor
|
||||
|
@ -64,7 +64,7 @@ public class Blocks implements ContentList{
|
||||
duct, ductRouter, ductBridge,
|
||||
|
||||
//liquid
|
||||
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
|
||||
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidContainer, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
|
||||
|
||||
//power
|
||||
combustionGenerator, thermalGenerator, steamGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor,
|
||||
@ -86,18 +86,19 @@ public class Blocks implements ContentList{
|
||||
repairPoint, repairTurret,
|
||||
|
||||
//payloads
|
||||
payloadConveyor, payloadRouter, payloadPropulsionTower,
|
||||
payloadConveyor, payloadRouter, payloadPropulsionTower, deconstructor, constructor, largeConstructor, payloadLoader, payloadUnloader,
|
||||
|
||||
//logic
|
||||
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank,
|
||||
|
||||
//campaign
|
||||
launchPad, interplanetaryAccelerator,
|
||||
|
||||
//misc experimental
|
||||
blockForge, blockLoader, blockUnloader
|
||||
launchPad, interplanetaryAccelerator
|
||||
;
|
||||
|
||||
/** @deprecated use the blocks with proper names, */
|
||||
@Deprecated
|
||||
public static Block blockForge, blockLoader, blockUnloader;
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
//region environment
|
||||
@ -125,7 +126,7 @@ public class Blocks implements ContentList{
|
||||
isLiquid = true;
|
||||
status = StatusEffects.wet;
|
||||
statusDuration = 120f;
|
||||
drownTime = 140f;
|
||||
drownTime = 200f;
|
||||
cacheLayer = CacheLayer.water;
|
||||
albedo = 0.9f;
|
||||
}};
|
||||
@ -158,7 +159,7 @@ public class Blocks implements ContentList{
|
||||
variants = 0;
|
||||
status = StatusEffects.wet;
|
||||
statusDuration = 140f;
|
||||
drownTime = 120f;
|
||||
drownTime = 200f;
|
||||
liquidDrop = Liquids.water;
|
||||
isLiquid = true;
|
||||
cacheLayer = CacheLayer.water;
|
||||
@ -186,7 +187,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
tar = new Floor("tar"){{
|
||||
drownTime = 150f;
|
||||
drownTime = 230f;
|
||||
status = StatusEffects.tarred;
|
||||
statusDuration = 240f;
|
||||
speedMultiplier = 0.19f;
|
||||
@ -213,7 +214,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
slag = new Floor("molten-slag"){{
|
||||
drownTime = 150f;
|
||||
drownTime = 230f;
|
||||
status = StatusEffects.melting;
|
||||
statusDuration = 240f;
|
||||
speedMultiplier = 0.19f;
|
||||
@ -233,6 +234,12 @@ public class Blocks implements ContentList{
|
||||
placeableOn = false;
|
||||
solid = true;
|
||||
variants = 0;
|
||||
canShadow = false;
|
||||
}};
|
||||
|
||||
empty = new EmptyFloor("empty"){{
|
||||
placeableOn = false;
|
||||
solid = true;
|
||||
}};
|
||||
|
||||
stone = new Floor("stone");
|
||||
@ -337,34 +344,36 @@ public class Blocks implements ContentList{
|
||||
attributes.set(Attribute.oil, 1.6f);
|
||||
}};
|
||||
|
||||
moss = new Floor("moss"){{
|
||||
variants = 3;
|
||||
attributes.set(Attribute.spores, 0.15f);
|
||||
}};
|
||||
|
||||
sporeMoss = new Floor("spore-moss"){{
|
||||
variants = 3;
|
||||
attributes.set(Attribute.spores, 0.3f);
|
||||
}};
|
||||
|
||||
stoneWall = new StaticWall("stone-wall"){{
|
||||
variants = 2;
|
||||
}};
|
||||
|
||||
sporeWall = new StaticWall("spore-wall"){{
|
||||
variants = 2;
|
||||
taintedWater.asFloor().wall = deepTaintedWater.asFloor().wall = this;
|
||||
taintedWater.asFloor().wall = deepTaintedWater.asFloor().wall = sporeMoss.asFloor().wall = this;
|
||||
}};
|
||||
|
||||
dirtWall = new StaticWall("dirt-wall"){{
|
||||
variants = 2;
|
||||
}};
|
||||
dirtWall = new StaticWall("dirt-wall");
|
||||
|
||||
daciteWall = new StaticWall("dacite-wall"){{
|
||||
variants = 2;
|
||||
}};
|
||||
daciteWall = new StaticWall("dacite-wall");
|
||||
|
||||
iceWall = new StaticWall("ice-wall"){{
|
||||
variants = 2;
|
||||
iceSnow.asFloor().wall = this;
|
||||
albedo = 0.6f;
|
||||
}};
|
||||
|
||||
snowWall = new StaticWall("snow-wall"){{
|
||||
variants = 2;
|
||||
}};
|
||||
snowWall = new StaticWall("snow-wall");
|
||||
|
||||
duneWall = new StaticWall("dune-wall"){{
|
||||
variants = 2;
|
||||
basalt.asFloor().wall = darksandWater.asFloor().wall = darksandTaintedWater.asFloor().wall = this;
|
||||
}};
|
||||
|
||||
@ -377,21 +386,15 @@ public class Blocks implements ContentList{
|
||||
|
||||
shrubs = new StaticWall("shrubs");
|
||||
|
||||
shaleWall = new StaticWall("shale-wall"){{
|
||||
variants = 2;
|
||||
}};
|
||||
shaleWall = new StaticWall("shale-wall");
|
||||
|
||||
sporePine = new StaticTree("spore-pine"){{
|
||||
variants = 0;
|
||||
moss.asFloor().wall = this;
|
||||
}};
|
||||
|
||||
snowPine = new StaticTree("snow-pine"){{
|
||||
variants = 0;
|
||||
}};
|
||||
snowPine = new StaticTree("snow-pine");
|
||||
|
||||
pine = new StaticTree("pine"){{
|
||||
variants = 0;
|
||||
}};
|
||||
pine = new StaticTree("pine");
|
||||
|
||||
whiteTreeDead = new TreeBlock("white-tree-dead");
|
||||
|
||||
@ -404,7 +407,7 @@ public class Blocks implements ContentList{
|
||||
|
||||
boulder = new Prop("boulder"){{
|
||||
variants = 2;
|
||||
stone.asFloor().decoration = this;
|
||||
stone.asFloor().decoration = craters.asFloor().decoration = charr.asFloor().decoration = this;
|
||||
}};
|
||||
|
||||
snowBoulder = new Prop("snow-boulder"){{
|
||||
@ -414,18 +417,22 @@ public class Blocks implements ContentList{
|
||||
|
||||
shaleBoulder = new Prop("shale-boulder"){{
|
||||
variants = 2;
|
||||
shale.asFloor().decoration = this;
|
||||
}};
|
||||
|
||||
sandBoulder = new Prop("sand-boulder"){{
|
||||
variants = 2;
|
||||
sand.asFloor().decoration = this;
|
||||
}};
|
||||
|
||||
daciteBoulder = new Prop("dacite-boulder"){{
|
||||
variants = 2;
|
||||
dacite.asFloor().decoration = this;
|
||||
}};
|
||||
|
||||
basaltBoulder = new Prop("basalt-boulder"){{
|
||||
variants = 2;
|
||||
basalt.asFloor().decoration = hotrock.asFloor().decoration = darksand.asFloor().decoration = magmarock.asFloor().decoration = this;
|
||||
}};
|
||||
|
||||
moss = new Floor("moss"){{
|
||||
@ -1130,10 +1137,16 @@ public class Blocks implements ContentList{
|
||||
liquidCapacity = 20f;
|
||||
}};
|
||||
|
||||
liquidContainer = new LiquidRouter("liquid-container"){{
|
||||
requirements(Category.liquid, with(Items.titanium, 10, Items.metaglass, 15));
|
||||
liquidCapacity = 700f;
|
||||
size = 2;
|
||||
}};
|
||||
|
||||
liquidTank = new LiquidRouter("liquid-tank"){{
|
||||
requirements(Category.liquid, with(Items.titanium, 25, Items.metaglass, 25));
|
||||
requirements(Category.liquid, with(Items.titanium, 30, Items.metaglass, 40));
|
||||
size = 3;
|
||||
liquidCapacity = 1500f;
|
||||
liquidCapacity = 1800f;
|
||||
health = 500;
|
||||
}};
|
||||
|
||||
@ -1899,6 +1912,7 @@ public class Blocks implements ContentList{
|
||||
length = 200f;
|
||||
hitEffect = Fx.hitMeltdown;
|
||||
hitColor = Pal.meltdownHit;
|
||||
status = StatusEffects.melting;
|
||||
drawSize = 420f;
|
||||
|
||||
incendChance = 0.4f;
|
||||
@ -2082,6 +2096,49 @@ public class Blocks implements ContentList{
|
||||
consumes.power(6f);
|
||||
}};
|
||||
|
||||
deconstructor = new PayloadDeconstructor("deconstructor"){{
|
||||
requirements(Category.units, with(Items.thorium, 250, Items.silicon, 200, Items.graphite, 250));
|
||||
itemCapacity = 250;
|
||||
consumes.power(3f);
|
||||
size = 5;
|
||||
deconstructSpeed = 2f;
|
||||
}};
|
||||
|
||||
constructor = new Constructor("constructor"){{
|
||||
requirements(Category.units, with(Items.thorium, 100));
|
||||
hasPower = true;
|
||||
consumes.power(2f);
|
||||
size = 3;
|
||||
}};
|
||||
|
||||
largeConstructor = new Constructor("large-constructor"){{
|
||||
requirements(Category.units, with(Items.thorium, 100));
|
||||
hasPower = true;
|
||||
consumes.power(2f);
|
||||
maxBlockSize = 4;
|
||||
minBlockSize = 3;
|
||||
size = 5;
|
||||
}};
|
||||
|
||||
payloadLoader = new PayloadLoader("payload-loader"){{
|
||||
requirements(Category.units, with(Items.thorium, 100));
|
||||
hasPower = true;
|
||||
consumes.power(2f);
|
||||
size = 3;
|
||||
}};
|
||||
|
||||
payloadUnloader = new PayloadUnloader("payload-unloader"){{
|
||||
requirements(Category.units, with(Items.thorium, 100));
|
||||
hasPower = true;
|
||||
consumes.power(2f);
|
||||
size = 3;
|
||||
}};
|
||||
|
||||
//TODO deprecated
|
||||
blockForge = constructor;
|
||||
blockLoader = payloadLoader;
|
||||
blockUnloader = payloadUnloader;
|
||||
|
||||
//endregion
|
||||
//region sandbox
|
||||
|
||||
@ -2244,30 +2301,6 @@ public class Blocks implements ContentList{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import arc.math.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
@ -34,7 +35,14 @@ public abstract class BlockProducer extends PayloadBlock{
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{region, outRegion};
|
||||
return new TextureRegion[]{region, outRegion, topRegion};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||
Draw.rect(region, req.drawx(), req.drawy());
|
||||
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||
Draw.rect(topRegion, req.drawx(), req.drawy());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,12 +51,6 @@ public abstract class BlockProducer extends PayloadBlock{
|
||||
|
||||
bars.add("progress", (BlockProducerBuild entity) -> new Bar("bar.progress", Pal.ammo, () -> entity.recipe() == null ? 0f : (entity.progress / entity.recipe().buildCost)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
|
||||
Draw.rect(region, req.drawx(), req.drawy());
|
||||
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
|
||||
}
|
||||
|
||||
public abstract class BlockProducerBuild extends PayloadBlockBuild<BuildPayload>{
|
||||
public float progress, time, heat;
|
||||
@ -85,6 +87,7 @@ public abstract class BlockProducer extends PayloadBlock{
|
||||
if(progress >= recipe.buildCost){
|
||||
consume();
|
||||
payload = new BuildPayload(recipe, team);
|
||||
Fx.placeBlock.at(x, y, payload.size() / tilesize);
|
||||
payVector.setZero();
|
||||
progress %= 1f;
|
||||
}
|
||||
@ -109,6 +112,7 @@ public abstract class BlockProducer extends PayloadBlock{
|
||||
|
||||
for(TextureRegion region : recipe.getGeneratedIcons()){
|
||||
Shaders.blockbuild.region = region;
|
||||
Shaders.blockbuild.time = time;
|
||||
Shaders.blockbuild.progress = progress / recipe.buildCost;
|
||||
|
||||
Draw.rect(region, x, y, recipe.rotate ? rotdeg() : 0);
|
||||
@ -126,6 +130,9 @@ public abstract class BlockProducer extends PayloadBlock{
|
||||
}
|
||||
|
||||
drawPayload();
|
||||
|
||||
Draw.z(Layer.blockBuilding + 1.1f);
|
||||
Draw.rect(topRegion, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,67 +0,0 @@
|
||||
package mindustry.world.blocks.payloads;
|
||||
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class BlockUnloader extends BlockLoader{
|
||||
|
||||
public BlockUnloader(String name){
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outputsItems(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rotatedOutput(int x, int y){
|
||||
return false;
|
||||
}
|
||||
|
||||
public class BlockUnloaderBuild extends BlockLoaderBuild{
|
||||
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
if(shouldExport()){
|
||||
moveOutPayload();
|
||||
}else if(moveInPayload()){
|
||||
|
||||
//load up items
|
||||
if(payload.block().hasItems && !full()){
|
||||
if(efficiency() > 0.01f && timer(timerLoad, loadTime / efficiency())){
|
||||
//load up items a set amount of times
|
||||
for(int j = 0; j < itemsLoaded && !full(); j++){
|
||||
for(int i = 0; i < items.length(); i++){
|
||||
if(payload.build.items.get(i) > 0){
|
||||
Item item = content.item(i);
|
||||
payload.build.items.remove(item, 1);
|
||||
items.add(item, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dump();
|
||||
}
|
||||
|
||||
public boolean full(){
|
||||
return items.total() >= itemCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldExport(){
|
||||
return payload != null && (payload.block().hasItems && payload.build.items.empty());
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import arc.util.io.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
@ -33,6 +34,16 @@ public class BuildPayload implements Payload{
|
||||
build.dropped();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] requirements(){
|
||||
return build.block.requirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float buildTime(){
|
||||
return build.block.buildCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float x(){
|
||||
return build.x;
|
||||
@ -61,9 +72,14 @@ public class BuildPayload implements Payload{
|
||||
build.set(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadow(float alpha){
|
||||
Drawf.shadow(build.x, build.y, build.block.size * tilesize * 2f, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Drawf.shadow(build.x, build.y, build.block.size * tilesize * 2f);
|
||||
drawShadow(1f);
|
||||
Draw.rect(build.block.fullIcon, build.x, build.y);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.meta.*;
|
||||
@ -14,17 +13,17 @@ import mindustry.world.meta.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
/** Configurable BlockProducer variant. */
|
||||
public class BlockForge extends BlockProducer{
|
||||
public class Constructor extends BlockProducer{
|
||||
public float buildSpeed = 0.4f;
|
||||
public int minBlockSize = 1, maxBlockSize = 2;
|
||||
|
||||
public BlockForge(String name){
|
||||
public Constructor(String name){
|
||||
super(name);
|
||||
|
||||
size = 3;
|
||||
configurable = true;
|
||||
|
||||
config(Block.class, (BlockForgeBuild tile, Block block) -> {
|
||||
config(Block.class, (ConstructorBuild tile, Block block) -> {
|
||||
if(tile.recipe != block) tile.progress = 0f;
|
||||
if(canProduce(block)){
|
||||
tile.recipe = block;
|
||||
@ -43,7 +42,7 @@ public class BlockForge extends BlockProducer{
|
||||
return b.isVisible() && b.size >= minBlockSize && b.size <= maxBlockSize;
|
||||
}
|
||||
|
||||
public class BlockForgeBuild extends BlockProducerBuild{
|
||||
public class ConstructorBuild extends BlockProducerBuild{
|
||||
public @Nullable Block recipe;
|
||||
|
||||
@Override
|
||||
@ -53,7 +52,7 @@ public class BlockForge extends BlockProducer{
|
||||
|
||||
@Override
|
||||
public void buildConfiguration(Table table){
|
||||
ItemSelection.buildTable(table, content.blocks().select(BlockForge.this::canProduce), () -> recipe, this::configure);
|
||||
ItemSelection.buildTable(table, content.blocks().select(Constructor.this::canProduce), () -> recipe, this::configure);
|
||||
}
|
||||
|
||||
@Override
|
@ -7,6 +7,7 @@ import arc.util.io.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
@ -20,6 +21,8 @@ public interface Payload extends Position{
|
||||
/** draws this payload at a position. */
|
||||
void draw();
|
||||
|
||||
void drawShadow(float alpha);
|
||||
|
||||
/** @return hitbox size of the payload. */
|
||||
float size();
|
||||
|
||||
@ -27,6 +30,12 @@ public interface Payload extends Position{
|
||||
|
||||
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. */
|
||||
default boolean dump(){
|
||||
return false;
|
||||
|
@ -9,6 +9,7 @@ import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@ -24,6 +25,7 @@ public class PayloadBlock extends Block{
|
||||
|
||||
update = true;
|
||||
sync = true;
|
||||
envEnabled |= Env.space;
|
||||
}
|
||||
|
||||
public static boolean blends(Building build, int direction){
|
||||
@ -78,16 +80,16 @@ public class PayloadBlock extends Block{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlSelect(Unit player){
|
||||
return !player.spawnedByCore && this.payload == null && acceptUnitPayload(player) && player.tileOn() != null && player.tileOn().build == this;
|
||||
public boolean canControlSelect(Player player){
|
||||
return !player.unit().spawnedByCore && this.payload == null && acceptUnitPayload(player.unit()) && player.tileOn() != null && player.tileOn().build == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onControlSelect(Unit player){
|
||||
public void onControlSelect(Player player){
|
||||
float x = player.x, y = player.y;
|
||||
handleUnitPayload(player, p -> payload = (T)p);
|
||||
acceptPlayerPayload(player, p -> payload = (T)p);
|
||||
this.payVector.set(x, y).sub(this).clamp(-size * tilesize / 2f, -size * tilesize / 2f, size * tilesize / 2f, size * tilesize / 2f);
|
||||
this.payRotation = player.rotation;
|
||||
this.payRotation = player.unit().rotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,205 @@
|
||||
package mindustry.world.blocks.payloads;
|
||||
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class PayloadDeconstructor extends PayloadBlock{
|
||||
public float maxPayloadSize = 4;
|
||||
public float deconstructSpeed = 2.5f;
|
||||
public int dumpRate = 4;
|
||||
|
||||
public PayloadDeconstructor(String name){
|
||||
super(name);
|
||||
|
||||
outputsPayload = false;
|
||||
acceptsPayload = true;
|
||||
update = true;
|
||||
rotate = false;
|
||||
solid = true;
|
||||
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};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBars(){
|
||||
super.setBars();
|
||||
|
||||
bars.add("progress", (PayloadDeconstructorBuild e) -> new Bar("bar.progress", Pal.ammo, () -> e.progress));
|
||||
}
|
||||
|
||||
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.drawShadow(1f - progress);
|
||||
|
||||
//TODO looks really bad
|
||||
Draw.draw(Layer.blockOver, () -> {
|
||||
Drawf.construct(x, y, deconstructing.icon(), Pal.remove, deconstructing instanceof BuildPayload ? 0f : payRotation - 90f, 1f - progress, 1f - progress, time);
|
||||
Draw.color(Pal.remove);
|
||||
Draw.alpha(1f);
|
||||
|
||||
Lines.lineAngleCenter(x + Mathf.sin(time, 20f, tilesize / 2f * block.size - 3f), y, 90f, block.size * tilesize - 6f);
|
||||
|
||||
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 && payload.fits(maxPayloadSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
if(items.total() > 0){
|
||||
for(int i = 0; i < dumpRate; i++){
|
||||
dumpAccumulate();
|
||||
}
|
||||
}
|
||||
|
||||
if(deconstructing == null){
|
||||
progress = 0f;
|
||||
}
|
||||
|
||||
payRotation = Angles.moveToward(payRotation, 90f, payloadRotateSpeed * edelta());
|
||||
|
||||
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){
|
||||
Fx.breakBlock.at(x, y, deconstructing.size() / tilesize);
|
||||
|
||||
deconstructing = null;
|
||||
accum = null;
|
||||
}
|
||||
}else if(moveInPayload(false) && payload != null){
|
||||
accum = new float[payload.requirements().length];
|
||||
deconstructing = payload;
|
||||
payload = null;
|
||||
progress = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldConsume(){
|
||||
return deconstructing != null && enabled;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
@ -11,20 +11,21 @@ import mindustry.ui.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class BlockLoader extends PayloadBlock{
|
||||
public class PayloadLoader extends PayloadBlock{
|
||||
public final int timerLoad = timers++;
|
||||
|
||||
public float loadTime = 2f;
|
||||
public int itemsLoaded = 5;
|
||||
public float liquidsLoaded = 5f;
|
||||
public int itemsLoaded = 8;
|
||||
public float liquidsLoaded = 40f;
|
||||
public int maxBlockSize = 2;
|
||||
|
||||
public BlockLoader(String name){
|
||||
public PayloadLoader(String name){
|
||||
super(name);
|
||||
|
||||
hasItems = true;
|
||||
itemCapacity = 25;
|
||||
//liquidCapacity = 25;
|
||||
hasLiquids = true;
|
||||
itemCapacity = 100;
|
||||
liquidCapacity = 100f;
|
||||
update = true;
|
||||
outputsPayload = true;
|
||||
size = 3;
|
||||
@ -45,7 +46,7 @@ public class BlockLoader extends PayloadBlock{
|
||||
public void setBars(){
|
||||
super.setBars();
|
||||
|
||||
bars.add("progress", (BlockLoaderBuild entity) -> new Bar(() -> Core.bundle.format("bar.items", entity.payload == null ? 0 : entity.payload.build.items.total()), () -> Pal.items, entity::fraction));
|
||||
bars.add("progress", (PayloadLoaderBuild entity) -> new Bar(() -> Core.bundle.format("bar.items", entity.payload == null ? 0 : entity.payload.build.items.total()), () -> Pal.items, entity::fraction));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,14 +57,14 @@ public class BlockLoader extends PayloadBlock{
|
||||
Draw.rect(topRegion, req.drawx(), req.drawy());
|
||||
}
|
||||
|
||||
public class BlockLoaderBuild extends PayloadBlockBuild<BuildPayload>{
|
||||
public class PayloadLoaderBuild extends PayloadBlockBuild<BuildPayload>{
|
||||
|
||||
@Override
|
||||
public boolean acceptPayload(Building source, Payload payload){
|
||||
return super.acceptPayload(source, payload) &&
|
||||
(payload instanceof BuildPayload build) &&
|
||||
((build.build.block.hasItems && build.block().unloadable && build.block().itemCapacity >= 10 && build.block().size <= maxBlockSize)/* ||
|
||||
((BlockPayload)payload).entity.block().hasLiquids && ((BlockPayload)payload).block().liquidCapacity >= 10f)*/);
|
||||
payload instanceof BuildPayload build &&
|
||||
((build.build.block.hasItems && build.block().unloadable && build.block().itemCapacity >= 10 && build.block().size <= maxBlockSize) ||
|
||||
build.build.block().hasLiquids && build.block().liquidCapacity >= 10f);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,6 +72,11 @@ public class BlockLoader extends PayloadBlock{
|
||||
return items.total() < itemCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptLiquid(Building source, Liquid liquid){
|
||||
return liquids.current() == liquid || liquids.currentAmount() < 0.2f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(region, x, y);
|
||||
@ -120,17 +126,17 @@ public class BlockLoader extends PayloadBlock{
|
||||
}
|
||||
}
|
||||
|
||||
//load up liquids (disabled)
|
||||
/*
|
||||
//load up liquids
|
||||
if(payload.block().hasLiquids && liquids.total() >= 0.001f){
|
||||
Liquid liq = liquids.current();
|
||||
float total = liquids.currentAmount();
|
||||
float flow = Math.min(Math.min(liquidsLoaded * delta(), payload.block().liquidCapacity - payload.entity.liquids.get(liq) - 0.0001f), total);
|
||||
if(payload.entity.acceptLiquid(payload.entity, liq, flow)){
|
||||
payload.entity.liquids.add(liq, flow);
|
||||
float flow = Math.min(Math.min(liquidsLoaded * edelta(), payload.block().liquidCapacity - payload.build.liquids.get(liq)), total);
|
||||
//TODO potential crash here
|
||||
if(payload.build.acceptLiquid(payload.build, liq)){
|
||||
payload.build.liquids.add(liq, flow);
|
||||
liquids.remove(liq, flow);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,8 +145,8 @@ public class BlockLoader extends PayloadBlock{
|
||||
}
|
||||
|
||||
public boolean shouldExport(){
|
||||
return payload != null &&
|
||||
((payload.block().hasLiquids && payload.build.liquids.total() >= payload.block().liquidCapacity - 0.001f) ||
|
||||
return payload != null && (
|
||||
(payload.block().hasLiquids && payload.build.liquids.total() >= payload.block().liquidCapacity - 0.001f) ||
|
||||
(payload.block().hasItems && payload.build.items.total() >= payload.block().itemCapacity));
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package mindustry.world.blocks.payloads;
|
||||
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class PayloadUnloader extends PayloadLoader{
|
||||
public int offloadSpeed = 4;
|
||||
|
||||
public PayloadUnloader(String name){
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outputsItems(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rotatedOutput(int x, int y){
|
||||
return false;
|
||||
}
|
||||
|
||||
public class PayloadUnloaderBuild extends PayloadLoaderBuild{
|
||||
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptLiquid(Building source, Liquid liquid){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
if(shouldExport()){
|
||||
//one-use, disposable block
|
||||
if(payload.block().instantDeconstruct){
|
||||
payload.block().breakEffect.at(this, payload.block().size);
|
||||
payload = null;
|
||||
}else{
|
||||
moveOutPayload();
|
||||
}
|
||||
}else if(moveInPayload()){
|
||||
|
||||
//unload items
|
||||
if(payload.block().hasItems && !full()){
|
||||
if(efficiency() > 0.01f && timer(timerLoad, loadTime / efficiency())){
|
||||
//load up items a set amount of times
|
||||
for(int j = 0; j < itemsLoaded && !full(); j++){
|
||||
for(int i = 0; i < items.length(); i++){
|
||||
if(payload.build.items.get(i) > 0){
|
||||
Item item = content.item(i);
|
||||
payload.build.items.remove(item, 1);
|
||||
items.add(item, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unload liquids
|
||||
//TODO tile is null may crash
|
||||
if(payload.block().hasLiquids && payload.build.liquids.currentAmount() >= 0.01f &&
|
||||
(liquids.current() == payload.build.liquids.current() || liquids.currentAmount() <= 0.2f)){
|
||||
var liq = payload.build.liquids.current();
|
||||
float remaining = liquidCapacity - liquids.currentAmount();
|
||||
float flow = Math.min(Math.min(liquidsLoaded * delta(), remaining), payload.build.liquids.currentAmount());
|
||||
|
||||
liquids.add(liq, flow);
|
||||
payload.build.liquids.remove(liq, flow);
|
||||
}
|
||||
}
|
||||
|
||||
dumpLiquid(liquids.current());
|
||||
for(int i = 0; i < offloadSpeed; i++){
|
||||
dumpAccumulate();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean full(){
|
||||
return items.total() >= itemCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldExport(){
|
||||
return payload != null && (
|
||||
(!payload.block().hasItems || payload.build.items.empty()) &&
|
||||
(!payload.block().hasLiquids || payload.build.liquids.currentAmount() <= 0.001f)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import mindustry.entities.EntityCollisions.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@ -39,6 +40,16 @@ public class UnitPayload implements Payload{
|
||||
showOverlay(icon.getRegion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] requirements(){
|
||||
return unit.type.getTotalRequirements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float buildTime(){
|
||||
return unit.type.getBuildTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Writes write){
|
||||
write.b(payloadUnit);
|
||||
@ -105,11 +116,20 @@ public class UnitPayload implements Payload{
|
||||
//prevents stacking
|
||||
unit.vel.add(Mathf.range(0.5f), Mathf.range(0.5f));
|
||||
unit.add();
|
||||
unit.unloaded();
|
||||
Events.fire(new UnitUnloadEvent(unit));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadow(float alpha){
|
||||
//TODO should not happen
|
||||
if(unit.type == null) return;
|
||||
|
||||
unit.type.drawSoftShadow(unit, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
//TODO should not happen
|
||||
|