Cleanup, bugfixes

This commit is contained in:
Anuken 2019-10-05 15:51:29 -04:00
parent e5c7d5dd2f
commit 4b99f7c819
17 changed files with 356 additions and 242 deletions

View File

@ -45,7 +45,6 @@ database = Core Database
savegame = Save Game savegame = Save Game
loadgame = Load Game loadgame = Load Game
joingame = Join Game joingame = Join Game
addplayers = Add/Remove Players
customgame = Custom Game customgame = Custom Game
newgame = New Game newgame = New Game
none = <none> none = <none>
@ -164,7 +163,6 @@ server.port = Port:
server.addressinuse = Address already in use! server.addressinuse = Address already in use!
server.invalidport = Invalid port number! server.invalidport = Invalid port number!
server.error = [crimson]Error hosting server. server.error = [crimson]Error hosting server.
save.old = This save is for an older version of the game, and can no longer be used.\n\n[lightgray]Save backwards compatibility will be implemented in the full 4.0 release.
save.new = New Save save.new = New Save
save.overwrite = Are you sure you want to overwrite\nthis save slot? save.overwrite = Are you sure you want to overwrite\nthis save slot?
overwrite = Overwrite overwrite = Overwrite
@ -378,7 +376,6 @@ campaign = Campaign
load = Load load = Load
save = Save save = Save
fps = FPS: {0} fps = FPS: {0}
tps = TPS: {0}
ping = Ping: {0}ms ping = Ping: {0}ms
language.restart = Please restart your game for the language settings to take effect. language.restart = Please restart your game for the language settings to take effect.
settings = Settings settings = Settings
@ -392,8 +389,9 @@ abandon = Abandon
abandon.text = This zone and all its resources will be lost to the enemy. abandon.text = This zone and all its resources will be lost to the enemy.
locked = Locked locked = Locked
complete = [lightgray]Complete: complete = [lightgray]Complete:
zone.requirement.wave = Wave {0} in {1} requirement.wave = Reach Wave {0} in {1}
zone.requirement = Destroy core: {0} requirement.core = Destroy Enemy Core in {0}
requirement.unlock = Unlock {0}
resume = Resume Zone:\n[lightgray]{0} resume = Resume Zone:\n[lightgray]{0}
bestwave = [lightgray]Best Wave: {0} bestwave = [lightgray]Best Wave: {0}
launch = < LAUNCH > launch = < LAUNCH >
@ -406,11 +404,11 @@ uncover = Uncover
configure = Configure Loadout configure = Configure Loadout
bannedblocks = Banned Blocks bannedblocks = Banned Blocks
addall = Add All addall = Add All
configure.locked = [lightgray]Unlock configuring loadout: Wave {0}. configure.locked = [lightgray]Unlock configuring loadout: {0}.
configure.invalid = Amount must be a number between 0 and {0}. configure.invalid = Amount must be a number between 0 and {0}.
zone.unlocked = [lightgray]{0} unlocked. zone.unlocked = [lightgray]{0} unlocked.
zone.requirements.met = {0}: zone requirements met. zone.requirement.complete = Requirement for {0} completed:[lightgray]\n{1}
zone.config.complete = Wave {0} reached:\nLoadout config unlocked. zone.config.unlocked = Loadout unlocked:[lightgray]\n{0}
zone.resources = [lightgray]Resources Detected: zone.resources = [lightgray]Resources Detected:
zone.objective = [lightgray]Objective: [accent]{0} zone.objective = [lightgray]Objective: [accent]{0}
zone.objective.survival = Survive zone.objective.survival = Survive
@ -471,12 +469,13 @@ settings.cleardata = Clear Game Data...
settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone!
settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit.
paused = [accent]< Paused > paused = [accent]< Paused >
clear = Clear
banned = [scarlet]Banned
yes = Yes yes = Yes
no = No no = No
info.title = Info info.title = Info
error.title = [crimson]An error has occured error.title = [crimson]An error has occured
error.crashtitle = An error has occured error.crashtitle = An error has occured
attackpvponly = [scarlet]Only available in Attack/PvP modes
blocks.input = Input blocks.input = Input
blocks.output = Output blocks.output = Output
blocks.booster = Booster blocks.booster = Booster

View File

