Zone objective abstraction, cleanup
This commit is contained in:
@@ -965,12 +965,12 @@ public class Blocks implements ContentList{
|
||||
//region liquid
|
||||
|
||||
mechanicalPump = new Pump("mechanical-pump"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.copper, 15, Items.lead, 10));
|
||||
requirements(Category.liquid, ItemStack.with(Items.copper, 15, Items.metaglass, 10));
|
||||
pumpAmount = 0.1f;
|
||||
}};
|
||||
|
||||
rotaryPump = new Pump("rotary-pump"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.copper, 70, Items.lead, 50, Items.silicon, 20, Items.titanium, 35));
|
||||
requirements(Category.liquid, ItemStack.with(Items.copper, 70, Items.metaglass, 50, Items.silicon, 20, Items.titanium, 35));
|
||||
pumpAmount = 0.8f;
|
||||
consumes.power(0.15f);
|
||||
liquidCapacity = 30f;
|
||||
@@ -979,7 +979,7 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
thermalPump = new Pump("thermal-pump"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.copper, 80, Items.lead, 65, Items.silicon, 30, Items.titanium, 40, Items.thorium, 35));
|
||||
requirements(Category.liquid, ItemStack.with(Items.copper, 80, Items.metaglass, 70, Items.silicon, 30, Items.titanium, 40, Items.thorium, 35));
|
||||
pumpAmount = 1.5f;
|
||||
consumes.power(0.30f);
|
||||
liquidCapacity = 40f;
|
||||
@@ -993,13 +993,13 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
pulseConduit = new Conduit("pulse-conduit"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.titanium, 1, Items.metaglass, 1));
|
||||
requirements(Category.liquid, ItemStack.with(Items.titanium, 2, Items.metaglass, 1));
|
||||
liquidCapacity = 16f;
|
||||
health = 90;
|
||||
}};
|
||||
|
||||
liquidRouter = new LiquidRouter("liquid-router"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.titanium, 2, Items.metaglass, 2));
|
||||
requirements(Category.liquid, ItemStack.with(Items.graphite, 4, Items.metaglass, 2));
|
||||
liquidCapacity = 20f;
|
||||
}};
|
||||
|
||||
@@ -1011,11 +1011,11 @@ public class Blocks implements ContentList{
|
||||
}};
|
||||
|
||||
liquidJunction = new LiquidJunction("liquid-junction"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.titanium, 2, Items.metaglass, 2));
|
||||
requirements(Category.liquid, ItemStack.with(Items.graphite, 2, Items.metaglass, 2));
|
||||
}};
|
||||
|
||||
bridgeConduit = new LiquidExtendingBridge("bridge-conduit"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.titanium, 4, Items.metaglass, 4));
|
||||
requirements(Category.liquid, ItemStack.with(Items.graphite, 4, Items.metaglass, 8));
|
||||
range = 4;
|
||||
hasPower = false;
|
||||
}};
|
||||
|
||||
@@ -146,7 +146,7 @@ public class Control implements ApplicationListener, Loadable{
|
||||
});
|
||||
|
||||
Events.on(ZoneRequireCompleteEvent.class, e -> {
|
||||
ui.hudfrag.showToast(Core.bundle.format("zone.requirement.complete", state.wave, e.zone.localizedName));
|
||||
ui.hudfrag.showToast(Core.bundle.format("zone.requirements.met", e.zone.localizedName));
|
||||
});
|
||||
|
||||
Events.on(ZoneConfigureCompleteEvent.class, e -> {
|
||||
|
||||
@@ -180,6 +180,10 @@ public class Logic implements ApplicationListener{
|
||||
Effects.effect(Fx.launch, tile);
|
||||
}
|
||||
|
||||
if(world.getZone() != null){
|
||||
world.getZone().setLaunched();
|
||||
}
|
||||
|
||||
Time.runTask(30f, () -> {
|
||||
for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){
|
||||
for(Item item : content.items()){
|
||||
|
||||
12
core/src/io/anuke/mindustry/game/Objective.java
Normal file
12
core/src/io/anuke/mindustry/game/Objective.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
/** Defines a specific objective for a game. */
|
||||
public interface Objective{
|
||||
|
||||
/** @return whether this objective is met. */
|
||||
boolean complete();
|
||||
|
||||
/** @return the string displayed when this objective is completed, in imperative form.
|
||||
* e.g. when the objective is 'complete 10 waves', this would display "complete 10 waves".*/
|
||||
String display();
|
||||
}
|
||||
38
core/src/io/anuke/mindustry/game/Objectives.java
Normal file
38
core/src/io/anuke/mindustry/game/Objectives.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
/** Holds objective classes. */
|
||||
public class Objectives{
|
||||
|
||||
public static class WaveObjective implements Objective{
|
||||
public int wave;
|
||||
|
||||
public WaveObjective(int wave){
|
||||
this.wave = wave;
|
||||
}
|
||||
|
||||
protected WaveObjective(){}
|
||||
|
||||
@Override
|
||||
public boolean complete(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String display(){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LaunchObjective implements Objective{
|
||||
|
||||
@Override
|
||||
public boolean complete(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String display(){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,10 @@ public class ItemStack implements Comparable<ItemStack>{
|
||||
item = Items.copper;
|
||||
}
|
||||
|
||||
public ItemStack copy(){
|
||||
return new ItemStack(item, amount);
|
||||
}
|
||||
|
||||
public boolean equals(ItemStack other){
|
||||
return other != null && other.item == item && other.amount == amount;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.graphics.g2d.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.ArcAnnotate.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
@@ -74,7 +74,7 @@ public class Zone extends UnlockableContent{
|
||||
}
|
||||
|
||||
for(ZoneRequirement other : zoneRequirements){
|
||||
if(other.zone.bestWave() < other.wave){
|
||||
if(!other.isComplete()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,23 @@ public class Zone extends UnlockableContent{
|
||||
defaultStartingItems.each(stack -> startingItems.add(new ItemStack(stack.item, stack.amount)));
|
||||
}
|
||||
|
||||
public boolean hasLaunched(){
|
||||
return Core.settings.getBool(name + "-launched", false);
|
||||
}
|
||||
|
||||
public void setLaunched(){
|
||||
if(!hasLaunched() && getRules().attackMode){
|
||||
for(Zone zone : content.zones()){
|
||||
ZoneRequirement req = Structs.find(zone.zoneRequirements, f -> f.zone == this);
|
||||
if(req != null && req.isComplete()){
|
||||
Events.fire(new ZoneRequireCompleteEvent(zone, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
Core.settings.put(name + "-launched", true);
|
||||
data.modified();
|
||||
}
|
||||
|
||||
public void updateWave(int wave){
|
||||
int value = Core.settings.getInt(name + "-wave", 0);
|
||||
if(value < wave){
|
||||
@@ -112,7 +129,7 @@ public class Zone extends UnlockableContent{
|
||||
|
||||
for(Zone zone : content.zones()){
|
||||
ZoneRequirement req = Structs.find(zone.zoneRequirements, f -> f.zone == this);
|
||||
if(req != null && wave == req.wave + 1){
|
||||
if(req != null && wave == req.wave + 1 && req.isComplete()){
|
||||
Events.fire(new ZoneRequireCompleteEvent(zone, this));
|
||||
}
|
||||
}
|
||||
@@ -127,7 +144,8 @@ public class Zone extends UnlockableContent{
|
||||
return Core.settings.getInt(name + "-wave", 0);
|
||||
}
|
||||
|
||||
public boolean isCompleted(){
|
||||
/** @return whether initial conditions to launch are met. */
|
||||
public boolean isLaunchMet(){
|
||||
return bestWave() >= conditionWave;
|
||||
}
|
||||
|
||||
@@ -208,19 +226,33 @@ public class Zone extends UnlockableContent{
|
||||
return ContentType.zone;
|
||||
}
|
||||
|
||||
/*
|
||||
public static class ZoneRequirement{
|
||||
|
||||
public @NonNull Zone zone;
|
||||
public @NonNull int wave;
|
||||
public int wave;
|
||||
|
||||
public ZoneRequirement(Zone zone, int wave){
|
||||
this.zone = zone;
|
||||
this.wave = wave;
|
||||
}
|
||||
|
||||
public ZoneRequirement(Zone zone){
|
||||
this.zone = zone;
|
||||
}
|
||||
|
||||
protected ZoneRequirement(){
|
||||
|
||||
}
|
||||
|
||||
public boolean isComplete(){
|
||||
if(zone.getRules().attackMode){
|
||||
return zone.hasLaunched();
|
||||
}else{
|
||||
return zone.bestWave() >= wave;
|
||||
}
|
||||
}
|
||||
|
||||
public static ZoneRequirement[] with(Object... objects){
|
||||
ZoneRequirement[] out = new ZoneRequirement[objects.length / 2];
|
||||
for(int i = 0; i < objects.length; i += 2){
|
||||
@@ -228,6 +260,6 @@ public class Zone extends UnlockableContent{
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.graphics.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.game.Rules;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.ItemType;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.graphics.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
|
||||
@@ -69,13 +67,11 @@ public class CustomRulesDialog extends FloatingDialog{
|
||||
main.addButton("$configure",
|
||||
() -> loadoutDialog.show(
|
||||
Blocks.coreShard.itemCapacity,
|
||||
() -> rules.loadout,
|
||||
rules.loadout,
|
||||
() -> {
|
||||
rules.loadout.clear();
|
||||
rules.loadout.add(new ItemStack(Items.copper, 100));
|
||||
},
|
||||
() -> {}, () -> {},
|
||||
item -> item.type == ItemType.material
|
||||
}, () -> {}, () -> {}
|
||||
)).left().width(300f);
|
||||
main.row();
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ public class DeployDialog extends FloatingDialog{
|
||||
|
||||
button.defaults().colspan(2);
|
||||
button.row();
|
||||
button.add(Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
button.add(Core.bundle.format("save", color + slot.getWave()));
|
||||
button.row();
|
||||
button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime()));
|
||||
button.row();
|
||||
|
||||
@@ -2,9 +2,7 @@ package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.function.*;
|
||||
import io.anuke.arc.input.*;
|
||||
import io.anuke.arc.scene.ui.*;
|
||||
import io.anuke.arc.scene.ui.layout.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
@@ -16,10 +14,12 @@ import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class LoadoutDialog extends FloatingDialog{
|
||||
private Runnable hider;
|
||||
private Supplier<Array<ItemStack>> supplier;
|
||||
//private Supplier<Array<ItemStack>> supplier;
|
||||
private Runnable resetter;
|
||||
private Runnable updater;
|
||||
private Predicate<Item> filter;
|
||||
private Array<ItemStack> stacks = new Array<>();
|
||||
private Array<ItemStack> originalStacks = new Array<>();
|
||||
//private Predicate<Item> filter;
|
||||
private Table items;
|
||||
private int capacity;
|
||||
|
||||
@@ -33,54 +33,37 @@ public class LoadoutDialog extends FloatingDialog{
|
||||
}
|
||||
});
|
||||
|
||||
cont.add(items = new Table()).left();
|
||||
cont.pane(t -> items = t.margin(10f)).left();
|
||||
|
||||
shown(this::setup);
|
||||
hidden(() -> {
|
||||
originalStacks.selectFrom(stacks, s -> s.amount > 0);
|
||||
updater.run();
|
||||
if(hider != null){
|
||||
hider.run();
|
||||
}
|
||||
});
|
||||
|
||||
cont.row();
|
||||
buttons.addImageTextButton("$back", Icon.arrowLeft, this::hide).size(210f, 64f);
|
||||
|
||||
cont.addButton("$add", () -> {
|
||||
FloatingDialog dialog = new FloatingDialog("");
|
||||
dialog.setFillParent(false);
|
||||
for(Item item : content.items().select(item -> filter.test(item) && item.type == ItemType.material && supplier.get().find(stack -> stack.item == item) == null)){
|
||||
TextButton button = dialog.cont.addButton("", Styles.cleart, () -> {
|
||||
dialog.hide();
|
||||
supplier.get().add(new ItemStack(item, 0));
|
||||
updater.run();
|
||||
setup();
|
||||
}).size(300f, 36f).get();
|
||||
button.clearChildren();
|
||||
button.left();
|
||||
button.addImage(item.icon(Cicon.small)).size(8 * 3).pad(4);
|
||||
button.add(item.localizedName);
|
||||
dialog.cont.row();
|
||||
}
|
||||
dialog.show();
|
||||
}).size(100f, 40).left().disabled(b -> !content.items().contains(item -> filter.test(item) && !supplier.get().contains(stack -> stack.item == item)));
|
||||
|
||||
cont.row();
|
||||
cont.addButton("$settings.reset", () -> {
|
||||
buttons.addImageTextButton("$settings.reset", Icon.refreshSmall, () -> {
|
||||
resetter.run();
|
||||
updater.run();
|
||||
setup();
|
||||
}).size(210f, 64f);
|
||||
|
||||
cont.row();
|
||||
cont.addImageTextButton("$back", Icon.arrowLeft, this::hide).size(210f, 64f);
|
||||
}
|
||||
|
||||
public void show(int capacity, Supplier<Array<ItemStack>> supplier, Runnable reseter, Runnable updater, Runnable hider, Predicate<Item> filter){
|
||||
public void show(int capacity, Array<ItemStack> stacks, Runnable reseter, Runnable updater, Runnable hider){
|
||||
this.originalStacks = stacks;
|
||||
this.stacks = stacks.map(ItemStack::copy);
|
||||
this.stacks.addAll(content.items().select(i -> i.type == ItemType.material &&
|
||||
!stacks.contains(stack -> stack.item == i)).map(i -> new ItemStack(i, 0)));
|
||||
this.stacks.sort(Structs.comparingInt(s -> s.item.id));
|
||||
this.resetter = reseter;
|
||||
this.supplier = supplier;
|
||||
this.updater = updater;
|
||||
this.capacity = capacity;
|
||||
this.hider = hider;
|
||||
this.filter = filter;
|
||||
//this.filter = filter;
|
||||
show();
|
||||
}
|
||||
|
||||
@@ -88,41 +71,54 @@ public class LoadoutDialog extends FloatingDialog{
|
||||
items.clearChildren();
|
||||
items.left();
|
||||
float bsize = 40f;
|
||||
int step = 50;
|
||||
|
||||
for(ItemStack stack : supplier.get()){
|
||||
items.addButton("x", Styles.clearPartialt, () -> {
|
||||
supplier.get().remove(stack);
|
||||
updater.run();
|
||||
setup();
|
||||
}).size(bsize);
|
||||
int i = 0;
|
||||
|
||||
items.addButton("-", Styles.clearPartialt, () -> {
|
||||
stack.amount = Math.max(stack.amount - step, 0);
|
||||
updater.run();
|
||||
}).size(bsize);
|
||||
for(ItemStack stack : stacks){
|
||||
items.table(Tex.pane, t -> {
|
||||
t.margin(4).marginRight(8).left();
|
||||
t.addButton("-", Styles.cleart, () -> {
|
||||
stack.amount = Math.max(stack.amount - step(stack.amount), 0);
|
||||
updater.run();
|
||||
}).size(bsize);
|
||||
|
||||
items.addButton("+", Styles.clearPartialt, () -> {
|
||||
stack.amount = Math.min(stack.amount + step, capacity);
|
||||
updater.run();
|
||||
}).size(bsize);
|
||||
t.addButton("+", Styles.cleart, () -> {
|
||||
stack.amount = Math.min(stack.amount + step(stack.amount), capacity);
|
||||
updater.run();
|
||||
}).size(bsize);
|
||||
|
||||
items.addImageButton(Icon.pencilSmaller, Styles.clearPartial2i, () -> ui.showTextInput("$configure", stack.item.localizedName, 10, stack.amount + "", true, str -> {
|
||||
if(Strings.canParsePostiveInt(str)){
|
||||
int amount = Strings.parseInt(str);
|
||||
if(amount >= 0 && amount <= capacity){
|
||||
stack.amount = amount;
|
||||
updater.run();
|
||||
return;
|
||||
t.addImageButton(Icon.pencilSmaller, Styles.cleari, () -> ui.showTextInput("$configure", stack.item.localizedName, 10, stack.amount + "", true, str -> {
|
||||
if(Strings.canParsePostiveInt(str)){
|
||||
int amount = Strings.parseInt(str);
|
||||
if(amount >= 0 && amount <= capacity){
|
||||
stack.amount = amount;
|
||||
updater.run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ui.showInfo(Core.bundle.format("configure.invalid", capacity));
|
||||
})).size(bsize);
|
||||
ui.showInfo(Core.bundle.format("configure.invalid", capacity));
|
||||
})).size(bsize);
|
||||
|
||||
items.addImage(stack.item.icon(Cicon.small)).size(8 * 3).padRight(4).padLeft(4);
|
||||
items.label(() -> stack.amount + "").left();
|
||||
t.addImage(stack.item.icon(Cicon.small)).size(8 * 3).padRight(4).padLeft(4);
|
||||
t.label(() -> stack.amount + "").left().width(90f);
|
||||
}).pad(2).left().fillX();
|
||||
|
||||
items.row();
|
||||
|
||||
if(++i % 2 == 0 || (mobile && Core.graphics.isPortrait())){
|
||||
items.row();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int step(int amount){
|
||||
if(amount < 1000){
|
||||
return 100;
|
||||
}else if(amount < 2000){
|
||||
return 200;
|
||||
}else if(amount < 5000){
|
||||
return 500;
|
||||
}else{
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,12 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
req.table(r -> {
|
||||
r.add("$complete").colspan(2).left();
|
||||
r.row();
|
||||
for(ZoneRequirement other : zone.zoneRequirements){
|
||||
for(ZoneRequirement zreq : zone.zoneRequirements){
|
||||
r.addImage(Icon.terrain).padRight(4);
|
||||
r.add(Core.bundle.format("zone.requirement", other.wave, other.zone.localizedName())).color(Color.lightGray);
|
||||
r.addImage(other.zone.bestWave() >= other.wave ? Icon.checkSmall : Icon.cancelSmall, other.zone.bestWave() >= other.wave ? Color.lightGray : Color.scarlet).padLeft(3);
|
||||
r.add(!zreq.zone.getRules().attackMode ?
|
||||
Core.bundle.format("zone.requirement.wave", zreq.wave, zreq.zone.localizedName()) :
|
||||
Core.bundle.format("zone.requirement", zreq.zone.localizedName)).color(Color.lightGray);
|
||||
r.addImage(zreq.isComplete() ? Icon.checkSmall : Icon.cancelSmall, zreq.isComplete() ? Color.lightGray : Color.scarlet).padLeft(3);
|
||||
r.row();
|
||||
}
|
||||
});
|
||||
@@ -82,8 +84,8 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
r.add("$research.list").colspan(2).left();
|
||||
r.row();
|
||||
for(Block block : zone.blockRequirements){
|
||||
r.addImage(block.icon(Cicon.small)).size(8 * 3).padRight(4);
|
||||
r.add(block.localizedName).color(Color.lightGray);
|
||||
r.addImage(block.icon(Cicon.small)).size(8 * 3).padRight(5);
|
||||
r.add(block.localizedName).color(Color.lightGray).left();
|
||||
r.addImage(data.isUnlocked(block) ? Icon.checkSmall : Icon.cancelSmall, data.isUnlocked(block) ? Color.lightGray : Color.scarlet).padLeft(3);
|
||||
r.row();
|
||||
}
|
||||
@@ -136,7 +138,7 @@ public class ZoneInfoDialog extends FloatingDialog{
|
||||
cont.row();
|
||||
|
||||
cont.addButton(zone.canConfigure() ? "$configure" : Core.bundle.format("configure.locked", zone.configureWave),
|
||||
() -> loadout.show(zone.loadout.core().itemCapacity, zone::getStartingItems, zone::resetStartingItems, zone::updateLaunchCost, rebuildItems, item -> data.getItem(item) > 0 && item.type == ItemType.material)
|
||||
() -> loadout.show(zone.loadout.core().itemCapacity, zone.getStartingItems(), zone::resetStartingItems, zone::updateLaunchCost, rebuildItems)
|
||||
).fillX().pad(3).disabled(b -> !zone.canConfigure());
|
||||
}
|
||||
cont.marginRight(12f);
|
||||
|
||||
Reference in New Issue
Block a user