Launch pad rework progress, base mechanics done
This commit is contained in:
@@ -1,18 +1,46 @@
|
||||
package mindustry.world.blocks.campaign;
|
||||
|
||||
import arc.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.io.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.consumers.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class LandingPad extends Block{
|
||||
static ObjectMap<Item, Seq<LandingPadBuild>> waiting = new ObjectMap<>();
|
||||
static long lastUpdateId = -1;
|
||||
|
||||
static{
|
||||
Events.on(ResetEvent.class, e -> {
|
||||
waiting.clear();
|
||||
lastUpdateId = -1;
|
||||
});
|
||||
}
|
||||
|
||||
public float cooldownTime = 12f;
|
||||
public float consumeLiquidAmount = 100f;
|
||||
public Liquid consumeLiquid = Liquids.water;
|
||||
|
||||
public LandingPad(String name){
|
||||
super(name);
|
||||
|
||||
hasItems = true;
|
||||
hasLiquids = true;
|
||||
solid = true;
|
||||
update = true;
|
||||
configurable = true;
|
||||
@@ -22,19 +50,127 @@ public class LandingPad extends Block{
|
||||
configClear((LandingPadBuild build) -> build.config = null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
consume(new ConsumeLiquid(consumeLiquid, consumeLiquidAmount){
|
||||
|
||||
@Override
|
||||
public void build(Building build, Table table){
|
||||
table.add(new ReqImage(liquid.uiIcon, () -> build.liquids.get(liquid) >= amount)).size(iconMed).top().left();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float efficiency(Building build){
|
||||
return build.liquids.get(consumeLiquid) >= amount ? 1f : 0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(Stats stats){
|
||||
stats.add(Stat.input, liquid, amount, false);
|
||||
}
|
||||
}).update(false);
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBars(){
|
||||
super.setBars();
|
||||
|
||||
addLiquidBar(consumeLiquid);
|
||||
//TODO: does cooldown even need to exist?
|
||||
addBar("heat", (LandingPadBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.cooldown));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outputsItems(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void landingPadLanded(Tile tile){
|
||||
if(tile == null || !(tile.build instanceof LandingPadBuild build)) return;
|
||||
build.handleLanding();
|
||||
}
|
||||
|
||||
public class LandingPadBuild extends Building{
|
||||
public @Nullable Item config;
|
||||
//priority collisions are possible, but should be extremely rare
|
||||
public int priority = Mathf.rand.nextInt();
|
||||
public float cooldown = 0f;
|
||||
|
||||
|
||||
public void handleLanding(){
|
||||
if(!state.isCampaign() || config == null) return;
|
||||
//TODO animation, etc
|
||||
|
||||
cooldown = 1f;
|
||||
items.set(config, itemCapacity);
|
||||
liquids.remove(consumeLiquid, consumeLiquidAmount);
|
||||
for(int i = 0; i < 10; i++){
|
||||
Fx.steam.at(this);
|
||||
}
|
||||
//TODO this is a temporary effect
|
||||
Fx.shockwave.at(this);
|
||||
|
||||
state.rules.sector.info.importCooldownTimers.put(config, 0f);
|
||||
}
|
||||
|
||||
public void updateTimers(){
|
||||
if(state.isCampaign() && lastUpdateId != state.updateId){
|
||||
lastUpdateId = state.updateId;
|
||||
|
||||
float[] imports = state.rules.sector.info.getImportRates(state.getPlanet());
|
||||
|
||||
for(Item item : content.items()){
|
||||
float importedPerFrame = imports[item.id]/60f;
|
||||
if(importedPerFrame > 0f){
|
||||
float framesBetweenArrival = itemCapacity / importedPerFrame;
|
||||
|
||||
state.rules.sector.info.importCooldownTimers.increment(item, 0f, 1f / framesBetweenArrival * Time.delta);
|
||||
}
|
||||
}
|
||||
|
||||
waiting.each((item, pads) -> {
|
||||
if(pads.size > 0){
|
||||
pads.sort(p -> p.priority);
|
||||
|
||||
var first = pads.first();
|
||||
var head = pads.peek();
|
||||
|
||||
Call.landingPadLanded(first.tile);
|
||||
|
||||
|
||||
//swap priorities, moving this block to the end of the list (if there is only one block waiting, this does nothing)
|
||||
var tmp = first.priority;
|
||||
first.priority = head.priority;
|
||||
head.priority = tmp;
|
||||
|
||||
|
||||
pads.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
updateTimers();
|
||||
|
||||
if(items.total() > 0){
|
||||
dumpAccumulate(config == null || items.get(config) != items.total() ? null : config);
|
||||
}
|
||||
|
||||
if(config != null && state.isCampaign()){
|
||||
|
||||
cooldown -= delta() / cooldownTime;
|
||||
|
||||
if(cooldown <= 0f && efficiency > 0f && items.total() == 0 && state.rules.sector.info.importCooldownTimers.get(config, 0f) >= 1f){
|
||||
|
||||
//queue landing for next frame
|
||||
waiting.get(config, Seq::new).add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,6 +181,11 @@ public class LandingPad extends Block{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildConfiguration(Table table){
|
||||
ItemSelection.buildTable(LandingPad.this, table, content.items(), () -> config, this::configure, selectionRows, selectionColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return false;
|
||||
@@ -59,12 +200,16 @@ public class LandingPad extends Block{
|
||||
public void read(Reads read, byte revision){
|
||||
super.read(read, revision);
|
||||
config = TypeIO.readItem(read);
|
||||
priority = read.i();
|
||||
cooldown = read.f();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Writes write){
|
||||
super.write(write);
|
||||
TypeIO.writeItem(write, config);
|
||||
write.i(priority);
|
||||
write.f(cooldown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class LaunchPad extends Block{
|
||||
|
||||
table.row();
|
||||
table.label(() -> {
|
||||
Sector dest = state.rules.sector == null ? null : state.rules.sector.info.getRealDestination();
|
||||
Sector dest = state.rules.sector == null ? null : state.rules.sector.info.destination;
|
||||
|
||||
return Core.bundle.format("launch.destination",
|
||||
dest == null || !dest.hasBase() ? Core.bundle.get("sectors.nonelaunch") :
|
||||
@@ -161,7 +161,7 @@ public class LaunchPad extends Block{
|
||||
@Override
|
||||
public void buildConfiguration(Table table){
|
||||
//TODO: this UI should be on landing pads
|
||||
if(!state.isCampaign() || net.client() || true){
|
||||
if(!state.isCampaign() || net.client()){
|
||||
deselect();
|
||||
return;
|
||||
}
|
||||
@@ -262,27 +262,23 @@ public class LaunchPad extends Block{
|
||||
|
||||
@Override
|
||||
public void remove(){
|
||||
if(!state.isCampaign()) return;
|
||||
if(!state.isCampaign() || net.client()) return;
|
||||
|
||||
Sector destsec = state.rules.sector.info.getRealDestination();
|
||||
Sector destsec = state.rules.sector.info.destination;
|
||||
|
||||
//actually launch the items upon removal
|
||||
if(team() == state.rules.defaultTeam){
|
||||
if(destsec != null && (destsec != state.rules.sector || net.client())){
|
||||
ItemSeq dest = new ItemSeq();
|
||||
if(team() == state.rules.defaultTeam && destsec != null && destsec != state.rules.sector){
|
||||
ItemSeq dest = new ItemSeq();
|
||||
|
||||
for(ItemStack stack : stacks){
|
||||
dest.add(stack);
|
||||
for(ItemStack stack : stacks){
|
||||
dest.add(stack);
|
||||
|
||||
//update export
|
||||
state.rules.sector.info.handleItemExport(stack);
|
||||
Events.fire(new LaunchItemEvent(stack));
|
||||
}
|
||||
|
||||
if(!net.client()){
|
||||
destsec.addItems(dest);
|
||||
}
|
||||
//update export statistics
|
||||
state.rules.sector.info.handleItemExport(stack);
|
||||
Events.fire(new LaunchItemEvent(stack));
|
||||
}
|
||||
|
||||
destsec.addItems(dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ public class ItemSource extends Block{
|
||||
while(counter >= limit){
|
||||
items.set(outputItem, 1);
|
||||
dump(outputItem);
|
||||
produced(outputItem);
|
||||
items.set(outputItem, 0);
|
||||
counter -= limit;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import static mindustry.Vars.*;
|
||||
//TODO replace with ConsumeLiquids?
|
||||
public class ConsumeLiquid extends ConsumeLiquidBase{
|
||||
public final Liquid liquid;
|
||||
public boolean trigger;
|
||||
|
||||
public ConsumeLiquid(Liquid liquid, float amount){
|
||||
super(amount);
|
||||
@@ -23,10 +22,6 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
|
||||
this(null, 0f);
|
||||
}
|
||||
|
||||
public ConsumeLiquid trigger(boolean trigger){
|
||||
this.trigger = trigger;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Block block){
|
||||
@@ -44,13 +39,6 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
|
||||
build.liquids.remove(liquid, amount * build.edelta() * multiplier.get(build));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Building build){
|
||||
if(trigger){
|
||||
build.liquids.remove(liquid, amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float efficiency(Building build){
|
||||
float ed = build.edelta() * build.efficiencyScale();
|
||||
|
||||
Reference in New Issue
Block a user