@ -1,13 +1,15 @@
package io.anuke.mindustry.content; package io.anuke.mindustry.content;
import io.anuke.arc.collection.Array; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.Objectives.*;
import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.maps.generators.*;
import io.anuke.mindustry.maps.generators.MapGenerator; import io.anuke.mindustry.maps.generators.MapGenerator.*;
import io.anuke.mindustry.maps.generators.MapGenerator.Decoration; import io.anuke.mindustry.maps.zonegen.*;
import io.anuke.mindustry.maps.zonegen.DesertWastesGenerator;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block;
import static io.anuke.arc.collection.Array.with;
import static io.anuke.mindustry.content.Items.*;
import static io.anuke.mindustry.type.ItemStack.list;
public class Zones implements ContentList{ public class Zones implements ContentList{
public static Zone public static Zone
@ -20,28 +22,26 @@ public class Zones implements ContentList{
public void load(){ public void load(){
groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{ groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{
baseLaunchCost = ItemStack.with(Items.copper, -60); baseLaunchCost = list(copper, -60);
startingItems = ItemStack.list(Items.copper, 60); startingItems = list(copper, 60);
alwaysUnlocked = true; alwaysUnlocked = true;
conditionWave = 5; conditionWave = 5;
launchPeriod = 5; launchPeriod = 5;
resources = new Item[]{Items.copper, Items.scrap, Items.lead}; resources = with(copper, scrap, lead);
}}; }};
desertWastes = new Zone("desertWastes", new DesertWastesGenerator(260, 260)){{ desertWastes = new Zone("desertWastes", new DesertWastesGenerator(260, 260)){{
startingItems = ItemStack.list(Items.copper, 120); startingItems = list(copper, 120);
conditionWave = 20; conditionWave = 20;
launchPeriod = 10; launchPeriod = 10;
loadout = Loadouts.advancedShard; loadout = Loadouts.advancedShard;
zoneRequirements = ZoneRequirement.with(groundZero, 20); resources = with(copper, lead, coal, sand);
blockRequirements = new Block[]{Blocks.combustionGenerator};
resources = new Item[]{Items.copper, Items.lead, Items.coal, Items.sand};
rules = r -> { rules = r -> {
r.waves = true; r.waves = true;
r.waveTimer = true; r.waveTimer = true;
r.launchWaveMultiplier = 3f; r.launchWaveMultiplier = 3f;
r.waveSpacing = 60 * 50f; r.waveSpacing = 60 * 50f;
r.spawns = Array.with( r.spawns = with(
new SpawnGroup(UnitTypes.crawler){{ new SpawnGroup(UnitTypes.crawler){{
unitScaling = 3f; unitScaling = 3f;
}}, }},
@ -75,96 +75,140 @@ public class Zones implements ContentList{
}} }}
); );
}; };
requirements = with(
new ZoneWave(groundZero, 20),
new Unlock(Blocks.combustionGenerator)
);
}}; }};
saltFlats = new Zone("saltFlats", new MapGenerator("saltFlats")){{ saltFlats = new Zone("saltFlats", new MapGenerator("saltFlats")){{
startingItems = ItemStack.list(Items.copper, 200, Items.silicon, 200, Items.lead, 200); startingItems = list(copper, 200, Items.silicon, 200, lead, 200);
loadout = Loadouts.basicFoundation; loadout = Loadouts.basicFoundation;
conditionWave = 10; conditionWave = 10;
launchPeriod = 5; launchPeriod = 5;
zoneRequirements = ZoneRequirement.with(desertWastes, 60); configureObjective = new Launched(this);
blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.draugFactory, Blocks.door, Blocks.waterExtractor}; resources = with(copper, scrap, lead, coal, sand, titanium);
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand, Items.titanium}; requirements = with(
new ZoneWave(desertWastes, 60),
new Unlock(Blocks.daggerFactory),
new Unlock(Blocks.draugFactory),
new Unlock(Blocks.door),
new Unlock(Blocks.waterExtractor)
);
}}; }};
frozenForest = new Zone("frozenForest", new MapGenerator("frozenForest", 1) frozenForest = new Zone("frozenForest", new MapGenerator("frozenForest", 1)
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{ .decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{
loadout = Loadouts.basicFoundation; loadout = Loadouts.basicFoundation;
baseLaunchCost = ItemStack.with(); startingItems = list(copper, 250);
startingItems = ItemStack.list(Items.copper, 250);
conditionWave = 10; conditionWave = 10;
blockRequirements = new Block[]{Blocks.junction, Blocks.router}; resources = with(copper, lead, coal);
zoneRequirements = ZoneRequirement.with(groundZero, 10); requirements = with(
resources = new Item[]{Items.copper, Items.lead, Items.coal}; new ZoneWave(groundZero, 10),
new Unlock(Blocks.junction),
new Unlock(Blocks.router)
);
}}; }};
craters = new Zone("craters", new MapGenerator("craters", 1).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{ craters = new Zone("craters", new MapGenerator("craters", 1).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{
startingItems = ItemStack.list(Items.copper, 100); startingItems = list(copper, 100);
conditionWave = 10; conditionWave = 10;
zoneRequirements = ZoneRequirement.with(frozenForest, 10); resources = with(copper, lead, coal, sand, scrap);
blockRequirements = new Block[]{Blocks.mender, Blocks.combustionGenerator}; requirements = with(
resources = new Item[]{Items.copper, Items.lead, Items.coal, Items.sand, Items.scrap}; new ZoneWave(frozenForest, 10),
new Unlock(Blocks.mender),
new Unlock(Blocks.combustionGenerator)
);
}}; }};
ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1)){{ ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1)){{
loadout = Loadouts.basicFoundation; loadout = Loadouts.basicFoundation;
baseLaunchCost = ItemStack.with(); startingItems = list(copper, 140, lead, 50);
startingItems = ItemStack.list(Items.copper, 140, Items.lead, 50);
conditionWave = 20; conditionWave = 20;
launchPeriod = 20; launchPeriod = 20;
zoneRequirements = ZoneRequirement.with(desertWastes, 20, craters, 15); resources = with(copper, scrap, lead, coal, sand);
blockRequirements = new Block[]{Blocks.graphitePress, Blocks.combustionGenerator, Blocks.kiln, Blocks.mechanicalPump}; requirements = with(
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand}; new ZoneWave(desertWastes, 20),
new ZoneWave(craters, 15),
new Unlock(Blocks.graphitePress),
new Unlock(Blocks.combustionGenerator),
new Unlock(Blocks.kiln),
new Unlock(Blocks.mechanicalPump)
);
}}; }};
stainedMountains = new Zone("stainedMountains", new MapGenerator("stainedMountains", 2) stainedMountains = new Zone("stainedMountains", new MapGenerator("stainedMountains", 2)
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{ .decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
loadout = Loadouts.basicFoundation; loadout = Loadouts.basicFoundation;
startingItems = ItemStack.list(Items.copper, 200, Items.lead, 50); startingItems = list(copper, 200, lead, 50);
conditionWave = 10; conditionWave = 10;
launchPeriod = 10; launchPeriod = 10;
zoneRequirements = ZoneRequirement.with(frozenForest, 15); resources = with(copper, scrap, lead, coal, titanium, sand);
blockRequirements = new Block[]{Blocks.pneumaticDrill, Blocks.powerNode, Blocks.turbineGenerator}; requirements = with(
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand}; new ZoneWave(frozenForest, 15),
new Unlock(Blocks.pneumaticDrill),
new Unlock(Blocks.powerNode),
new Unlock(Blocks.turbineGenerator)
);
}}; }};
fungalPass = new Zone("fungalPass", new MapGenerator("fungalPass")){{ fungalPass = new Zone("fungalPass", new MapGenerator("fungalPass")){{
startingItems = ItemStack.list(Items.copper, 250, Items.lead, 250, Items.metaglass, 100, Items.graphite, 100); startingItems = list(copper, 250, lead, 250, Items.metaglass, 100, Items.graphite, 100);
zoneRequirements = ZoneRequirement.with(stainedMountains, 15); resources = with(copper, lead, coal, titanium, sand);
blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.crawlerFactory, Blocks.door, Blocks.siliconSmelter}; configureObjective = new Launched(this);
resources = new Item[]{Items.copper, Items.lead, Items.coal, Items.titanium, Items.sand}; requirements = with(
new ZoneWave(stainedMountains, 15),
new Unlock(Blocks.daggerFactory),
new Unlock(Blocks.crawlerFactory),
new Unlock(Blocks.door),
new Unlock(Blocks.siliconSmelter)
);
}}; }};
overgrowth = new Zone("overgrowth", new MapGenerator("overgrowth")){{ overgrowth = new Zone("overgrowth", new MapGenerator("overgrowth")){{
startingItems = ItemStack.list(Items.copper, 1500, Items.lead, 1000, Items.silicon, 500, Items.metaglass, 250); startingItems = list(copper, 1500, lead, 1000, Items.silicon, 500, Items.metaglass, 250);
conditionWave = 12; conditionWave = 12;
launchPeriod = 4; launchPeriod = 4;
loadout = Loadouts.basicNucleus; loadout = Loadouts.basicNucleus;
zoneRequirements = ZoneRequirement.with(craters, 40, fungalPass, 10); configureObjective = new Launched(this);
blockRequirements = new Block[]{Blocks.cultivator, Blocks.sporePress, Blocks.titanFactory, Blocks.wraithFactory}; resources = with(copper, lead, coal, titanium, sand, thorium, scrap);
resources = new Item[]{Items.copper, Items.lead, Items.coal, Items.titanium, Items.sand, Items.thorium, Items.scrap}; requirements = with(
new ZoneWave(craters, 40),
new Launched(fungalPass),
new Unlock(Blocks.cultivator),
new Unlock(Blocks.sporePress),
new Unlock(Blocks.titanFactory),
new Unlock(Blocks.wraithFactory)
);
}}; }};
tarFields = new Zone("tarFields", new MapGenerator("tarFields") tarFields = new Zone("tarFields", new MapGenerator("tarFields")
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{ .decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
loadout = Loadouts.basicFoundation; loadout = Loadouts.basicFoundation;
startingItems = ItemStack.list(Items.copper, 250, Items.lead, 100); startingItems = list(copper, 250, lead, 100);
conditionWave = 15; conditionWave = 15;
launchPeriod = 10; launchPeriod = 10;
zoneRequirements = ZoneRequirement.with(ruinousShores, 20); requirements = with(new ZoneWave(ruinousShores, 20));
blockRequirements = new Block[]{Blocks.coalCentrifuge, Blocks.conduit, Blocks.wave}; resources = with(copper, scrap, lead, coal, titanium, thorium, sand);
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.thorium, Items.sand}; requirements = with(
new ZoneWave(ruinousShores, 20),
new Unlock(Blocks.coalCentrifuge),
new Unlock(Blocks.conduit),
new Unlock(Blocks.wave)
);
}}; }};
desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift")){{ desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift")){{
loadout = Loadouts.basicNucleus; loadout = Loadouts.basicNucleus;
baseLaunchCost = ItemStack.with(); startingItems = list(copper, 1000, lead, 1000, Items.graphite, 250, titanium, 250, Items.silicon, 250);
startingItems = ItemStack.list(Items.copper, 1000, Items.lead, 1000, Items.graphite, 250, Items.titanium, 250, Items.silicon, 250);
conditionWave = 3; conditionWave = 3;
launchPeriod = 2; launchPeriod = 2;
zoneRequirements = ZoneRequirement.with(tarFields, 20); resources = with(copper, scrap, lead, coal, titanium, sand, thorium);
blockRequirements = new Block[]{Blocks.thermalGenerator, Blocks.thoriumReactor}; requirements = with(
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand, Items.thorium}; new ZoneWave(tarFields, 20),
new Unlock(Blocks.thermalGenerator),
new Unlock(Blocks.thoriumReactor)
);
}}; }};
/* /*
@ -174,21 +218,23 @@ public class Zones implements ContentList{
startingItems = ItemStack.list(Items.copper, 2000, Items.lead, 2000, Items.graphite, 500, Items.titanium, 500, Items.silicon, 500); startingItems = ItemStack.list(Items.copper, 2000, Items.lead, 2000, Items.graphite, 500, Items.titanium, 500, Items.silicon, 500);
conditionWave = 3; conditionWave = 3;
launchPeriod = 2; launchPeriod = 2;
zoneRequirements = ZoneRequirement.with(stainedMountains, 40); requirements = with(stainedMountains, 40);
blockRequirements = new Block[]{Blocks.thermalGenerator}; blockRequirements = new Block[]{Blocks.thermalGenerator};
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand}; resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
}};*/ }};*/
nuclearComplex = new Zone("nuclearComplex", new MapGenerator("nuclearProductionComplex", 1) nuclearComplex = new Zone("nuclearComplex", new MapGenerator("nuclearProductionComplex", 1)
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{ .decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{
loadout = Loadouts.basicNucleus; loadout = Loadouts.basicNucleus;
baseLaunchCost = ItemStack.with(); startingItems = list(copper, 1250, lead, 1500, Items.silicon, 400, Items.metaglass, 250);
startingItems = ItemStack.list(Items.copper, 1250, Items.lead, 1500, Items.silicon, 400, Items.metaglass, 250);
conditionWave = 30; conditionWave = 30;
launchPeriod = 15; launchPeriod = 15;
zoneRequirements = ZoneRequirement.with(fungalPass, 8); resources = with(copper, scrap, lead, coal, titanium, thorium, sand);
blockRequirements = new Block[]{Blocks.thermalGenerator, Blocks.laserDrill}; requirements = with(
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.thorium, Items.sand}; new Launched(fungalPass),
new Unlock(Blocks.thermalGenerator),
new Unlock(Blocks.laserDrill)
);
}}; }};
/* /*
@ -198,9 +244,9 @@ public class Zones implements ContentList{
startingItems = ItemStack.list(Items.copper, 2000, Items.lead, 2000, Items.graphite, 500, Items.titanium, 500, Items.silicon, 500); startingItems = ItemStack.list(Items.copper, 2000, Items.lead, 2000, Items.graphite, 500, Items.titanium, 500, Items.silicon, 500);
conditionWave = 3; conditionWave = 3;
launchPeriod = 2; launchPeriod = 2;
zoneRequirements = ZoneRequirement.with(nuclearComplex, 40); requirements = with(nuclearComplex, 40);
blockRequirements = new Block[]{Blocks.thermalGenerator}; blockRequirements = new Block[]{Blocks.thermalGenerator};
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.thorium}; resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.thorium};
}};*/ }};*/
} }
} }

