Many crazy things

This commit is contained in:
Anuken
2021-11-14 23:10:15 -05:00
parent 70cf55f314
commit 486622e3e4
86 changed files with 472 additions and 318 deletions

View File

@@ -60,7 +60,7 @@ public class Blocks implements ContentList{
//crafting
siliconSmelter, siliconCrucible, siliconArcFurnace, kiln, graphitePress, plastaniumCompressor, multiPress, phaseWeaver, surgeSmelter, pyratiteMixer, blastMixer, cryofluidMixer,
melter, separator, disassembler, sporePress, pulverizer, incinerator, coalCentrifuge,
heatReactor, carbideCrucible,
oxidizer, heatReactor, carbideCrucible,
cellSynthesisChamber,
//sandbox
@@ -75,13 +75,16 @@ public class Blocks implements ContentList{
//transport
conveyor, titaniumConveyor, plastaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router,
overflowGate, underflowGate, massDriver,
//transport - alternate
duct, ductRouter, ductBridge, ductUnloader,
surgeConveyor, surgeRouter,
//liquid
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidContainer, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
mechanicalPump, rotaryPump, impulsePump, conduit, pulseConduit, platedConduit, liquidRouter, liquidContainer, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
reinforcedConduit, reinforcedBridgeConduit, reinforcedLiquidRouter, reinforcedLiquidContainer, reinforcedLiquidTank,
//liquid - reinforced
reinforcedPump, reinforcedConduit, reinforcedBridgeConduit, reinforcedLiquidRouter, reinforcedLiquidContainer, reinforcedLiquidTank,
//power
combustionGenerator, thermalGenerator, steamGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor,
@@ -943,11 +946,21 @@ public class Blocks implements ContentList{
consumes.power(0.50f);
}};
oxidizer = new HeatProducer("oxidizer"){{
requirements(Category.crafting, with(Items.tungsten, 60, Items.graphite, 30));
//TODO bigger?
size = 2;
//TODO multi liquid output
//converts oxygen (?) + beryllium into heat + oxide
}};
heatReactor = new HeatProducer("heat-reactor"){{
//TODO quadvent
//TODO coolant?
requirements(Category.crafting, with(Items.tungsten, 60, Items.graphite, 30));
size = 3;
consumeTime = 60f * 10f;
craftTime = 60f * 10f;
consumes.item(Items.fissileMatter, 1);
}};
@@ -1370,7 +1383,7 @@ public class Blocks implements ContentList{
size = 2;
}};
thermalPump = new Pump("thermal-pump"){{
impulsePump = new Pump("impulse-pump"){{
requirements(Category.liquid, with(Items.copper, 80, Items.metaglass, 90, Items.silicon, 30, Items.titanium, 40, Items.thorium, 35));
pumpAmount = 0.22f;
consumes.power(1.3f);
@@ -1439,6 +1452,21 @@ public class Blocks implements ContentList{
consumes.power(0.30f);
}};
//reinforced stuff
//TODO different name
reinforcedPump = new Pump("reinforced-pump"){{
requirements(Category.liquid, with(Items.beryllium, 70, Items.tungsten, 20, Items.silicon, 20));
//TODO perhaps something else?
consumes.item(Items.beryllium);
pumpAmount = 0.4f;
consumes.power(0.5f);
liquidCapacity = 40f;
hasPower = true;
size = 2;
}};
reinforcedConduit = new ArmoredConduit("reinforced-conduit"){{
requirements(Category.liquid, with(Items.beryllium, 2, Items.graphite, 1));
botColor = Pal.darkestMetal;

View File

@@ -8,7 +8,7 @@ public class Items implements ContentList{
public static Item
scrap, copper, lead, graphite, coal, titanium, thorium, silicon, plastanium,
phaseFabric, surgeAlloy, sporePod, sand, blastCompound, pyratite, metaglass,
beryllium, fissileMatter, dormantCyst, tungsten, carbide;
beryllium, tungsten, oxide, carbide, fissileMatter, dormantCyst;
@Override
public void load(){
@@ -98,6 +98,19 @@ public class Items implements ContentList{
cost = 1.3f;
}};
tungsten = new Item("tungsten", Color.valueOf("768a9a")){{
hardness = 5;
cost = 1.5f;
}};
oxide = new Item("oxide", Color.valueOf("e4ffd6")){{
cost = 1.1f;
}};
carbide = new Item("carbide", Color.valueOf("89769a")){{
cost = 1.3f;
}};
fissileMatter = new Item("fissile-matter", Color.valueOf("5e988d")){{
radioactivity = 1.5f;
}};
@@ -105,14 +118,5 @@ public class Items implements ContentList{
dormantCyst = new Item("dormant-cyst", Color.valueOf("df824d")){{
flammability = 0.1f;
}};
tungsten = new Item("tungsten", Color.valueOf("768a9a")){{
hardness = 5;
cost = 1.5f;
}};
carbide = new Item("carbide", Color.valueOf("89769a")){{
cost = 1.3f;
}};
}
}

View File

@@ -5,7 +5,8 @@ import mindustry.ctype.*;
import mindustry.type.*;
public class Liquids implements ContentList{
public static Liquid water, slag, oil, cryofluid, neoplasm;
public static Liquid water, slag, oil, cryofluid, neoplasm,
ozone, hydrogen;
@Override
public void load(){
@@ -55,5 +56,21 @@ public class Liquids implements ContentList{
colorFrom = Color.valueOf("f98f4a");
colorTo = Color.valueOf("9e172c");
}};
//TODO reactivity, etc
ozone = new Liquid("ozone", Color.valueOf("bdd7ff")){{
gas = true;
barColor = Color.valueOf("97bdf7");
explosiveness = 1f;
flammability = 1f;
}};
//TODO combustion
hydrogen = new Liquid("hydrogen", Color.valueOf("e8d1ff")){{
gas = true;
barColor = Color.valueOf("c599f0");
}};
//TODO dicyanoacetylene
}
}

View File

@@ -104,7 +104,7 @@ public class TechTree implements ContentList{
});
node(rotaryPump, () -> {
node(thermalPump, () -> {
node(impulsePump, () -> {
});
});

View File

@@ -572,6 +572,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
}
public void dumpLiquid(Liquid liquid, float scaling){
dumpLiquid(liquid, scaling, -1);
}
/** @param outputDir output liquid direction relative to rotation, or -1 to use any direction. */
public void dumpLiquid(Liquid liquid, float scaling, int outputDir){
int dump = this.cdump;
if(liquids.get(liquid) <= 0.0001f) return;
@@ -581,6 +586,9 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
for(int i = 0; i < proximity.size; i++){
incrementDump(proximity.size);
Building other = proximity.get((i + dump) % proximity.size);
if(outputDir != -1 && (relativeTo(other) + rotation) % 4 != outputDir) return;
other = other.getLiquidDestination(self(), liquid);
if(other != null && other.team == team && other.block.hasLiquids && canDumpLiquid(other, liquid) && other.liquids != null){
@@ -1211,13 +1219,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
public void displayBars(Table table){
for(Func<Building, Bar> bar : block.bars.list()){
//TODO fix conclusively
try{
table.add(bar.get(self())).growX();
table.row();
}catch(ClassCastException e){
break;
}
table.add(bar.get(self())).growX();
table.row();
}
}

View File

@@ -128,13 +128,13 @@ public class Drawf{
}
public static void liquid(TextureRegion region, float x, float y, float alpha, Color color, float rotation){
Draw.color(color, alpha);
Draw.color(color, alpha * color.a);
Draw.rect(region, x, y, rotation);
Draw.color();
}
public static void liquid(TextureRegion region, float x, float y, float alpha, Color color){
Draw.color(color, alpha);
Draw.color(color, alpha * color.a);
Draw.rect(region, x, y);
Draw.color();
}

View File

@@ -59,7 +59,8 @@ public abstract class SaveFileReader{
"cryofluidmixer", "cryofluid-mixer",
"block-forge", "constructor",
"block-unloader", "payload-unloader",
"block-loader", "payload-loader"
"block-loader", "payload-loader",
"thermal-pump", "impulse-pump"
);
public static final ObjectMap<String, String> modContentNameMap = ObjectMap.of(

View File

@@ -14,9 +14,12 @@ import mindustry.world.meta.*;
import static mindustry.entities.Puddles.*;
/** A better name for this class would be "fluid", but it's too late for that. */
public class Liquid extends UnlockableContent{
protected static final Rand rand = new Rand();
/** TODO If true, this fluid is treated as a gas (and does not create puddles) */
public boolean gas = false;
/** Color used in pipes and on the ground. */
public Color color;
/** Color of this liquid in gas form. */
@@ -58,6 +61,22 @@ public class Liquid extends UnlockableContent{
this(name, new Color(Color.black));
}
@Override
public void init(){
super.init();
if(gas){
//always "boils", it's a gas
boilPoint = -1;
//ensure no accidental global mutation
color = color.cpy();
//all gases are transparent
color.a = 0.5f;
//for gases, gas color is implicitly their color
gasColor = color;
}
}
/** @return true if this liquid will boil in this global environment. */
public boolean willBoil(){
return Attribute.heat.env() >= boilPoint;

View File

@@ -30,19 +30,11 @@ public class Bar extends Element{
public Bar(Prov<CharSequence> name, Prov<Color> color, Floatp fraction){
this.fraction = fraction;
try{
lastValue = value = Mathf.clamp(fraction.get());
}catch(Exception e){ //getting the fraction may involve referring to invalid data
lastValue = value = 0f;
}
lastValue = value = Mathf.clamp(fraction.get());
update(() -> {
try{
this.name = name.get();
this.blinkColor.set(color.get());
setColor(color.get());
}catch(Exception e){ //getting the fraction may involve referring to invalid data
this.name = "";
}
this.name = name.get();
this.blinkColor.set(color.get());
setColor(color.get());
});
}
@@ -85,12 +77,8 @@ public class Bar extends Element{
public void draw(){
if(fraction == null) return;
float computed;
try{
computed = Mathf.clamp(fraction.get());
}catch(Exception e){ //getting the fraction may involve referring to invalid data
computed = 0f;
}
float computed = Mathf.clamp(fraction.get());
if(lastValue > computed){
blink = 1f;

View File

@@ -454,10 +454,14 @@ public class Block extends UnlockableContent{
Liquid liquid = consumes.<ConsumeLiquid>get(ConsumeType.liquid).liquid;
current = entity -> liquid;
}else{
current = entity -> entity.liquids == null ? Liquids.water : entity.liquids.current();
current = entity -> entity.liquids.current();
}
bars.add("liquid", entity -> new Bar(() -> entity.liquids.get(current.get(entity)) <= 0.001f ? Core.bundle.get("bar.liquid") : current.get(entity).localizedName,
() -> current.get(entity).barColor(), () -> entity == null || entity.liquids == null ? 0f : entity.liquids.get(current.get(entity)) / liquidCapacity));
bars.add("liquid", entity -> new Bar(
() -> entity.liquids.get(current.get(entity)) <= 0.001f ? Core.bundle.get("bar.liquid") : current.get(entity).localizedName,
() -> current.get(entity).barColor(),
() -> entity.liquids.get(current.get(entity)) / liquidCapacity)
);
}
if(hasPower && consumes.hasPower()){
@@ -465,12 +469,20 @@ public class Block extends UnlockableContent{
boolean buffered = cons.buffered;
float capacity = cons.capacity;
bars.add("power", entity -> new Bar(() -> buffered ? Core.bundle.format("bar.poweramount", Float.isNaN(entity.power.status * capacity) ? "<ERROR>" : UI.formatAmount((int)(entity.power.status * capacity))) :
Core.bundle.get("bar.power"), () -> Pal.powerBar, () -> Mathf.zero(cons.requestedPower(entity)) && entity.power.graph.getPowerProduced() + entity.power.graph.getBatteryStored() > 0f ? 1f : entity.power.status));
bars.add("power", entity -> new Bar(
() -> buffered ? Core.bundle.format("bar.poweramount", Float.isNaN(entity.power.status * capacity) ? "<ERROR>" : UI.formatAmount((int)(entity.power.status * capacity))) :
Core.bundle.get("bar.power"),
() -> Pal.powerBar,
() -> Mathf.zero(cons.requestedPower(entity)) && entity.power.graph.getPowerProduced() + entity.power.graph.getBatteryStored() > 0f ? 1f : entity.power.status)
);
}
if(hasItems && configurable){
bars.add("items", entity -> new Bar(() -> Core.bundle.format("bar.items", entity.items.total()), () -> Pal.items, () -> (float)entity.items.total() / itemCapacity));
bars.add("items", entity -> new Bar(
() -> Core.bundle.format("bar.items", entity.items.total()),
() -> Pal.items,
() -> (float)entity.items.total() / itemCapacity)
);
}
if(unitCapModifier != 0){
@@ -515,46 +527,46 @@ public class Block extends UnlockableContent{
}
public void drawPlan(BuildPlan req, Eachable<BuildPlan> list, boolean valid){
drawPlan(req, list, valid, 1f);
public void drawPlan(BuildPlan plan, Eachable<BuildPlan> list, boolean valid){
drawPlan(plan, list, valid, 1f);
}
public void drawPlan(BuildPlan req, Eachable<BuildPlan> list, boolean valid, float alpha){
public void drawPlan(BuildPlan plan, Eachable<BuildPlan> list, boolean valid, float alpha){
Draw.reset();
Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f));
Draw.alpha(alpha);
float prevScale = Draw.scl;
Draw.scl *= req.animScale;
drawRequestRegion(req, list);
Draw.scl *= plan.animScale;
drawRequestRegion(plan, list);
Draw.scl = prevScale;
Draw.reset();
}
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
TextureRegion reg = getRequestRegion(req, list);
Draw.rect(reg, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
TextureRegion reg = getRequestRegion(plan, list);
Draw.rect(reg, plan.drawx(), plan.drawy(), !rotate ? 0 : plan.rotation * 90);
if(req.worldContext && player != null && teamRegion != null && teamRegion.found()){
if(plan.worldContext && player != null && teamRegion != null && teamRegion.found()){
if(teamRegions[player.team().id] == teamRegion) Draw.color(player.team().color);
Draw.rect(teamRegions[player.team().id], req.drawx(), req.drawy());
Draw.rect(teamRegions[player.team().id], plan.drawx(), plan.drawy());
Draw.color();
}
drawRequestConfig(req, list);
drawRequestConfig(plan, list);
}
public TextureRegion getRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
public TextureRegion getRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
return fullIcon;
}
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
public void drawRequestConfig(BuildPlan plan, Eachable<BuildPlan> list){
}
public void drawRequestConfigCenter(BuildPlan req, Object content, String region, boolean cross){
public void drawRequestConfigCenter(BuildPlan plan, Object content, String region, boolean cross){
if(content == null){
if(cross){
Draw.rect("cross", req.drawx(), req.drawy());
Draw.rect("cross", plan.drawx(), plan.drawy());
}
return;
}
@@ -562,15 +574,15 @@ public class Block extends UnlockableContent{
if(color == null) return;
Draw.color(color);
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.color();
}
public void drawRequestConfigCenter(BuildPlan req, Object content, String region){
drawRequestConfigCenter(req, content, region, false);
public void drawRequestConfigCenter(BuildPlan plan, Object content, String region){
drawRequestConfigCenter(plan, content, region, false);
}
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
public void drawRequestConfigTop(BuildPlan plan, Eachable<BuildPlan> list){
}

View File

@@ -51,8 +51,8 @@ public class Door extends Wall{
}
@Override
public TextureRegion getRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
return req.config == Boolean.TRUE ? openRegion : region;
public TextureRegion getRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
return plan.config == Boolean.TRUE ? openRegion : region;
}
public class DoorBuild extends Building{

View File

@@ -15,9 +15,9 @@ public class Thruster extends Wall{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(topRegion, req.drawx(), req.drawy(), req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(topRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
}
@Override

View File

@@ -66,13 +66,13 @@ public class Conveyor extends Block implements Autotiler{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
int[] bits = getTiling(req, list);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
int[] bits = getTiling(plan, list);
if(bits == null) return;
TextureRegion region = regions[bits[0]][0];
Draw.rect(region, req.drawx(), req.drawy(), region.width * bits[1] * Draw.scl, region.height * bits[2] * Draw.scl, req.rotation * 90);
Draw.rect(region, plan.drawx(), plan.drawy(), region.width * bits[1] * Draw.scl, region.height * bits[2] * Draw.scl, plan.rotation * 90);
}
@Override

View File

@@ -47,19 +47,19 @@ public class DirectionBridge extends Block{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(dirRegion, req.drawx(), req.drawy(), req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(dirRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
public void drawRequestConfigTop(BuildPlan plan, Eachable<BuildPlan> list){
otherReq = null;
otherDst = range;
Point2 d = Geometry.d4(req.rotation);
Point2 d = Geometry.d4(plan.rotation);
list.each(other -> {
if(other.block == this && req != other && Mathf.clamp(other.x - req.x, -1, 1) == d.x && Mathf.clamp(other.y - req.y, -1, 1) == d.y){
int dst = Math.max(Math.abs(other.x - req.x), Math.abs(other.y - req.y));
if(other.block == this && plan != other && Mathf.clamp(other.x - plan.x, -1, 1) == d.x && Mathf.clamp(other.y - plan.y, -1, 1) == d.y){
int dst = Math.max(Math.abs(other.x - plan.x), Math.abs(other.y - plan.y));
if(dst <= otherDst){
otherReq = other;
otherDst = dst;
@@ -68,7 +68,7 @@ public class DirectionBridge extends Block{
});
if(otherReq != null){
drawBridge(req.rotation, req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), null);
drawBridge(plan.rotation, plan.drawx(), plan.drawy(), otherReq.drawx(), otherReq.drawy(), null);
}
}

View File

@@ -46,15 +46,15 @@ public class DirectionalUnloader extends Block{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(topRegion, req.drawx(), req.drawy(), req.rotation * 90);
drawRequestConfig(req, list);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(topRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
drawRequestConfig(plan, list);
}
@Override
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
drawRequestConfigCenter(req, req.config, "duct-unloader-center");
public void drawRequestConfig(BuildPlan plan, Eachable<BuildPlan> list){
drawRequestConfigCenter(plan, plan.config, "duct-unloader-center");
}
@Override

View File

@@ -50,16 +50,16 @@ public class Duct extends Block implements Autotiler{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
int[] bits = getTiling(req, list);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
int[] bits = getTiling(plan, list);
if(bits == null) return;
Draw.scl(bits[1], bits[2]);
Draw.alpha(0.5f);
Draw.rect(botRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(botRegions[bits[0]], plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.color();
Draw.rect(topRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(topRegions[bits[0]], plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.scl();
}

View File

@@ -53,9 +53,9 @@ public class DuctRouter extends Block{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(topRegion, req.drawx(), req.drawy(), req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(topRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
}
public class DuctRouterBuild extends Building{

View File

@@ -61,16 +61,16 @@ public class ItemBridge extends Block{
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
public void drawRequestConfigTop(BuildPlan plan, Eachable<BuildPlan> list){
otherReq = null;
list.each(other -> {
if(other.block == this && req != other && req.config instanceof Point2 p && p.equals(other.x - req.x, other.y - req.y)){
if(other.block == this && plan != other && plan.config instanceof Point2 p && p.equals(other.x - plan.x, other.y - plan.y)){
otherReq = other;
}
});
if(otherReq != null){
drawBridge(req, otherReq.drawx(), otherReq.drawy(), 0);
drawBridge(plan, otherReq.drawx(), otherReq.drawy(), 0);
}
}

View File

@@ -21,10 +21,10 @@ public class PayloadRouter extends PayloadConveyor{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
super.drawRequestRegion(req, list);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
super.drawRequestRegion(plan, list);
Draw.rect(overRegion, req.drawx(), req.drawy());
Draw.rect(overRegion, plan.drawx(), plan.drawy());
}
public class PayloadRouterBuild extends PayloadConveyorBuild{

View File

@@ -32,8 +32,8 @@ public class Sorter extends Block{
}
@Override
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
drawRequestConfigCenter(req, req.config, "center", true);
public void drawRequestConfig(BuildPlan plan, Eachable<BuildPlan> list){
drawRequestConfigCenter(plan, plan.config, "center", true);
}
@Override

View File

@@ -82,17 +82,17 @@ public class StackConveyor extends Block implements Autotiler{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
int[] bits = getTiling(req, list);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
int[] bits = getTiling(plan, list);
if(bits == null) return;
TextureRegion region = regions[0];
Draw.rect(region, req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(region, plan.drawx(), plan.drawy(), plan.rotation * 90);
for(int i = 0; i < 4; i++){
if((bits[3] & (1 << i)) == 0){
Draw.rect(edgeRegion, req.drawx(), req.drawy(), (req.rotation - i) * 90);
Draw.rect(edgeRegion, plan.drawx(), plan.drawy(), (plan.rotation - i) * 90);
}
}
}

View File

@@ -3,4 +3,6 @@ package mindustry.world.blocks.heat;
/** Basic interface for any block that produces heat.*/
public interface HeatBlock{
float heat();
/** @return heat as a fraction of max heat */
float heatFrac();
}

View File

@@ -1,47 +1,28 @@
package mindustry.world.blocks.heat;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.power.NuclearReactor.*;
import mindustry.world.meta.*;
import mindustry.world.blocks.production.*;
import mindustry.world.draw.*;
public class HeatProducer extends Block{
public class HeatProducer extends GenericCrafter{
public float heatOutput = 10f;
public float warmupRate = 0.15f;
public float consumeTime = 100;
public @Load("@-heat") TextureRegion heatRegion;
public @Load("@-glow") TextureRegion glowRegion;
public @Load("@-top1") TextureRegion topRegion1;
public @Load("@-top2") TextureRegion topRegion2;
public Color heatColor = new Color(1f, 0.22f, 0.22f, 0.8f);
public float heatPulse = 0.3f, heatPulseScl = 10f, glowMult = 1.2f;
public Effect consumeEffect = Fx.none;
public HeatProducer(String name){
super(name);
drawer = new DrawHeatOutput();
update = solid = rotate = true;
canOverdrive = false;
}
@Override
public void setStats(){
stats.timePeriod = consumeTime;
super.setStats();
stats.add(Stat.productionTime, consumeTime / 60f, StatUnit.seconds);
//TODO heat prod stats
}
@@ -52,64 +33,20 @@ public class HeatProducer extends Block{
bars.add("heat", (NuclearReactorBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat));
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(req.rotation > 1 ? topRegion2 : topRegion1, req.drawx(), req.drawy(), req.rotation * 90);
}
@Override
public TextureRegion[] icons(){
return new TextureRegion[]{region, topRegion1};
}
public class HeatProducerBuild extends Building implements HeatBlock{
public class HeatProducerBuild extends GenericCrafterBuild implements HeatBlock{
public float heat;
public float progress;
@Override
public void updateTile(){
if(consValid()){
progress += getProgressIncrease(consumeTime);
if(progress >= 1f){
consume();
consumeEffect.at(this);
progress -= 1f;
}
}
super.updateTile();
//heat approaches target at the same speed regardless of efficiency
heat = Mathf.approachDelta(heat, heatOutput * efficiency() * Mathf.num(consValid()), warmupRate * delta());
}
@Override
public void draw(){
Draw.rect(region, x, y);
Draw.rect(rotation > 1 ? topRegion2 : topRegion1, x, y, rotdeg());
if(heat > 0){
Draw.z(Layer.blockAdditive);
Draw.blend(Blending.additive);
Draw.color(heatColor, heat / heatOutput * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse))));
Draw.rect(heatRegion, x, y, rotdeg());
Draw.color(Draw.getColor().mul(glowMult));
Draw.rect(glowRegion, x, y);
Draw.blend();
Draw.color();
}
}
@Override
public double sense(LAccess sensor){
if(sensor == LAccess.progress) return Mathf.clamp(progress);
return super.sense(sensor);
}
@Override
public boolean shouldAmbientSound(){
return cons.valid();
public float heatFrac(){
return heat / heatOutput;
}
@Override
@@ -120,14 +57,12 @@ public class HeatProducer extends Block{
@Override
public void write(Writes write){
super.write(write);
write.f(progress);
write.f(heat);
}
@Override
public void read(Reads read, byte revision){
super.read(read, revision);
progress = read.f();
heat = read.f();
}
}

View File

@@ -52,17 +52,17 @@ public class Conduit extends LiquidBlock implements Autotiler{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
int[] bits = getTiling(req, list);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
int[] bits = getTiling(plan, list);
if(bits == null) return;
Draw.scl(bits[1], bits[2]);
Draw.color(botColor);
Draw.alpha(0.5f);
Draw.rect(botRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(botRegions[bits[0]], plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.color();
Draw.rect(topRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(topRegions[bits[0]], plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.scl();
}

View File

@@ -39,10 +39,10 @@ public abstract class BlockProducer extends PayloadBlock{
}
@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());
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

View File

@@ -51,11 +51,11 @@ public class PayloadLoader extends PayloadBlock{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(inRegion, req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(topRegion, req.drawx(), req.drawy());
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(inRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.rect(outRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.rect(topRegion, plan.drawx(), plan.drawy());
}
public class PayloadLoaderBuild extends PayloadBlockBuild<BuildPayload>{

View File

@@ -87,11 +87,11 @@ public class PayloadMassDriver extends PayloadBlock{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(baseRegion, req.drawx(), req.drawy());
Draw.rect(topRegion, req.drawx(), req.drawy());
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(region, req.drawx(), req.drawy());
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(baseRegion, plan.drawx(), plan.drawy());
Draw.rect(topRegion, plan.drawx(), plan.drawy());
Draw.rect(outRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.rect(region, plan.drawx(), plan.drawy());
}
@Override

View File

@@ -64,10 +64,10 @@ public class PayloadSource extends PayloadBlock{
}
@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());
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());
}
public boolean canProduce(Block b){

View File

@@ -35,9 +35,9 @@ public class PowerDiode extends Block{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(fullIcon, req.drawx(), req.drawy());
Draw.rect(arrow, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(fullIcon, plan.drawx(), plan.drawy());
Draw.rect(arrow, plan.drawx(), plan.drawy(), !rotate ? 0 : plan.rotation * 90);
}
// battery % of the graph on either side, defaults to zero

View File

@@ -302,23 +302,23 @@ public class PowerNode extends PowerBlock{
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
if(req.config instanceof Point2[] ps){
public void drawRequestConfigTop(BuildPlan plan, Eachable<BuildPlan> list){
if(plan.config instanceof Point2[] ps){
setupColor(1f);
for(Point2 point : ps){
int px = req.x + point.x, py = req.y + point.y;
int px = plan.x + point.x, py = plan.y + point.y;
otherReq = null;
list.each(other -> {
if(other.block != null
&& (px >= other.x - ((other.block.size-1)/2) && py >= other.y - ((other.block.size-1)/2) && px <= other.x + other.block.size/2 && py <= other.y + other.block.size/2)
&& other != req && other.block.hasPower){
&& other != plan && other.block.hasPower){
otherReq = other;
}
});
if(otherReq == null || otherReq.block == null) continue;
drawLaser(player == null ? Team.sharded : player.team(), req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), size, otherReq.block.size);
drawLaser(player == null ? Team.sharded : player.team(), plan.drawx(), plan.drawy(), otherReq.drawx(), otherReq.drawy(), size, otherReq.block.size);
}
Draw.color();
}

View File

@@ -71,9 +71,9 @@ public class BeamDrill extends Block{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(topRegion, req.drawx(), req.drawy(), req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(topRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
}
@Override

View File

@@ -82,16 +82,16 @@ public class Drill extends Block{
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
if(!req.worldContext) return;
Tile tile = req.tile();
public void drawRequestConfigTop(BuildPlan plan, Eachable<BuildPlan> list){
if(!plan.worldContext) return;
Tile tile = plan.tile();
if(tile == null) return;
countOre(tile);
if(returnItem == null || !drawMineItem) return;
Draw.color(returnItem.color);
Draw.rect(itemRegion, req.drawx(), req.drawy());
Draw.rect(itemRegion, plan.drawx(), plan.drawy());
Draw.color();
}

View File

@@ -7,9 +7,11 @@ import arc.util.*;
import arc.util.io.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.logic.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.draw.*;
import mindustry.world.meta.*;
@@ -19,7 +21,13 @@ public class GenericCrafter extends Block{
public @Nullable ItemStack outputItem;
/** Overwrites outputItem if not null. */
public @Nullable ItemStack[] outputItems;
/** Written to outputLiquids as a single-element array if outputLiquids is null. */
public @Nullable LiquidStack outputLiquid;
/** Overwrites outputLiquid if not null. */
public @Nullable LiquidStack[] outputLiquids;
/** Liquid output directions, specified in the same order as outputLiquids. Use -1 to dump in every direction. Rotations are relative to block. */
public int[] liquidOutputDirections = {-1};
public float craftTime = 80;
public Effect craftEffect = Fx.none;
@@ -52,8 +60,27 @@ public class GenericCrafter extends Block{
stats.add(Stat.output, StatValues.items(craftTime, outputItems));
}
if(outputLiquid != null){
stats.add(Stat.output, outputLiquid.liquid, outputLiquid.amount * (60f / craftTime), true);
if(outputLiquids != null){
stats.add(Stat.output, StatValues.liquids(craftTime, outputLiquids));
}
}
@Override
public void setBars(){
super.setBars();
//set up liquid bars for multiple liquid outputs; TODO multiple inputs not yet supported due to inherent complexity
//TODO this will currently screw up input display if input liquids are available
if(outputLiquids != null && outputLiquids.length > 1){
bars.remove("liquid");
for(var stack : outputLiquids){
bars.add("liquid-" + stack.liquid.name, entity -> new Bar(
() -> stack.liquid.localizedName,
() -> stack.liquid.barColor(),
() -> entity.liquids.get(stack.liquid) / liquidCapacity)
);
}
}
}
@@ -70,9 +97,21 @@ public class GenericCrafter extends Block{
if(outputItems == null && outputItem != null){
outputItems = new ItemStack[]{outputItem};
}
if(outputLiquids == null && outputLiquid != null){
outputLiquids = new LiquidStack[]{outputLiquid};
}
super.init();
}
public void drawPlanBase(BuildPlan req, Eachable<BuildPlan> list){
super.drawRequestRegion(req, list);
}
@Override
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
drawer.drawPlan(this, plan, list);
}
@Override
public TextureRegion[] icons(){
return drawer.icons(this);
@@ -102,13 +141,21 @@ public class GenericCrafter extends Block{
@Override
public boolean shouldConsume(){
if(outputItems != null){
for(ItemStack output : outputItems){
for(var output : outputItems){
if(items.get(output.item) + output.amount > itemCapacity){
return false;
}
}
}
return (outputLiquid == null || !(liquids.get(outputLiquid.liquid) >= liquidCapacity - 0.001f)) && enabled;
if(outputLiquids != null){
for(var output : outputLiquids){
if(liquids.get(output.liquid) >= liquidCapacity - 0.001f){
return false;
}
}
}
return enabled;
}
@Override
@@ -141,15 +188,17 @@ public class GenericCrafter extends Block{
consume();
if(outputItems != null){
for(ItemStack output : outputItems){
for(var output : outputItems){
for(int i = 0; i < output.amount; i++){
offload(output.item);
}
}
}
if(outputLiquid != null){
handleLiquid(this, outputLiquid.liquid, outputLiquid.amount);
if(outputLiquids != null){
for(var output : outputLiquids){
handleLiquid(this, output.liquid, output.amount);
}
}
craftEffect.at(x, y);
@@ -163,8 +212,12 @@ public class GenericCrafter extends Block{
}
}
if(outputLiquid != null){
dumpLiquid(outputLiquid.liquid);
if(outputLiquids != null){
for(int i = 0; i < outputLiquids.length; i++){
int dir = liquidOutputDirections.length > i ? liquidOutputDirections[i] : -1;
dumpLiquid(outputLiquids[i].liquid, 2f, dir);
}
}
}

View File

@@ -15,6 +15,8 @@ import static mindustry.Vars.*;
public class Pump extends LiquidBlock{
/** Pump amount per tile. */
public float pumpAmount = 0.2f;
/** Interval in-between item consumptions, if applicable. */
public float consumeTime = 60f * 5f;
public Pump(String name){
super(name);
@@ -41,6 +43,10 @@ public class Pump extends LiquidBlock{
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
if(canPump(other)){
if(liquidDrop != null && other.floor().liquidDrop != liquidDrop){
liquidDrop = null;
break;
}
liquidDrop = other.floor().liquidDrop;
amount += other.floor().liquidMultiplier;
}
@@ -81,6 +87,7 @@ public class Pump extends LiquidBlock{
}
public class PumpBuild extends LiquidBuild{
public float consTimer;
public float amount = 0f;
public Liquid liquidDrop = null;
@@ -121,6 +128,12 @@ public class Pump extends LiquidBlock{
if(consValid() && liquidDrop != null){
float maxPump = Math.min(liquidCapacity - liquids.total(), amount * pumpAmount * edelta());
liquids.add(liquidDrop, maxPump);
//does nothing for most pumps, as those do not require items.
if((consTimer += delta()) >= consumeTime){
consume();
consumeTime = 0f;
}
}
dumpLiquid(liquids.current());

View File

@@ -81,9 +81,9 @@ public class WallCrafter extends Block{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(topRegion, req.drawx(), req.drawy(), req.rotation * 90);
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(topRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
}
@Override

View File

@@ -45,8 +45,8 @@ public class ItemSource extends Block{
}
@Override
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
drawRequestConfigCenter(req, req.config, "center", true);
public void drawRequestConfig(BuildPlan plan, Eachable<BuildPlan> list){
drawRequestConfigCenter(plan, plan.config, "center", true);
}
@Override

View File

@@ -41,8 +41,8 @@ public class LiquidSource extends Block{
}
@Override
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
drawRequestConfigCenter(req, req.config, "center", true);
public void drawRequestConfig(BuildPlan plan, Eachable<BuildPlan> list){
drawRequestConfigCenter(plan, plan.config, "center", true);
}
public class LiquidSourceBuild extends Building{

View File

@@ -44,8 +44,8 @@ public class Unloader extends Block{
}
@Override
public void drawRequestConfig(BuildPlan req, Eachable<BuildPlan> list){
drawRequestConfigCenter(req, req.config, "unloader-center");
public void drawRequestConfig(BuildPlan plan, Eachable<BuildPlan> list){
drawRequestConfigCenter(plan, plan.config, "unloader-center");
}
@Override

View File

@@ -32,11 +32,11 @@ public class Reconstructor extends UnitBlock{
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(inRegion, req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(outRegion, req.drawx(), req.drawy(), req.rotation * 90);
Draw.rect(topRegion, req.drawx(), req.drawy());
public void drawRequestRegion(BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(region, plan.drawx(), plan.drawy());
Draw.rect(inRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.rect(outRegion, plan.drawx(), plan.drawy(), plan.rotation * 90);
Draw.rect(topRegion, plan.drawx(), plan.drawy());
}
@Override

View File

@@ -116,10 +116,10 @@ public class UnitFactory extends UnitBlock{
}
@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());
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());
}
public static class UnitPlan{

View File

@@ -2,7 +2,10 @@ package mindustry.world.draw;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.entities.units.*;
import mindustry.world.*;
import mindustry.world.blocks.production.*;
import mindustry.world.blocks.production.GenericCrafter.*;
/** An implementation of custom rendering behavior for a crafter block.
@@ -20,6 +23,11 @@ public class DrawBlock{
}
/** Draws the planned version of this block. */
public void drawPlan(GenericCrafter crafter, BuildPlan plan, Eachable<BuildPlan> list){
crafter.drawPlanBase(plan, list);
}
/** Load any relevant texture regions. */
public void load(Block block){

View File

@@ -0,0 +1,58 @@
package mindustry.world.draw;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.entities.units.*;
import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.blocks.heat.*;
import mindustry.world.blocks.production.*;
import mindustry.world.blocks.production.GenericCrafter.*;
public class DrawHeatOutput extends DrawBlock{
public TextureRegion heat, glow, top1, top2;
public Color heatColor = new Color(1f, 0.22f, 0.22f, 0.8f);
public float heatPulse = 0.3f, heatPulseScl = 10f, glowMult = 1.2f;
@Override
public void draw(GenericCrafterBuild build){
Draw.rect(build.block.region, build.x, build.y);
Draw.rect(build.rotation > 1 ? top2 : top1, build.x, build.y, build.rotdeg());
if(build instanceof HeatBlock heater && heater.heat() > 0){
Draw.z(Layer.blockAdditive);
Draw.blend(Blending.additive);
Draw.color(heatColor, heater.heatFrac() * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse))));
Draw.rect(heat, build.x, build.y, build.rotdeg());
Draw.color(Draw.getColor().mul(glowMult));
Draw.rect(glow, build.x, build.y);
Draw.blend();
Draw.color();
}
}
@Override
public void drawPlan(GenericCrafter block, BuildPlan plan, Eachable<BuildPlan> list){
Draw.rect(block.region, plan.drawx(), plan.drawy());
Draw.rect(plan.rotation > 1 ? top2 : top1, plan.drawx(), plan.drawy(), plan.rotation * 90);
}
@Override
public void load(Block block){
heat = Core.atlas.find(block.name + "-heat");
glow = Core.atlas.find(block.name + "-glow");
top1 = Core.atlas.find(block.name + "-top1");
top2 = Core.atlas.find(block.name + "-top2");
}
@Override
public TextureRegion[] icons(Block block){
return new TextureRegion[]{block.region, top1};
}
}

View File

@@ -61,6 +61,14 @@ public class StatValues{
};
}
public static StatValue liquids(float timePeriod, LiquidStack... stacks){
return table -> {
for(var stack : stacks){
table.add(new LiquidDisplay(stack.liquid, stack.amount * (60f / timePeriod), true)).padRight(5);
}
};
}
public static StatValue items(ItemStack... stacks){
return items(true, stacks);
}