New mission classes

This commit is contained in:
Anuken
2018-09-21 19:36:19 -04:00
parent 3bd40eeb27
commit d067bbfa65
18 changed files with 172 additions and 40 deletions

View File

@ -63,6 +63,7 @@ text.mission.complete.body=Sector {0},{1} has been conquered.
text.mission.wave=Survive [accent]{0}[] waves.
text.mission.battle=Destroy the enemy base.
text.mission.resource=Obtain {0} x{1}
text.mission.block=Create '{0}' structure
text.none=<none>
text.close=Close
text.quit=Quit
@ -617,7 +618,7 @@ block.rotary-pump.name=Rotary Pump
block.thorium-reactor.name=Thorium Reactor
block.command-center.name=Command Center
block.mass-driver.name=Mass Driver
block.blast-drill.name=Blast Drill
block.blast-drill.name=Airblast Drill
block.thermal-pump.name=Thermal Pump
block.thermal-generator.name=Thermal Generator
block.alloy-smelter.name=Alloy Smelter

View File

@ -129,7 +129,6 @@ public class DebugBlocks extends BlockList implements ContentList{
Table cont = new Table();
for(int i = 0; i < items.size; i++){
if(i == 0) continue;
final int f = i;
ImageButton button = cont.addImageButton("liquid-icon-" + items.get(i).name, "toggle", 24, () -> {
Call.setLiquidSourceLiquid(null, tile, items.get(f));

View File

@ -13,6 +13,7 @@ import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.ContentDatabase;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Saves;
import io.anuke.mindustry.input.DefaultKeybinds;
import io.anuke.mindustry.input.DesktopInput;
@ -378,11 +379,13 @@ public class Control extends Module{
if(world.getSector() != null && !world.getSector().complete){
//all assigned missions are complete
if(world.getSector().completedMissions >= world.getSector().missions.size){
state.mode = GameMode.victory;
world.sectors().completeSector(world.getSector().x, world.getSector().y);
world.sectors().save();
ui.missions.show(world.getSector());
}else if(world.getSector().currentMission().isComplete()){
state.mode = world.getSector().currentMission().getMode();
//increment completed missions, check next index next frame
world.getSector().completedMissions ++;
}

View File

@ -210,11 +210,11 @@ public class UI extends SceneModule{
}
}
public void loadAnd(Runnable call){
loadAnd("$text.loading", call);
public void loadGraphics(Runnable call){
loadGraphics("$text.loading", call);
}
public void loadAnd(String text, Runnable call){
public void loadGraphics(String text, Runnable call){
loadfrag.show(text);
Timers.runTask(7f, () -> {
call.run();

View File

@ -95,7 +95,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
"$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Runnable) loadDialog::show,
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () -> {
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> {
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
@ -116,7 +116,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
ui.showError("$text.web.unsupported");
}else {
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> {
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
try{
MapTileData data = MapIO.readPixmap(new Pixmap(file));
@ -137,7 +137,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
FileHandle result = file;
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
try{
if(!editor.getTags().containsKey("name")){
@ -168,7 +168,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
Platform.instance.showFileChooser("$text.saveimage", "Image Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + ".png");
FileHandle result = file;
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
try{
Pixmaps.write(MapIO.generatePixmap(editor.getMap()), result);
}catch (Exception e){
@ -194,7 +194,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
resizeDialog = new MapResizeDialog(editor, (x, y) -> {
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
editor.resize(x, y);
view.clearStack();
});
@ -203,7 +203,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
loadDialog = new MapLoadDialog(map -> {
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
try(DataInputStream stream = new DataInputStream(map.stream.get())){
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
@ -338,7 +338,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
public void beginEditMap(InputStream is){
ui.loadAnd(() -> {
ui.loadGraphics(() -> {
try{
shownWithMap = true;
DataInputStream stream = new DataInputStream(is);

View File

@ -17,6 +17,12 @@ public enum GameMode{
enemyCheat = true;
showPads = true;
}},
victory{{
disableWaves = true;
hidden = true;
enemyCheat = false;
showPads = true;
}},
pvp{{
showPads = true;
disableWaves = true;

View File

@ -7,6 +7,7 @@ import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.Saves.SaveSlot;
import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.maps.missions.Mission;
import io.anuke.mindustry.maps.missions.VictoryMission;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.ucore.util.Bits;
@ -15,6 +16,8 @@ import static io.anuke.mindustry.Vars.control;
@Serialize
public class Sector{
private static final Mission victoryMission = new VictoryMission();
/**Position on the map, can be positive or negative.*/
public short x, y;
/**Whether this sector has already been completed.*/
@ -52,7 +55,7 @@ public class Sector{
}
public Mission currentMission(){
return missions.get(Math.min(completedMissions, missions.size - 1));
return completedMissions >= missions.size ? victoryMission : missions.get(completedMissions);
}
public int getSeed(){

View File

@ -20,7 +20,6 @@ import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.ucore.noise.RidgedPerlin;
import io.anuke.ucore.noise.Simplex;
import io.anuke.ucore.noise.VoronoiNoise;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.SeedRandom;
@ -37,15 +36,12 @@ public class WorldGenerator{
private Simplex sim2 = new Simplex(baseSeed + 1);
private Simplex sim3 = new Simplex(baseSeed + 2);
private RidgedPerlin rid = new RidgedPerlin(baseSeed + 4, 1);
private VoronoiNoise vn = new VoronoiNoise(baseSeed + 2, (short)0);
private SeedRandom random = new SeedRandom(baseSeed + 3);
private GenResult result = new GenResult();
private ObjectMap<Block, Block> decoration;
public WorldGenerator(){
vn.setUseDistance(true);
decoration = Mathf.map(
Blocks.grass, Blocks.shrub,
Blocks.stone, Blocks.rock,

View File

@ -0,0 +1,34 @@
package io.anuke.mindustry.maps.missions;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.GameMode;
import static io.anuke.mindustry.Vars.threads;
/**A mission which simply runs a single action and is completed instantly.*/
public abstract class ActionMission implements Mission{
private Runnable runner;
public ActionMission(Runnable runner){
this.runner = runner;
}
@Override
public boolean isComplete(){
if(runner != null){
threads.run(runner);
runner = null;
}
return true;
}
@Override
public String displayString(){
return "";
}
@Override
public GameMode getMode(){
return Vars.state.mode;
}
}

View File

@ -7,15 +7,10 @@ import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.maps.generation.FortressGenerator;
import io.anuke.mindustry.maps.generation.Generation;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
public class BattleMission implements Mission{
private final static int coreX = 60, coreY = 60;
@Override
public void display(Table table){
table.add("$text.mission.battle");
}
@Override
public GameMode getMode(){

View File

@ -0,0 +1,49 @@
package io.anuke.mindustry.maps.missions;
import io.anuke.mindustry.game.EventType.BlockBuildEvent;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.util.Bundles;
import static io.anuke.mindustry.Vars.defaultTeam;
import static io.anuke.mindustry.Vars.world;
/**A mission in which the player must place a block.*/
public class BlockMission implements Mission{
private final Block block;
private boolean complete;
static{
Events.on(BlockBuildEvent.class, event -> {
if(world.getSector() != null && event.team == defaultTeam){
Mission mission = world.getSector().currentMission();
if(mission instanceof BlockMission){
BlockMission block = (BlockMission)world.getSector().currentMission();
if(block.block == event.tile.block()){
block.complete = true;
}
}
}
});
}
public BlockMission(Block block){
this.block = block;
}
@Override
public boolean isComplete(){
return complete;
}
@Override
public String displayString(){
return Bundles.format("text.mission.block", block.formalName);
}
@Override
public GameMode getMode(){
return GameMode.noWaves;
}
}

View File

@ -0,0 +1,17 @@
package io.anuke.mindustry.maps.missions;
import static io.anuke.mindustry.Vars.*;
/**An action mission which simply expands the sector.*/
public class ExpandMission extends ActionMission{
public ExpandMission(int expandX, int expandY){
super(() -> {
if(headless){
world.sectors().expandSector(world.getSector(), expandX, expandY);
}else{
ui.loadLogic(() -> world.sectors().expandSector(world.getSector(), expandX, expandY));
}
});
}
}

View File

@ -14,7 +14,10 @@ public interface Mission{
boolean isComplete();
String displayString();
GameMode getMode();
void display(Table table);
default void display(Table table){
table.add(displayString());
}
default Array<SpawnGroup> getWaves(Sector sector){
return new Array<>();

View File

@ -3,9 +3,12 @@ package io.anuke.mindustry.maps.missions;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.util.Bundles;
import static io.anuke.mindustry.Vars.state;
/**A mission that is completed when the player obtains items in their core.*/
public class ResourceMission implements Mission{
private final Item item;
private final int amount;
@ -15,11 +18,6 @@ public class ResourceMission implements Mission{
this.amount = amount;
}
@Override
public void display(Table table){
}
@Override
public GameMode getMode(){
return GameMode.waves;
@ -27,7 +25,12 @@ public class ResourceMission implements Mission{
@Override
public boolean isComplete(){
return Vars.state.teams.get(Vars.defaultTeam).cores.first().entity.items.has(item, amount);
for(Tile tile : state.teams.get(Vars.defaultTeam).cores){
if(tile.entity.items.has(item, amount)){
return true;
}
}
return false;
}
@Override

View File

@ -0,0 +1,26 @@
package io.anuke.mindustry.maps.missions;
import io.anuke.mindustry.game.GameMode;
import io.anuke.ucore.scene.ui.layout.Table;
public class VictoryMission implements Mission{
@Override
public boolean isComplete(){
return false;
}
@Override
public String displayString(){
return "none";
}
@Override
public GameMode getMode(){
return GameMode.victory;
}
@Override
public void display(Table table){
}
}

View File

@ -2,10 +2,12 @@ package io.anuke.mindustry.maps.missions;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.Waves;
import io.anuke.mindustry.maps.Sector;
import io.anuke.mindustry.maps.generation.Generation;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
import static io.anuke.mindustry.Vars.state;
@ -28,11 +30,6 @@ public class WaveMission implements Mission{
generateCoreAt(gen, coreX, coreY, Team.blue);
}
@Override
public void display(Table table){
table.add(Bundles.format("text.mission.wave", target));
}
@Override
public GameMode getMode(){
return GameMode.waves;

View File

@ -24,7 +24,7 @@ public class SaveDialog extends LoadDialog{
slots.row();
slots.addImageTextButton("$text.save.new", "icon-add", "clear", 14 * 3, () ->
ui.showTextInput("$text.save", "$text.save.newslot", "", text -> {
ui.loadAnd("$text.saving", () -> {
ui.loadGraphics("$text.saving", () -> {
control.getSaves().addSave(text);
threads.runGraphics(() -> threads.run(() -> threads.runGraphics(this::setup)));
});

View File

@ -59,7 +59,7 @@ public class MenuFragment extends Fragment{
maps = new MobileButton("icon-map", isize, "$text.maps", ui.maps::show),
load = new MobileButton("icon-load", isize, "$text.load", ui.load::show),
join = new MobileButton("icon-add", isize, "$text.joingame", ui.join::show),
editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadAnd(ui.editor::show)),
editor = new MobileButton("icon-editor", isize, "$text.editor", () -> ui.loadGraphics(ui.editor::show)),
tools = new MobileButton("icon-tools", isize, "$text.settings", ui.settings::show),
unlocks = new MobileButton("icon-unlocks", isize, "$text.unlocks", ui.unlocks::show),
donate = new MobileButton("icon-donate", isize, "$text.donate", Platform.instance::openDonations);
@ -114,7 +114,7 @@ public class MenuFragment extends Fragment{
out.row();
out.add(new MenuButton("icon-editor", "$text.editor", () -> ui.loadAnd(ui.editor::show)));
out.add(new MenuButton("icon-editor", "$text.editor", () -> ui.loadGraphics(ui.editor::show)));
out.add(new MenuButton("icon-map", "$text.maps", ui.maps::show));