View File

@ -146,11 +146,15 @@ public class Control implements ApplicationListener, Loadable{
}); });
Events.on(ZoneRequireCompleteEvent.class, e -> { Events.on(ZoneRequireCompleteEvent.class, e -> {
ui.hudfrag.showToast(Core.bundle.format("zone.requirements.met", e.zone.localizedName)); if(e.objective.display() != null){
ui.hudfrag.showToast(Core.bundle.format("zone.requirement.complete", e.zoneForMet.localizedName, e.objective.display()));
}
}); });
Events.on(ZoneConfigureCompleteEvent.class, e -> { Events.on(ZoneConfigureCompleteEvent.class, e -> {
ui.hudfrag.showToast(Core.bundle.format("zone.config.complete", e.zone.configureWave)); if(e.zone.configureObjective.display() != null){
ui.hudfrag.showToast(Core.bundle.format("zone.config.unlocked", e.zone.configureObjective.display()));
}
}); });
Events.on(Trigger.newGame, () -> { Events.on(Trigger.newGame, () -> {

View File

@ -136,8 +136,7 @@ public class Logic implements ApplicationListener{
public void runWave(){ public void runWave(){
spawner.spawnEnemies(); spawner.spawnEnemies();
state.wave++; state.wave++;
state.wavetime = world.isZone() && world.getZone().isBossWave(state.wave) ? state.rules.waveSpacing * state.rules.bossWaveMultiplier : state.wavetime = world.isZone() && world.getZone().isLaunchWave(state.wave) ? state.rules.waveSpacing * state.rules.launchWaveMultiplier : state.rules.waveSpacing;
world.isZone() && world.getZone().isLaunchWave(state.wave) ? state.rules.waveSpacing * state.rules.launchWaveMultiplier : state.rules.waveSpacing;
Events.fire(new WaveEvent()); Events.fire(new WaveEvent());
} }

View File

@ -1,13 +1,13 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.*;
import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.*;
/** Base class for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. */ /** Base class for a content type that is loaded in {@link io.anuke.mindustry.core.ContentLoader}. */
public abstract class Content{ public abstract class Content implements Comparable<Content>{
public final short id; public final short id;
/** The mod that loaded this piece of content. */ /** The mod that loaded this piece of content. */
public @Nullable LoadedMod mod; public @Nullable LoadedMod mod;
@ -34,6 +34,11 @@ public abstract class Content{
public void load(){ public void load(){
} }
@Override
public int compareTo(Content c){
return Integer.compare(id, c.id);
}
@Override @Override
public String toString(){ public String toString(){
return getContentType().name() + "#" + id; return getContentType().name() + "#" + id;

View File

@ -61,11 +61,13 @@ public class EventType{
/** Called when a zone's requirements are met. */ /** Called when a zone's requirements are met. */
public static class ZoneRequireCompleteEvent{ public static class ZoneRequireCompleteEvent{
public final Zone zone, required; public final Zone zoneMet, zoneForMet;
public final Objective objective;
public ZoneRequireCompleteEvent(Zone zone, Zone required){ public ZoneRequireCompleteEvent(Zone zoneMet, Zone zoneForMet, Objective objective){
this.zone = zone; this.zoneMet = zoneMet;
this.required = required; this.zoneForMet = zoneForMet;
this.objective = objective;
} }
} }

View File

@ -91,12 +91,17 @@ public class GlobalData{
state.stats.itemsDelivered.getAndIncrement(item, 0, amount); state.stats.itemsDelivered.getAndIncrement(item, 0, amount);
} }
public boolean hasItems(Array<ItemStack> stacks){
return !stacks.contains(s -> items.get(s.item, 0) < s.amount);
}
public boolean hasItems(ItemStack[] stacks){ public boolean hasItems(ItemStack[] stacks){
for(ItemStack stack : stacks){ for(ItemStack stack : stacks){
if(items.get(stack.item, 0) < stack.amount){ if(!has(stack.item, stack.amount)){
return false; return false;
} }
} }
return true; return true;
} }
@ -107,6 +112,13 @@ public class GlobalData{
modified = true; modified = true;
} }
public void removeItems(Array<ItemStack> stacks){
for(ItemStack stack : stacks){
items.getAndIncrement(stack.item, 0, -stack.amount);
}
modified = true;
}
public boolean has(Item item, int amount){ public boolean has(Item item, int amount){
return items.get(item, 0) >= amount; return items.get(item, 0) >= amount;
} }

View File

@ -1,5 +1,10 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.game.Objectives.*;
import io.anuke.mindustry.type.*;
/** Defines a specific objective for a game. */ /** Defines a specific objective for a game. */
public interface Objective{ public interface Objective{
@ -7,6 +12,16 @@ public interface Objective{
boolean complete(); boolean complete();
/** @return the string displayed when this objective is completed, in imperative form. /** @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".*/ * e.g. when the objective is 'complete 10 waves', this would display "complete 10 waves".
String display(); * If this objective should not be displayed, should return null.*/
@Nullable String display();
/** Build a display for this zone requirement.*/
default void build(Table table){
}
default Zone zone(){
return this instanceof ZoneObjective ? ((ZoneObjective)this).zone : null;
}
} }

View File

@ -1,16 +1,21 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.arc.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.type.*;
/** Holds objective classes. */ /** Holds objective classes. */
public class Objectives{ public class Objectives{
public static class WaveObjective implements Objective{ //TODO
public static class Wave implements Objective{
public int wave; public int wave;
public WaveObjective(int wave){ public Wave(int wave){
this.wave = wave; this.wave = wave;
} }
protected WaveObjective(){} protected Wave(){}
@Override @Override
public boolean complete(){ public boolean complete(){
@ -19,20 +24,72 @@ public class Objectives{
@Override @Override
public String display(){ public String display(){
//TODO
return null; return null;
} }
} }
public static class LaunchObjective implements Objective{ public static class Unlock implements Objective{
public @NonNull UnlockableContent content;
public Unlock(UnlockableContent content){
this.content = content;
}
protected Unlock(){}
@Override @Override
public boolean complete(){ public boolean complete(){
return false; return content.unlocked();
} }
@Override @Override
public String display(){ public String display(){
return null; return Core.bundle.format("requirement.unlock", content.localizedName);
} }
} }
public static class ZoneWave extends ZoneObjective{
public int wave;
public ZoneWave(Zone zone, int wave){
this.zone = zone;
this.wave = wave;
}
protected ZoneWave(){}
@Override
public boolean complete(){
return zone.bestWave() >= wave;
}
@Override
public String display(){
return Core.bundle.format("requirement.wave", wave, zone.localizedName);
}
}
public static class Launched extends ZoneObjective{
public Launched(Zone zone){
this.zone = zone;
}
protected Launched(){}
@Override
public boolean complete(){
return zone.hasLaunched();
}
@Override
public String display(){
return Core.bundle.format("requirement.core", zone.localizedName);
}
}
public abstract static class ZoneObjective implements Objective{
public @NonNull Zone zone;
}
} }

View File

@ -18,6 +18,7 @@ import io.anuke.mindustry.entities.Effects.*;
import io.anuke.mindustry.entities.bullet.*; import io.anuke.mindustry.entities.bullet.*;
import io.anuke.mindustry.entities.type.*; import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Objectives.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
@ -60,6 +61,13 @@ public class ContentParser{
Log.info(Core.assets.get(path)); Log.info(Core.assets.get(path));
return Core.assets.get(path); return Core.assets.get(path);
}); });
put(Objective.class, (type, data) -> {
Class<? extends Objective> oc = data.has("type") ? resolve(data.getString("type"), "io.anuke.mindustry.game.objectives") : ZoneWave.class;
data.remove("type");
Objective obj = oc.getDeclaredConstructor().newInstance();
readFields(obj, data);
return obj;
});
}}; }};
/** Stores things that need to be parsed fully, e.g. reading fields of content. /** Stores things that need to be parsed fully, e.g. reading fields of content.
* This is done to accomodate binding of content names first.*/ * This is done to accomodate binding of content names first.*/

View File

@ -10,7 +10,7 @@ import io.anuke.mindustry.world.blocks.*;
import static io.anuke.mindustry.Vars.content; import static io.anuke.mindustry.Vars.content;
public class Item extends UnlockableContent implements Comparable<Item>{ public class Item extends UnlockableContent{
public final Color color; public final Color color;
/** type of the item; used for tabs and core acceptance. default value is {@link ItemType#resource}. */ /** type of the item; used for tabs and core acceptance. default value is {@link ItemType#resource}. */
@ -61,11 +61,6 @@ public class Item extends UnlockableContent implements Comparable<Item>{
return localizedName(); return localizedName();
} }
@Override
public int compareTo(Item item){
return Integer.compare(id, item.id);
}
@Override @Override
public ContentType getContentType(){ public ContentType getContentType(){
return ContentType.item; return ContentType.item;

View File

@ -6,23 +6,20 @@ import io.anuke.arc.function.*;
import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.content.*; import io.anuke.mindustry.content.*;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Objectives.*;
import io.anuke.mindustry.maps.generators.*; import io.anuke.mindustry.maps.generators.*;
import io.anuke.mindustry.world.*;
import java.util.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
public class Zone extends UnlockableContent{ public class Zone extends UnlockableContent{
public @NonNull Generator generator; public @NonNull Generator generator;
//public Block[] blockRequirements = {}; public @NonNull Objective configureObjective = new ZoneWave(this, 15);
public Objective[] requirements = {}; public Array<Objective> requirements = new Array<>();
public Objective configureObjective; //TODO //TODO autogenerate
public Item[] resources = {}; public Array<Item> resources = new Array<>();
public Consumer<Rules> rules = rules -> {}; public Consumer<Rules> rules = rules -> {};
public boolean alwaysUnlocked; public boolean alwaysUnlocked;
@ -31,9 +28,9 @@ public class Zone extends UnlockableContent{
public Loadout loadout = Loadouts.basicShard; public Loadout loadout = Loadouts.basicShard;
public TextureRegion preview; public TextureRegion preview;
protected ItemStack[] baseLaunchCost = {}; protected Array<ItemStack> baseLaunchCost = new Array<>();
protected Array<ItemStack> startingItems = new Array<>(); protected Array<ItemStack> startingItems = new Array<>();
protected ItemStack[] launchCost = null; protected Array<ItemStack> launchCost;
private Array<ItemStack> defaultStartingItems = new Array<>(); private Array<ItemStack> defaultStartingItems = new Array<>();
@ -61,35 +58,15 @@ public class Zone extends UnlockableContent{
} }
} }
public boolean isBossWave(int wave){
return wave % configureWave == 0 && wave > 0;
}
public boolean isLaunchWave(int wave){ public boolean isLaunchWave(int wave){
return metCondition() && wave % launchPeriod == 0; return metCondition() && wave % launchPeriod == 0;
} }
public boolean canUnlock(){ public boolean canUnlock(){
if(data.isUnlocked(this)){ return data.isUnlocked(this) || !requirements.contains(r -> !r.complete());
return true;
}
for(ZoneRequirement other : zoneRequirements){
if(!other.isComplete()){
return false;
}
}
for(Block other : blockRequirements){
if(!data.isUnlocked(other)){
return false;
}
}
return true;
} }
public ItemStack[] getLaunchCost(){ public Array<ItemStack> getLaunchCost(){
if(launchCost == null){ if(launchCost == null){
updateLaunchCost(); updateLaunchCost();
} }
@ -110,35 +87,41 @@ public class Zone extends UnlockableContent{
} }
public void setLaunched(){ public void setLaunched(){
if(!hasLaunched() && getRules().attackMode){ updateObjectives(() -> {
for(Zone zone : content.zones()){ Core.settings.put(name + "-launched", true);
ZoneRequirement req = Structs.find(zone.zoneRequirements, f -> f.zone == this); data.modified();
if(req != null && req.isComplete()){ });
Events.fire(new ZoneRequireCompleteEvent(zone, this));
}
}
}
Core.settings.put(name + "-launched", true);
data.modified();
} }
public void updateWave(int wave){ public void updateWave(int wave){
int value = Core.settings.getInt(name + "-wave", 0); int value = Core.settings.getInt(name + "-wave", 0);
if(value < wave){ if(value < wave){
Core.settings.put(name + "-wave", wave); updateObjectives(() -> {
data.modified(); Core.settings.put(name + "-wave", wave);
data.modified();
});
}
}
for(Zone zone : content.zones()){ public void updateObjectives(Runnable closure){
ZoneRequirement req = Structs.find(zone.zoneRequirements, f -> f.zone == this); Array<ZoneObjective> incomplete = content.zones()
if(req != null && wave == req.wave + 1 && req.isComplete()){ .map(z -> z.requirements).<Objective>flatten()
Events.fire(new ZoneRequireCompleteEvent(zone, this)); .select(o -> o.zone() == this && !o.complete())
} .as(ZoneObjective.class);
}
if(wave == configureWave + 1){ boolean wasConfig = configureObjective.complete();
Events.fire(new ZoneConfigureCompleteEvent(this));
closure.run();
for(ZoneObjective objective : incomplete){
if(objective.complete()){
Events.fire(new ZoneRequireCompleteEvent(objective.zone, content.zones().find(z -> z.requirements.contains(objective)), objective));
} }
} }
if(!wasConfig && configureObjective.complete()){
Events.fire(new ZoneConfigureCompleteEvent(this));
}
} }
public int bestWave(){ public int bestWave(){
@ -171,7 +154,7 @@ public class Zone extends UnlockableContent{
} }
stacks.sort(); stacks.sort();
launchCost = stacks.toArray(ItemStack.class); launchCost = stacks;
Core.settings.putObject(name + "-starting-items", startingItems); Core.settings.putObject(name + "-starting-items", startingItems);
data.modified(); data.modified();
} }
@ -183,13 +166,13 @@ public class Zone extends UnlockableContent{
} }
public boolean canConfigure(){ public boolean canConfigure(){
return bestWave() >= configureWave; return configureObjective.complete();
} }
@Override @Override
public void init(){ public void init(){
generator.init(loadout); generator.init(loadout);
Arrays.sort(resources); resources.sort();
for(ItemStack stack : startingItems){ for(ItemStack stack : startingItems){
defaultStartingItems.add(new ItemStack(stack.item, stack.amount)); defaultStartingItems.add(new ItemStack(stack.item, stack.amount));
@ -227,40 +210,4 @@ public class Zone extends UnlockableContent{
return ContentType.zone; return ContentType.zone;
} }
/*
public static class ZoneRequirement{
public @NonNull Zone zone;
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){
out[i / 2] = new ZoneRequirement((Zone)objects[i], (Integer)objects[i + 1]);
}
return out;
}
}*/
} }

View File

@ -1,6 +1,7 @@
package io.anuke.mindustry.ui.dialogs; package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.function.*; import io.anuke.arc.function.*;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.scene.style.*; import io.anuke.arc.scene.style.*;
@ -34,9 +35,14 @@ public class CustomRulesDialog extends FloatingDialog{
banDialog.shown(this::rebuildBanned); banDialog.shown(this::rebuildBanned);
banDialog.buttons.addImageTextButton("$addall", Icon.arrow16Small, () -> { banDialog.buttons.addImageTextButton("$addall", Icon.arrow16Small, () -> {
rules.bannedBlocks.addAll(content.blocks()); rules.bannedBlocks.addAll(content.blocks().select(Block::isBuildable));
rebuildBanned(); rebuildBanned();
}).size(210f, 64f); }).size(180, 64f);
banDialog.buttons.addImageTextButton("$clear", Icon.trash16Small, () -> {
rules.bannedBlocks.clear();
rebuildBanned();
}).size(180, 64f);
setFillParent(true); setFillParent(true);
shown(this::setup); shown(this::setup);
@ -44,40 +50,58 @@ public class CustomRulesDialog extends FloatingDialog{
} }
private void rebuildBanned(){ private void rebuildBanned(){
float previousScroll = banDialog.getChildren().isEmpty() ? 0f : ((ScrollPane)banDialog.getChildren().first()).getScrollY(); float previousScroll = banDialog.cont.getChildren().isEmpty() ? 0f : ((ScrollPane)banDialog.cont.getChildren().first()).getScrollY();
banDialog.cont.clear(); banDialog.cont.clear();
banDialog.cont.pane(t -> { banDialog.cont.pane(t -> {
t.margin(10f); t.margin(10f);
for(Block block : rules.bannedBlocks){
t.table(Styles.flatOver, b -> {
b.left().margin(4f);
b.addImage(block.icon(Cicon.medium));
b.add(block.localizedName).padLeft(3).growX().left().wrap();
b.addImageButton(Icon.cancelSmall, () -> { if(rules.bannedBlocks.isEmpty()){
t.add("$empty");
}
Array<Block> array = Array.with(rules.bannedBlocks);
array.sort();
int cols = mobile && Core.graphics.isPortrait() ? 1 : mobile ? 2 : 3;
int i = 0;
for(Block block : array){
t.table(Tex.underline, b -> {
b.left().margin(4f);
b.addImage(block.icon(Cicon.medium)).size(Cicon.medium.size).padRight(3);
b.add(block.localizedName).color(Color.lightGray).padLeft(3).growX().left().wrap();
b.addImageButton(Icon.cancelSmall, Styles.clearPartiali, () -> {
rules.bannedBlocks.remove(block); rules.bannedBlocks.remove(block);
rebuildBanned(); rebuildBanned();
}).size(70f).pad(-4f).padLeft(0f); }).size(70f).pad(-4f).padLeft(0f);
}).size(300f, 70f); }).size(300f, 70f).padRight(5);
t.row();
if(++i % cols == 0){
t.row();
}
} }
}).get().setScrollYForce(previousScroll); }).get().setScrollYForce(previousScroll);
banDialog.cont.row(); banDialog.cont.row();
banDialog.cont.addImageTextButton("$add", Icon.addSmall, () -> { banDialog.cont.addImageTextButton("$add", Icon.addSmall, () -> {
FloatingDialog dialog = new FloatingDialog("$add"); FloatingDialog dialog = new FloatingDialog("$add");
content.blocks().each(b -> !rules.bannedBlocks.contains(b), b -> { dialog.cont.pane(t -> {
int cols = mobile && Core.graphics.isPortrait() ? 4 : 8; t.left().margin(14f);
int i = 0; int[] i = {0};
dialog.cont.addImageButton(new TextureRegionDrawable(b.icon(Cicon.medium)), Styles.cleari, () -> { content.blocks().each(b -> !rules.bannedBlocks.contains(b) && b.isBuildable(), b -> {
rules.bannedBlocks.add(b); int cols = mobile && Core.graphics.isPortrait() ? 4 : 12;
rebuildBanned(); t.addImageButton(new TextureRegionDrawable(b.icon(Cicon.medium)), Styles.cleari, () -> {
dialog.hide(); rules.bannedBlocks.add(b);
}).size(80f); rebuildBanned();
dialog.hide();
}).size(60f).get().resizeImage(Cicon.medium.size);
if(++i % cols == 0){ if(++i[0] % cols == 0){
dialog.cont.row(); t.row();
} }
});
}); });
dialog.addCloseButton(); dialog.addCloseButton();
dialog.show(); dialog.show();
}).size(300f, 64f); }).size(300f, 64f);

View File

@ -21,9 +21,7 @@ import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.io.SaveIO.*; import io.anuke.mindustry.io.SaveIO.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Zone.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.ui.Styles;
import io.anuke.mindustry.ui.TreeLayout.*; import io.anuke.mindustry.ui.TreeLayout.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@ -156,7 +154,7 @@ public class DeployDialog extends FloatingDialog{
node.allChildren.clear(); node.allChildren.clear();
node.allChildren.addAll(node.children); node.allChildren.addAll(node.children);
for(ZoneNode other : new ObjectSetIterator<>(nodes)){ for(ZoneNode other : new ObjectSetIterator<>(nodes)){
if(Structs.contains(other.zone.zoneRequirements, req -> req.zone == node.zone)){ if(other.zone.requirements.contains(req -> req.zone() == node.zone)){
node.allChildren.add(other); node.allChildren.add(other);
} }
} }
@ -164,12 +162,7 @@ public class DeployDialog extends FloatingDialog{
} }
boolean hidden(Zone zone){ boolean hidden(Zone zone){
for(ZoneRequirement other : zone.zoneRequirements){ return zone.requirements.contains(o -> o.zone() != null && o.zone().locked());
if(!data.isUnlocked(other.zone)){
return true;
}
}
return false;
} }
void buildButton(Zone zone, Button button){ void buildButton(Zone zone, Button button){
@ -258,7 +251,7 @@ public class DeployDialog extends FloatingDialog{
//this.height /= 2f; //this.height /= 2f;
nodes.add(this); nodes.add(this);
arr.selectFrom(content.zones(), other -> other.zoneRequirements.length > 0 && other.zoneRequirements[0].zone == zone); arr.selectFrom(content.zones(), other -> other.requirements.size > 0 && other.requirements.first().zone() == zone);
children = new ZoneNode[arr.size]; children = new ZoneNode[arr.size];
for(int i = 0; i < children.length; i++){ for(int i = 0; i < children.length; i++){

View File

@ -1,15 +1,15 @@
package io.anuke.mindustry.ui.dialogs; package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.*;
import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.scene.ui.layout.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.Objectives.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Zone.*;
import io.anuke.mindustry.world.*;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@ -38,8 +38,7 @@ public class ZoneInfoDialog extends FloatingDialog{
if(!zone.unlocked()) return; if(!zone.unlocked()) return;
ItemStack[] stacks = zone.getLaunchCost(); for(ItemStack stack : zone.getLaunchCost()){
for(ItemStack stack : stacks){
if(stack.amount == 0) continue; if(stack.amount == 0) continue;
if(i++ % 2 == 0){ if(i++ % 2 == 0){
@ -62,31 +61,32 @@ public class ZoneInfoDialog extends FloatingDialog{
cont.table(req -> { cont.table(req -> {
req.defaults().left(); req.defaults().left();
if(zone.zoneRequirements.length > 0){ Array<Objective> zones = zone.requirements.select(o -> !(o instanceof Unlock));
if(!zones.isEmpty()){
req.table(r -> { req.table(r -> {
r.add("$complete").colspan(2).left(); r.add("$complete").colspan(2).left();
r.row(); r.row();
for(ZoneRequirement zreq : zone.zoneRequirements){ for(Objective o : zones){
r.addImage(Icon.terrain).padRight(4); r.addImage(Icon.terrain).padRight(4);
r.add(!zreq.zone.getRules().attackMode ? r.add(o.display()).color(Color.lightGray);
Core.bundle.format("zone.requirement.wave", zreq.wave, zreq.zone.localizedName()) : r.addImage(o.complete() ? Icon.checkSmall : Icon.cancelSmall, o.complete() ? Color.lightGray : Color.scarlet).padLeft(3);
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(); r.row();
} }
}); });
} }
req.row(); req.row();
Array<Unlock> blocks = zone.requirements.select(o -> o instanceof Unlock).as(Unlock.class);
if(zone.blockRequirements.length > 0){ if(!blocks.isEmpty()){
req.table(r -> { req.table(r -> {
r.add("$research.list").colspan(2).left(); r.add("$research.list").colspan(2).left();
r.row(); r.row();
for(Block block : zone.blockRequirements){ for(Unlock blocko : blocks){
r.addImage(block.icon(Cicon.small)).size(8 * 3).padRight(5); r.addImage(blocko.content.icon(Cicon.small)).size(8 * 3).padRight(5);
r.add(block.localizedName).color(Color.lightGray).left(); r.add(blocko.content.localizedName).color(Color.lightGray).left();
r.addImage(data.isUnlocked(block) ? Icon.checkSmall : Icon.cancelSmall, data.isUnlocked(block) ? Color.lightGray : Color.scarlet).padLeft(3); r.addImage(blocko.content.unlocked() ? Icon.checkSmall : Icon.cancelSmall, blocko.content.unlocked() ? Color.lightGray : Color.scarlet).padLeft(3);
r.row(); r.row();
} }
@ -108,7 +108,7 @@ public class ZoneInfoDialog extends FloatingDialog{
t.left(); t.left();
t.add("$zone.resources").padRight(6); t.add("$zone.resources").padRight(6);
if(zone.resources.length > 0){ if(zone.resources.size > 0){
t.table(r -> { t.table(r -> {
t.left(); t.left();
int i = 0; int i = 0;
@ -137,7 +137,7 @@ public class ZoneInfoDialog extends FloatingDialog{
cont.row(); cont.row();
cont.addButton(zone.canConfigure() ? "$configure" : Core.bundle.format("configure.locked", zone.configureWave), cont.addButton(zone.canConfigure() ? "$configure" : Core.bundle.format("configure.locked", zone.configureObjective.display()),
() -> loadout.show(zone.loadout.core().itemCapacity, zone.getStartingItems(), zone::resetStartingItems, zone::updateLaunchCost, rebuildItems) () -> loadout.show(zone.loadout.core().itemCapacity, zone.getStartingItems(), zone::resetStartingItems, zone::updateLaunchCost, rebuildItems)
).fillX().pad(3).disabled(b -> !zone.canConfigure()); ).fillX().pad(3).disabled(b -> !zone.canConfigure());
} }

View File

@ -153,8 +153,7 @@ public class PlacementFragment extends Fragment{
button.setChecked(control.input.block == block); button.setChecked(control.input.block == block);
if(state.rules.bannedBlocks.contains(block)){ if(state.rules.bannedBlocks.contains(block)){
button.getStyle().imageUp = Icon.cancelSmall; button.forEach(elem -> elem.setColor(Color.darkGray));
button.forEach(elem -> elem.setColor(Color.gray));
} }
}); });
@ -231,6 +230,15 @@ public class PlacementFragment extends Fragment{
} }
}).growX().left().margin(3); }).growX().left().margin(3);
if(state.rules.bannedBlocks.contains(lastDisplay)){
topTable.row();
topTable.table(b -> {
b.addImage(Icon.cancelSmall).padRight(2).color(Color.scarlet);
b.add("$banned");
b.left();
}).padTop(2).left();
}
}else if(tileDisplayBlock() != null){ //show selected tile }else if(tileDisplayBlock() != null){ //show selected tile
lastDisplay = tileDisplayBlock(); lastDisplay = tileDisplayBlock();
topTable.table(t -> { topTable.table(t -> {
@ -309,7 +317,7 @@ public class PlacementFragment extends Fragment{
returnArray.sort((b1, b2) -> { returnArray.sort((b1, b2) -> {
int locked = -Boolean.compare(unlocked(b1), unlocked(b2)); int locked = -Boolean.compare(unlocked(b1), unlocked(b2));
if(locked != 0) return locked; if(locked != 0) return locked;
return -Boolean.compare(state.rules.bannedBlocks.contains(b1), state.rules.bannedBlocks.contains(b2)); return Boolean.compare(state.rules.bannedBlocks.contains(b1), state.rules.bannedBlocks.contains(b2));
}); });
return returnArray; return returnArray;
} }

View File

@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=9f567f04a005ea8b4132b31d64f325ec105def5e archash=feb8c35e143c0a048488341ae916c7732ea7a84e