Allow launch/landing pads outside of campaign as voids/sources

This commit is contained in:
Anuken
2025-02-03 21:55:33 -05:00
parent 0afa47c18d
commit 9f03050d04
2 changed files with 77 additions and 17 deletions

View File

@@ -1,6 +1,8 @@
package mindustry.world.blocks.campaign;
import arc.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
@@ -62,8 +64,16 @@ public class LandingPad extends Block{
emitLight = true;
lightRadius = 90f;
config(Item.class, (LandingPadBuild build, Item item) -> build.config = item);
configClear((LandingPadBuild build) -> build.config = null);
config(Item.class, (LandingPadBuild build, Item item) -> {
if(!accessible()) return;
build.config = item;
});
configClear((LandingPadBuild build) -> {
if(!accessible()) return;
build.config = null;
});
}
@Override
@@ -109,6 +119,10 @@ public class LandingPad extends Block{
build.handleLanding();
}
public boolean accessible(){
return state.rules.editor || state.rules.allowEditWorldProcessors || state.isCampaign();
}
public class LandingPadBuild extends Building{
public @Nullable Item config;
//priority collisions are possible, but should be extremely rare
@@ -120,14 +134,16 @@ public class LandingPad extends Block{
public float liquidRemoved;
public void handleLanding(){
if(!state.isCampaign() || config == null) return;
if(config == null) return;
cooldown = 1f;
arriving = config;
arrivingTimer = 0f;
liquidRemoved = 0f;
state.rules.sector.info.importCooldownTimers.put(config, 0f);
if(state.isCampaign() && !isFake()){
state.rules.sector.info.importCooldownTimers.put(config, 0f);
}
}
public void updateTimers(){
@@ -276,7 +292,9 @@ public class LandingPad extends Block{
Effect.shake(3f, 3f, this);
items.set(arriving, itemCapacity);
state.getSector().info.handleItemImport(arriving, itemCapacity);
if(!isFake()){
state.getSector().info.handleItemImport(arriving, itemCapacity);
}
arriving = null;
arrivingTimer = 0f;
@@ -292,29 +310,70 @@ public class LandingPad extends Block{
cooldown = Mathf.clamp(cooldown);
}
if(config != null && state.isCampaign() && !state.getPlanet().campaignRules.legacyLaunchPads){
if(config != null && (isFake() || (state.isCampaign() && !state.getPlanet().campaignRules.legacyLaunchPads))){
if(cooldown <= 0f && efficiency > 0f && items.total() == 0 && state.rules.sector.info.getImportRate(state.getPlanet(), config) > 0f && state.rules.sector.info.importCooldownTimers.get(config, 0f) >= 1f){
if(cooldown <= 0f && efficiency > 0f && items.total() == 0 && (isFake() || (state.rules.sector.info.getImportRate(state.getPlanet(), config) > 0f && state.rules.sector.info.importCooldownTimers.get(config, 0f) >= 1f))){
//queue landing for next frame
waiting.get(config, Seq::new).add(this);
if(isFake()){
//there is no queue for enemy team blocks, it's all fake
Call.landingPadLanded(tile);
}else{
//queue landing for next frame
waiting.get(config, Seq::new).add(this);
}
}
}
}
/** @return whether this pad should receive items forever, essentially acting as an item source for maps. */
public boolean isFake(){
return team != state.rules.defaultTeam || !state.isCampaign();
}
@Override
public boolean canDump(Building to, Item item){
//hack: canDump is only ever called right before item offload, so count the item as "produced" before that.
//TODO: is this necessary?
produced(item);
return true;
}
@Override
public void drawSelect(){
if(config != null){
float dx = x - size * tilesize/2f, dy = y + size * tilesize/2f, s = iconSmall / 4f;
Draw.mixcol(Color.darkGray, 1f);
Draw.rect(config.fullIcon, dx, dy - 1, s, s);
Draw.reset();
Draw.rect(config.fullIcon, dx, dy, s, s);
}
}
@Override
public Cursor getCursor(){
return !accessible() ? SystemCursor.arrow : super.getCursor();
}
@Override
public boolean shouldShowConfigure(Player player){
return accessible();
}
@Override
public boolean onConfigureBuildTapped(Building other){
if(this == other || !accessible()){
deselect();
return false;
}
return super.onConfigureBuildTapped(other);
}
@Override
public void buildConfiguration(Table table){
ItemSelection.buildTable(LandingPad.this, table, content.items(), () -> config, this::configure, selectionRows, selectionColumns);
if(!net.client()){
if(!net.client() && !isFake()){
table.row();
table.table(t -> {
@@ -340,11 +399,11 @@ public class LandingPad extends Block{
public void display(Table table){
super.display(table);
if(!state.isCampaign() || net.client() || team != player.team()) return;
if(!state.isCampaign() || net.client() || team != player.team() || isFake()) return;
table.row();
table.label(() -> {
if(!state.isCampaign()) return "";
if(!state.isCampaign() || isFake()) return "";
if(state.getPlanet().campaignRules.legacyLaunchPads){
return Core.bundle.get("landingpad.legacy.disabled");

View File

@@ -104,8 +104,6 @@ public class LaunchPad extends Block{
super.draw();
if(!state.isCampaign()) return;
if(lightRegion.found()){
Draw.color(lightColor);
float progress = Math.min((float)items.total() / itemCapacity, launchCounter / launchTime);
@@ -136,7 +134,6 @@ public class LaunchPad extends Block{
@Override
public void updateTile(){
if(!state.isCampaign()) return;
//increment launchCounter then launch when full and base conditions are met
if((launchCounter += edelta()) >= launchTime && items.total() >= itemCapacity){
@@ -172,9 +169,13 @@ public class LaunchPad extends Block{
}).pad(4).wrap().width(200f).left();
}
@Override
public boolean shouldShowConfigure(Player player){
return state.isCampaign();
}
@Override
public void buildConfiguration(Table table){
//TODO: this UI should be on landing pads
if(!state.isCampaign() || net.client()){
deselect();
return;