Better launch selection

This commit is contained in:
Anuken 2020-10-18 18:34:19 -04:00
parent 97fd9abd8c
commit dac236b0e9
9 changed files with 104 additions and 82 deletions

View File

@ -9,7 +9,6 @@ import arc.math.*;
import arc.scene.ui.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.audio.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
@ -25,7 +24,6 @@ import mindustry.maps.Map;
import mindustry.type.*;
import mindustry.ui.dialogs.*;
import mindustry.world.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import java.io.*;
import java.text.*;
@ -250,19 +248,6 @@ public class Control implements ApplicationListener, Loadable{
});
}
//TODO move
public void handleLaunch(CoreBuild tile){
LaunchCorec ent = LaunchCore.create();
ent.set(tile);
ent.block(Blocks.coreShard);
ent.lifetime(Vars.launchDuration);
ent.add();
//remove schematic requirements from core
tile.items.remove(universe.getLastLoadout().requirements());
tile.items.remove(universe.getLaunchResources());
}
public void playSector(Sector sector){
playSector(sector, sector);
}

View File

@ -28,7 +28,7 @@ public class SectorInfo{
/** Items stored in all cores. */
public ItemSeq items = new ItemSeq();
/** The best available core type. */
public Block bestCoreType = Blocks.air;
public Block bestCoreType = Blocks.coreShard;
/** Max storage capacity. */
public int storageCapacity = 0;
/** Whether a core is available here. */

View File

@ -352,10 +352,6 @@ public class DesktopInput extends InputHandler{
table.button(Icon.map, Styles.clearPartiali, () -> {
ui.planet.show();
}).visible(() -> state.isCampaign()).tooltip("@planetmap");
table.button(Icon.up, Styles.clearPartiali, () -> {
ui.planet.showLaunch(state.getSector(), player.team().core());
}).visible(() -> state.isCampaign()).tooltip("@launchcore").disabled(b -> player.team().core() == null);
}
void pollInput(){

View File

@ -21,6 +21,13 @@ public class ItemSeq implements Iterable<ItemStack>, Serializable{
stacks.each(this::add);
}
public ItemSeq copy(){
ItemSeq out = new ItemSeq();
out.total = total;
System.arraycopy(values, 0, out.values, 0, values.length);
return out;
}
public void each(ItemConsumer cons){
for(int i = 0; i < values.length; i++){
if(values[i] != 0){
@ -46,6 +53,19 @@ public class ItemSeq implements Iterable<ItemStack>, Serializable{
return values[item.id] > 0;
}
public boolean has(ItemSeq seq){
for(int i = 0; i < values.length; i++){
if(seq.values[i] > values[i]){
return false;
}
}
return true;
}
public boolean has(Item item, int amount){
return values[item.id] >= amount;
}
public int get(Item item){
return values[item.id];
}

View File

@ -40,9 +40,22 @@ public class Sector{
this.id = tile.id;
}
/** @return a copy of the items in this sector - may be core items, or stored data. */
public ItemSeq getItems(){
if(isBeingPlayed()){
ItemSeq out = new ItemSeq();
if(state.rules.defaultTeam.core() != null) out.add(state.rules.defaultTeam.core().items);
return out;
}else{
return info.items;
}
}
public Seq<Sector> near(){
tmpSeq1.clear();
near(tmpSeq1::add);
for(Ptile tile : tile.tiles){
tmpSeq1.add(planet.getSector(tile));
}
return tmpSeq1;
}
@ -131,6 +144,12 @@ public class Sector{
removeItem(item, -amount);
}
public void removeItems(ItemSeq items){
ItemSeq copy = items.copy();
copy.each((i, a) -> copy.set(i, -a));
addItems(copy);
}
public void removeItem(Item item, int amount){
ItemSeq seq = new ItemSeq();
seq.add(item, -amount);

View File

@ -30,7 +30,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
super("@configure");
}
public void show(CoreBlock core, Building build, Runnable confirm){
public void show(CoreBlock core, Sector sector, Runnable confirm){
cont.clear();
buttons.clear();
@ -43,12 +43,14 @@ public class LaunchLoadoutDialog extends BaseDialog{
}
});
ItemSeq sitems = sector.getItems();
//updates sum requirements
Runnable update = () -> {
total.clear();
selected.requirements().each(total::add);
universe.getLaunchResources().each(total::add);
valid = build.items.has(total);
valid = sitems.has(total);
};
Cons<Table> rebuild = table -> {
@ -65,8 +67,8 @@ public class LaunchLoadoutDialog extends BaseDialog{
String amountStr = "[lightgray]" + (al + " + [accent]" + as + "[lightgray]");
table.add(
build.items.has(s.item, s.amount) ? amountStr :
"[scarlet]" + (Math.min(build.items.get(s.item), s.amount) + "[lightgray]/" + amountStr)).padLeft(2).left().padRight(4);
sitems.has(s.item, s.amount) ? amountStr :
"[scarlet]" + (Math.min(sitems.get(s.item), s.amount) + "[lightgray]/" + amountStr)).padLeft(2).left().padRight(4);
if(++i % 4 == 0){
table.row();
@ -108,7 +110,7 @@ public class LaunchLoadoutDialog extends BaseDialog{
selected = s;
update.run();
rebuildItems.run();
}).group(group).pad(4).disabled(!build.items.has(s.requirements())).checked(s == selected).size(200f);
}).group(group).pad(4).disabled(!sitems.has(s.requirements())).checked(s == selected).size(200f);
if(++i % cols == 0){
t.row();

View File

@ -78,10 +78,7 @@ public class PausedDialog extends BaseDialog{
cont.buttonRow("@load", Icon.download, load::show).disabled(b -> net.active());
}else if(state.isCampaign()){
cont.buttonRow("@launchcore", Icon.up, () -> {
hide();
ui.planet.showLaunch(state.getSector(), player.team().core());
}).disabled(b -> player.team().core() == null || net.client());
cont.buttonRow("@research", Icon.tree, ui.research::show);
cont.row();
@ -93,11 +90,7 @@ public class PausedDialog extends BaseDialog{
cont.row();
}
if(state.isCampaign() && net.active()){
cont.buttonRow("@research", Icon.tree, ui.research::show);
}else{
cont.buttonRow("@hostserver.mobile", Icon.host, ui.host::show).disabled(b -> net.active());
}
cont.buttonRow("@hostserver.mobile", Icon.host, ui.host::show).disabled(b -> net.active());
cont.buttonRow("@quit", Icon.exit, this::showQuitConfirm).update(s -> {
s.setText(control.saves.getCurrent() != null && control.saves.getCurrent().isAutosave() ? "@save.quit" : "@quit");

View File

@ -13,6 +13,7 @@ import arc.scene.event.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.game.*;
@ -22,7 +23,6 @@ import mindustry.graphics.g3d.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import static mindustry.Vars.*;
import static mindustry.graphics.g3d.PlanetRenderer.*;
@ -40,7 +40,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
public int launchRange;
public float zoom = 1f, selectAlpha = 1f;
public @Nullable Sector selected, hovered, launchSector;
public CoreBuild launcher;
public Mode mode = look;
public boolean launching;
public Cons<Sector> listener = s -> {};
@ -91,9 +90,16 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
mode = look;
selected = hovered = launchSector = null;
launching = false;
zoom = 1f;
planets.zoom = 2f;
selectAlpha = 0f;
launchSector = state.getSector();
if(planets.planet.getLastSector() != null){
lookAt(planets.planet.getLastSector());
}
return super.show();
}
@ -115,37 +121,33 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
super.show();
}
public void showLaunch(Sector sector, CoreBuild launcher){
if(launcher == null) return;
this.launcher = launcher;
selected = null;
hovered = null;
launching = false;
//update view to sector
lookAt(sector);
zoom = 1f;
planets.zoom = 2f;
selectAlpha = 0f;
launchRange = ((CoreBlock)launcher.block).launchRange;
launchSector = sector;
mode = launch;
super.show();
}
private void lookAt(Sector sector){
void lookAt(Sector sector){
planets.camPos.set(Tmp.v33.set(sector.tile.v).rotate(Vec3.Y, -sector.planet.getRotation()));
}
boolean canSelect(Sector sector){
if(mode == select) return sector.hasBase();
return mode == launch &&
(sector.tile.v.within(launchSector.tile.v, (launchRange + 0.5f) * planets.planet.sectorApproxRadius*2) //within range
|| (sector.preset != null && sector.preset.unlocked())); //is an unlocked preset
return sector.near().contains(Sector::hasBase)//(sector.tile.v.within(launchSector.tile.v, (launchRange + 0.5f) * planets.planet.sectorApproxRadius*2) //within range
|| (sector.preset != null && sector.preset.unlocked()); //is an unlocked preset
}
Sector findLauncher(Sector to){
//directly nearby.
if(to.near().contains(launchSector)) return launchSector;
Sector launchFrom = launchSector;
if(launchFrom == null){
//TODO pick one with the most resources
launchFrom = to.near().find(Sector::hasBase);
if(launchFrom == null && to.preset != null){
if(launchSector != null) return launchSector;
launchFrom = planets.planet.sectors.min(s -> !s.hasBase() ? Float.MAX_VALUE : s.tile.v.dst2(to.tile.v));
if(!launchFrom.hasBase()) launchFrom = null;
}
}
return launchFrom;
}
@Override
@ -157,9 +159,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
if(selectAlpha > 0.01f){
if(canSelect(sec) || sec.unlocked()){
if(sec.baseCoverage > 0){
planets.fill(sec, Tmp.c1.set(Team.crux.color).a(0.5f * sec.baseCoverage * selectAlpha), -0.002f);
}
//TODO remove completely?
//if(sec.baseCoverage > 0){
//planets.fill(sec, Tmp.c1.set(Team.crux.color).a(0.5f * sec.baseCoverage * selectAlpha), -0.002f);
//}
Color color =
sec.hasBase() ? Team.sharded.color :
@ -177,8 +180,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
}
}
if(launchSector != null){
planets.fill(launchSector, hoverColor, -0.001f);
Sector current = state.getSector() != null && state.getSector().isBeingPlayed() ? state.getSector() : null;
if(current != null){
planets.fill(current, hoverColor, -0.001f);
}
//draw hover border
@ -195,9 +200,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
planets.batch.flush(Gl.triangles);
if(mode == launch || mode == select){
if(hovered != launchSector && hovered != null && canSelect(hovered)){
planets.drawArc(planet, launchSector.tile.v, hovered.tile.v);
if(hovered != null && !hovered.hasBase()){
Sector launchFrom = findLauncher(hovered);
if(launchFrom != null && hovered != launchFrom && canSelect(hovered)){
planets.drawArc(planet, launchFrom.tile.v, hovered.tile.v);
}
}
@ -244,7 +250,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
addListener(new ElementGestureListener(){
@Override
public void tap(InputEvent event, float x, float y, int count, KeyCode button){
if(hovered != null && ((mode == launch ? canSelect(hovered) && hovered != launchSector : hovered.unlocked()) || debugSelect)){
if(hovered != null && ((mode == look ? canSelect(hovered) && hovered != launchSector : hovered.unlocked()) || debugSelect)){
selected = hovered;
}
@ -263,9 +269,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
},
new Table(t -> {
t.touchable = Touchable.disabled;
//TODO localize
t.top();
t.label(() -> mode == select ? "@sectors.select" : mode == launch ? "Select Launch Sector" : "").style(Styles.outlineLabel).color(Pal.accent);
t.label(() -> mode == select ? "@sectors.select" : "").style(Styles.outlineLabel).color(Pal.accent);
}),
new Table(t -> {
t.right();
@ -322,7 +327,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
stable.toFront();
//smooth camera toward the sector
if(mode == launch && launching){
if(mode == look && launching){
float len = planets.camPos.len();
planets.camPos.slerp(Tmp.v31.set(selected.tile.v).rotate(Vec3.Y,-selected.planet.getRotation()).setLength(len), 0.1f);
}
@ -453,16 +458,20 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
}
}
if(mode == launch && !sector.hasBase()){
Sector current = state.rules.sector;
if(mode == look && !sector.hasBase()){
shouldHide = false;
loadouts.show((CoreBlock)launcher.block, launcher, () -> {
control.handleLaunch(launcher);
Sector from = findLauncher(sector);
CoreBlock block = from.info.bestCoreType instanceof CoreBlock b ? b : (CoreBlock)Blocks.coreShard;
loadouts.show(block, from, () -> {
from.removeItems(universe.getLastLoadout().requirements());
from.removeItems(universe.getLaunchResources());
launching = true;
zoom = 0.5f;
ui.hudfrag.showLaunchDirect();
Time.runTask(launchDuration, () -> control.playSector(current, sector));
Time.runTask(launchDuration, () -> control.playSector(from, sector));
});
}else if(mode == select){
listener.get(sector);
@ -500,8 +509,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
public enum Mode{
/** Look around for existing sectors. Can only deploy. */
look,
/** Launch to a new location. */
launch,
/** Select a sector for some purpose. */
select
}

View File

@ -45,7 +45,7 @@ public class Fracker extends SolidPump{
Draw.rect(region, x, y);
super.drawCracks();
Drawf.liquid(liquidRegion, x, y, liquids.total() / liquidCapacity, result.color);
Drawf.liquid(liquidRegion, x, y, liquids.get(result) / liquidCapacity, result.color);
Draw.rect(rotatorRegion, x, y, pumpTime);
Draw.rect(topRegion, x, y);