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; package mindustry.world.blocks.campaign;
import arc.*; import arc.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
@@ -62,8 +64,16 @@ public class LandingPad extends Block{
emitLight = true; emitLight = true;
lightRadius = 90f; lightRadius = 90f;
config(Item.class, (LandingPadBuild build, Item item) -> build.config = item); config(Item.class, (LandingPadBuild build, Item item) -> {
configClear((LandingPadBuild build) -> build.config = null); if(!accessible()) return;
build.config = item;
});
configClear((LandingPadBuild build) -> {
if(!accessible()) return;
build.config = null;
});
} }
@Override @Override
@@ -109,6 +119,10 @@ public class LandingPad extends Block{
build.handleLanding(); build.handleLanding();
} }
public boolean accessible(){
return state.rules.editor || state.rules.allowEditWorldProcessors || state.isCampaign();
}
public class LandingPadBuild extends Building{ public class LandingPadBuild extends Building{
public @Nullable Item config; public @Nullable Item config;
//priority collisions are possible, but should be extremely rare //priority collisions are possible, but should be extremely rare
@@ -120,14 +134,16 @@ public class LandingPad extends Block{
public float liquidRemoved; public float liquidRemoved;
public void handleLanding(){ public void handleLanding(){
if(!state.isCampaign() || config == null) return; if(config == null) return;
cooldown = 1f; cooldown = 1f;
arriving = config; arriving = config;
arrivingTimer = 0f; arrivingTimer = 0f;
liquidRemoved = 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(){ public void updateTimers(){
@@ -276,7 +292,9 @@ public class LandingPad extends Block{
Effect.shake(3f, 3f, this); Effect.shake(3f, 3f, this);
items.set(arriving, itemCapacity); items.set(arriving, itemCapacity);
state.getSector().info.handleItemImport(arriving, itemCapacity); if(!isFake()){
state.getSector().info.handleItemImport(arriving, itemCapacity);
}
arriving = null; arriving = null;
arrivingTimer = 0f; arrivingTimer = 0f;
@@ -292,29 +310,70 @@ public class LandingPad extends Block{
cooldown = Mathf.clamp(cooldown); 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 if(isFake()){
waiting.get(config, Seq::new).add(this); //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 @Override
public boolean canDump(Building to, Item item){ 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. //hack: canDump is only ever called right before item offload, so count the item as "produced" before that.
//TODO: is this necessary?
produced(item); produced(item);
return true; 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 @Override
public void buildConfiguration(Table table){ public void buildConfiguration(Table table){
ItemSelection.buildTable(LandingPad.this, table, content.items(), () -> config, this::configure, selectionRows, selectionColumns); ItemSelection.buildTable(LandingPad.this, table, content.items(), () -> config, this::configure, selectionRows, selectionColumns);
if(!net.client()){ if(!net.client() && !isFake()){
table.row(); table.row();
table.table(t -> { table.table(t -> {
@@ -340,11 +399,11 @@ public class LandingPad extends Block{
public void display(Table table){ public void display(Table table){
super.display(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.row();
table.label(() -> { table.label(() -> {
if(!state.isCampaign()) return ""; if(!state.isCampaign() || isFake()) return "";
if(state.getPlanet().campaignRules.legacyLaunchPads){ if(state.getPlanet().campaignRules.legacyLaunchPads){
return Core.bundle.get("landingpad.legacy.disabled"); return Core.bundle.get("landingpad.legacy.disabled");

View File

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