mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-11-10 15:05:23 +03:00
Re-structuring
This commit is contained in:
parent
e24d96da6f
commit
153e6c5f1b
@ -13,8 +13,6 @@ text.linkfail = Failed to open link!\nThe URL has been copied to your clipboard.
|
||||
text.screenshot = Screenshot saved to {0}
|
||||
text.gameover = Game Over
|
||||
text.gameover.pvp = The[accent] {0}[] team is victorious!
|
||||
text.sector.gameover = This sector has been lost. Re-deploy?
|
||||
text.sector.retry = Retry
|
||||
text.highscore = [accent]New highscore!
|
||||
text.wave.lasted = You lasted until wave [accent]{0}[].
|
||||
text.level.highscore = High Score: [accent]{0}
|
||||
@ -35,41 +33,11 @@ text.loadgame = Load Game
|
||||
text.joingame = Join Game
|
||||
text.addplayers = Add/Remove Players
|
||||
text.customgame = Custom Game
|
||||
text.sectors = Sectors
|
||||
text.sector = Sector: [LIGHT_GRAY]{0}
|
||||
text.sector.time = Time: [LIGHT_GRAY]{0}
|
||||
text.sector.deploy = Deploy
|
||||
text.sector.abandon = Abandon
|
||||
text.sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone!
|
||||
text.sector.resume = Resume
|
||||
text.sector.locked = [scarlet][[Incomplete]
|
||||
text.sector.unexplored = [accent][[Unexplored]
|
||||
text.missions = Missions:[LIGHT_GRAY] {0}
|
||||
text.mission = Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.main = Main Mission:[LIGHT_GRAY] {0}
|
||||
text.mission.info = Mission Info
|
||||
text.mission.complete = Mission complete!
|
||||
text.mission.complete.body = Sector {0},{1} has been conquered.
|
||||
text.mission.wave = Survive[accent] {0}/{1} []waves\nWave in {2}
|
||||
text.mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies
|
||||
text.mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy
|
||||
text.mission.wave.menu = Survive[accent] {0}[] waves
|
||||
text.mission.battle = Destroy enemy core
|
||||
text.mission.resource.menu = Obtain {0} x{1}
|
||||
text.mission.resource = Obtain {0}:\n[accent]{1}/{2}[]
|
||||
text.mission.block = Create {0}
|
||||
text.mission.unit = Create {0} Unit
|
||||
text.mission.command = Send Command {0} To Units
|
||||
text.mission.linknode = Link Power Node
|
||||
text.mission.display = [accent]Mission:\n[LIGHT_GRAY]{0}
|
||||
text.mission.mech = Switch to mech[accent] {0}[]
|
||||
text.mission.create = Create[accent] {0}[]
|
||||
text.none = <none>
|
||||
text.close = Close
|
||||
text.quit = Quit
|
||||
text.maps = Maps
|
||||
text.continue = Continue
|
||||
text.nextmission = Next Mission
|
||||
text.maps.none = [LIGHT_GRAY]No maps found!
|
||||
text.about.button = About
|
||||
text.name = Name:
|
||||
@ -82,8 +50,6 @@ text.players.single = {0} player online
|
||||
text.server.closing = [accent]Closing server...
|
||||
text.server.kicked.kick = You have been kicked from the server!
|
||||
text.server.kicked.serverClose = Server closed.
|
||||
text.server.kicked.sectorComplete = Sector completed.
|
||||
text.server.kicked.sectorComplete.text = Your mission is complete.\nThe server will now continue at the next sector.
|
||||
text.server.kicked.clientOutdated = Outdated client! Update your game!
|
||||
text.server.kicked.serverOutdated = Outdated server! Ask the host to update!
|
||||
text.server.kicked.banned = You are banned on this server.
|
||||
@ -163,7 +129,6 @@ text.save.rename.text = New name:
|
||||
text.selectslot = Select a save.
|
||||
text.slot = [accent]Slot {0}
|
||||
text.save.corrupted = [accent]Save file corrupted or invalid!\nIf you have just updated your game, this is probably a change in the save format and [scarlet]not[] a bug.
|
||||
text.sector.corrupted = [accent]A save file for this sector was found, but loading failed.\nA new one has been created.
|
||||
text.empty = <empty>
|
||||
text.on = On
|
||||
text.off = Off
|
||||
@ -284,7 +249,6 @@ text.settings.graphics = Graphics
|
||||
text.settings.cleardata = Clear Game Data...
|
||||
text.settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone!
|
||||
text.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.
|
||||
text.settings.clearsectors = Clear Sectors
|
||||
text.settings.clearunlocks = Clear Unlocks
|
||||
text.settings.clearall = Clear All
|
||||
text.paused = [accent]< Paused >
|
||||
|
@ -177,12 +177,7 @@ public class WaveSpawner{
|
||||
flySpawns.clear();
|
||||
groundSpawns.clear();
|
||||
quadrants = new GridBits(quadWidth(), quadHeight());
|
||||
|
||||
if(world.getSector() == null){
|
||||
groups = Waves.getSpawns();
|
||||
}else{
|
||||
groups = world.getSector().spawns;
|
||||
}
|
||||
groups = Waves.getSpawns();
|
||||
|
||||
dynamicSpawn = true;
|
||||
|
||||
|
@ -121,7 +121,7 @@ public class Control implements ApplicationListener{
|
||||
|
||||
int last = Core.settings.getInt("hiscore" + world.getMap().name, 0);
|
||||
|
||||
if(state.wave > last && !state.mode.infiniteResources && !state.mode.disableWaveTimer && world.getSector() == null){
|
||||
if(state.wave > last && !state.mode.infiniteResources && !state.mode.disableWaveTimer){
|
||||
Core.settings.put("hiscore" + world.getMap().name, state.wave);
|
||||
Core.settings.save();
|
||||
hiscore = true;
|
||||
@ -131,10 +131,6 @@ public class Control implements ApplicationListener{
|
||||
});
|
||||
|
||||
Events.on(GameOverEvent.class, event -> {
|
||||
//delete saves for game-over sectors
|
||||
if(world.getSector() != null && world.getSector().hasSave()){
|
||||
world.getSector().getSave().delete();
|
||||
}
|
||||
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
|
||||
//the restart dialog can show info for any number of scenarios
|
||||
Call.onGameOver(event.winner);
|
||||
|
@ -4,7 +4,6 @@ import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.arc.ApplicationListener;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.entities.Entities;
|
||||
import io.anuke.arc.entities.EntityGroup;
|
||||
import io.anuke.arc.entities.EntityQuery;
|
||||
@ -12,13 +11,10 @@ import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.Teams;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
@ -53,10 +49,6 @@ public class Logic implements ApplicationListener{
|
||||
|
||||
/**Handles the event of content being used by either the player or some block.*/
|
||||
public void handleContent(UnlockableContent content){
|
||||
if(world.getSector() != null){
|
||||
world.getSector().currentMission().onContentUsed(content);
|
||||
}
|
||||
|
||||
if(!headless){
|
||||
control.unlocks.unlockContent(content);
|
||||
}
|
||||
@ -66,15 +58,6 @@ public class Logic implements ApplicationListener{
|
||||
state.set(State.playing);
|
||||
state.wavetime = wavespace * state.difficulty.timeScaling * 2;
|
||||
|
||||
for(Tile tile : state.teams.get(defaultTeam).cores){
|
||||
if(world.getSector() != null){
|
||||
Array<ItemStack> items = world.getSector().startingItems;
|
||||
for(ItemStack stack : items){
|
||||
tile.entity.items.add(stack.item, stack.amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Events.fire(new PlayEvent());
|
||||
}
|
||||
|
||||
@ -122,52 +105,12 @@ public class Logic implements ApplicationListener{
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSectors(){
|
||||
if(world.getSector() == null || state.gameOver) return;
|
||||
|
||||
world.getSector().currentMission().update();
|
||||
|
||||
//check unlocked sectors
|
||||
while(!world.getSector().complete && world.getSector().currentMission().isComplete()){
|
||||
Call.onMissionFinish(world.getSector().completedMissions);
|
||||
}
|
||||
|
||||
//check if all assigned missions are complete
|
||||
if(!world.getSector().complete && world.getSector().completedMissions >= world.getSector().missions.size){
|
||||
Call.onSectorComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Remote(called = Loc.both)
|
||||
public static void onGameOver(Team winner){
|
||||
ui.restart.show(winner);
|
||||
netClient.setQuiet();
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void onMissionFinish(int index){
|
||||
world.getSector().missions.get(index).onComplete();
|
||||
world.getSector().completedMissions = index + 1;
|
||||
|
||||
state.mode = world.getSector().currentMission().getMode();
|
||||
world.getSector().currentMission().onBegin();
|
||||
world.sectors.save();
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void onSectorComplete(){
|
||||
state.mode = GameMode.victory;
|
||||
|
||||
world.sectors.completeSector(world.getSector().x, world.getSector().y);
|
||||
world.sectors.save();
|
||||
|
||||
if(!headless && !Net.client()){
|
||||
ui.missions.show(world.getSector());
|
||||
}
|
||||
|
||||
Events.fire(new SectorCompleteEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
@ -221,7 +164,6 @@ public class Logic implements ApplicationListener{
|
||||
}
|
||||
|
||||
if(!Net.client() && !world.isInvalidMap()){
|
||||
updateSectors();
|
||||
checkGameOver();
|
||||
}
|
||||
}
|
||||
|
@ -66,8 +66,6 @@ public class UI implements ApplicationListener{
|
||||
public LocalPlayerDialog localplayers;
|
||||
public UnlocksDialog unlocks;
|
||||
public ContentInfoDialog content;
|
||||
public SectorsDialog sectors;
|
||||
public MissionDialog missions;
|
||||
|
||||
public Cursor drillCursor, unloadCursor;
|
||||
|
||||
@ -177,8 +175,6 @@ public class UI implements ApplicationListener{
|
||||
maps = new MapsDialog();
|
||||
localplayers = new LocalPlayerDialog();
|
||||
content = new ContentInfoDialog();
|
||||
sectors = new SectorsDialog();
|
||||
missions = new MissionDialog();
|
||||
|
||||
Group group = Core.scene.root;
|
||||
|
||||
|
@ -4,13 +4,11 @@ import io.anuke.arc.ApplicationListener;
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectMap;
|
||||
import io.anuke.arc.entities.EntityQuery;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.util.Log;
|
||||
import io.anuke.arc.util.Structs;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.arc.util.Tmp;
|
||||
import io.anuke.mindustry.ai.BlockIndexer;
|
||||
import io.anuke.mindustry.ai.Pathfinder;
|
||||
@ -21,8 +19,9 @@ import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.io.MapIO;
|
||||
import io.anuke.mindustry.maps.*;
|
||||
import io.anuke.mindustry.maps.generation.WorldGenerator;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
import io.anuke.mindustry.maps.Maps;
|
||||
import io.anuke.mindustry.maps.WorldGenerator;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Pos;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@ -32,14 +31,12 @@ import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class World implements ApplicationListener{
|
||||
public final Maps maps = new Maps();
|
||||
public final Sectors sectors = new Sectors();
|
||||
public final WorldGenerator generator = new WorldGenerator();
|
||||
public final BlockIndexer indexer = new BlockIndexer();
|
||||
public final WaveSpawner spawner = new WaveSpawner();
|
||||
public final Pathfinder pathfinder = new Pathfinder();
|
||||
|
||||
private Map currentMap;
|
||||
private Sector currentSector;
|
||||
private Tile[][] tiles;
|
||||
|
||||
private Array<Tile> tempTiles = new Array<>();
|
||||
@ -49,11 +46,6 @@ public class World implements ApplicationListener{
|
||||
maps.load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
sectors.load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(){
|
||||
maps.dispose();
|
||||
@ -88,14 +80,6 @@ public class World implements ApplicationListener{
|
||||
return currentMap;
|
||||
}
|
||||
|
||||
public Sector getSector(){
|
||||
return currentSector;
|
||||
}
|
||||
|
||||
public void setSector(Sector currentSector){
|
||||
this.currentSector = currentSector;
|
||||
}
|
||||
|
||||
public void setMap(Map map){
|
||||
this.currentMap = map;
|
||||
}
|
||||
@ -208,34 +192,7 @@ public class World implements ApplicationListener{
|
||||
return generating;
|
||||
}
|
||||
|
||||
/**Loads up a sector map. This does not call play(), but calls reset().*/
|
||||
public void loadSector(Sector sector){
|
||||
currentSector = sector;
|
||||
state.difficulty = sectors.getDifficulty(sector);
|
||||
state.mode = sector.currentMission().getMode();
|
||||
Time.mark();
|
||||
Time.mark();
|
||||
|
||||
logic.reset();
|
||||
|
||||
beginMapLoad();
|
||||
|
||||
int width = sectorSize, height = sectorSize;
|
||||
|
||||
Tile[][] tiles = createTiles(width, height);
|
||||
|
||||
Map map = new Map("Sector " + sector.x + ", " + sector.y, new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null);
|
||||
setMap(map);
|
||||
|
||||
EntityQuery.resizeTree(0, 0, width * tilesize, height * tilesize);
|
||||
|
||||
generator.generateMap(tiles, sector);
|
||||
|
||||
endMapLoad();
|
||||
}
|
||||
|
||||
public void loadMap(Map map){
|
||||
currentSector = null;
|
||||
beginMapLoad();
|
||||
this.currentMap = map;
|
||||
|
||||
|
@ -26,10 +26,6 @@ public class OverlayRenderer{
|
||||
for(Player player : players){
|
||||
InputHandler input = control.input(player.playerIndex);
|
||||
|
||||
if(world.getSector() != null){
|
||||
world.getSector().currentMission().drawOverlay();
|
||||
}
|
||||
|
||||
if(!input.isDrawing() || player.isDead()) continue;
|
||||
|
||||
Shaders.outline.color.set(Palette.accent);
|
||||
|
@ -92,12 +92,7 @@ public abstract class SaveFileVersion{
|
||||
short width = stream.readShort();
|
||||
short height = stream.readShort();
|
||||
|
||||
if(world.getSector() != null){
|
||||
world.setMap(new Map("Sector " + world.getSector().x + ", " + world.getSector().y, width, height));
|
||||
}else if(world.getMap() == null){
|
||||
world.setMap(new Map("unknown", width, height));
|
||||
}
|
||||
|
||||
world.setMap(new Map("unknown", width, height));
|
||||
world.beginMapLoad();
|
||||
|
||||
Tile[][] tiles = world.createTiles(width, height);
|
||||
|
@ -24,7 +24,6 @@ public class Save16 extends SaveFileVersion{
|
||||
stream.readLong(); //time
|
||||
stream.readLong(); //total playtime
|
||||
stream.readInt(); //build
|
||||
int sector = stream.readInt(); //sector ID
|
||||
|
||||
//general state
|
||||
byte mode = stream.readByte();
|
||||
@ -32,8 +31,6 @@ public class Save16 extends SaveFileVersion{
|
||||
Map map = world.maps.getByName(mapname);
|
||||
world.setMap(map);
|
||||
|
||||
world.setSector(world.sectors.get(sector));
|
||||
|
||||
int wave = stream.readInt();
|
||||
byte difficulty = stream.readByte();
|
||||
float wavetime = stream.readFloat();
|
||||
@ -59,7 +56,6 @@ public class Save16 extends SaveFileVersion{
|
||||
stream.writeLong(Time.millis()); //last saved
|
||||
stream.writeLong(headless ? 0 : control.saves.getTotalPlaytime()); //playtime
|
||||
stream.writeInt(Version.build); //build
|
||||
stream.writeInt(world.getSector() == null ? invalidSector : world.getSector().pos()); //sector ID
|
||||
|
||||
//--GENERAL STATE--
|
||||
stream.writeByte(state.mode.ordinal()); //gamemode
|
||||
|
@ -1,73 +0,0 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import io.anuke.annotations.Annotations.Serialize;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.graphics.Texture;
|
||||
import io.anuke.arc.util.Pack;
|
||||
import io.anuke.mindustry.game.Saves.SaveSlot;
|
||||
import io.anuke.mindustry.game.SpawnGroup;
|
||||
import io.anuke.mindustry.maps.missions.*;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
import static io.anuke.mindustry.Vars.headless;
|
||||
|
||||
@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.*/
|
||||
public boolean complete;
|
||||
/**Slot ID of this sector's save. -1 means no save has been created.*/
|
||||
public int saveID = -1;
|
||||
/**Num of missions in this sector that have been completed so far.*/
|
||||
public int completedMissions;
|
||||
|
||||
/**Display texture. Needs to be disposed.*/
|
||||
public transient Texture texture;
|
||||
/**Missions of this sector-- what needs to be accomplished to unlock it.*/
|
||||
public transient Array<Mission> missions = new Array<>();
|
||||
/**Enemies spawned at this sector.*/
|
||||
public transient Array<SpawnGroup> spawns;
|
||||
/**Difficulty of the sector, measured by calculating distance from origin and applying scaling.*/
|
||||
public transient int difficulty;
|
||||
/**Items the player starts with on this sector.*/
|
||||
public transient Array<ItemStack> startingItems;
|
||||
|
||||
public Mission getDominantMission(){
|
||||
for(Mission mission : missions){
|
||||
if(mission instanceof WaveMission || mission instanceof BattleMission){
|
||||
return mission;
|
||||
}
|
||||
}
|
||||
|
||||
for(Mission mission : missions){
|
||||
if(mission instanceof BlockMission){
|
||||
return mission;
|
||||
}
|
||||
}
|
||||
return missions.first();
|
||||
}
|
||||
|
||||
public Mission currentMission(){
|
||||
return completedMissions >= missions.size ? victoryMission : missions.get(completedMissions);
|
||||
}
|
||||
|
||||
public int getSeed(){
|
||||
return pos();
|
||||
}
|
||||
|
||||
public SaveSlot getSave(){
|
||||
return !hasSave() ? null : control.saves.getByID(saveID);
|
||||
}
|
||||
|
||||
public boolean hasSave(){
|
||||
return !headless && control.saves.getByID(saveID) != null;
|
||||
}
|
||||
|
||||
public int pos(){
|
||||
return Pack.shortInt(x, y);
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.GridMap;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.Liquids;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.content.UnitTypes;
|
||||
import io.anuke.mindustry.content.blocks.CraftingBlocks;
|
||||
import io.anuke.mindustry.content.blocks.ProductionBlocks;
|
||||
import io.anuke.mindustry.content.blocks.UnitBlocks;
|
||||
import io.anuke.mindustry.content.blocks.UpgradeBlocks;
|
||||
import io.anuke.mindustry.entities.units.UnitCommand;
|
||||
import io.anuke.mindustry.maps.missions.*;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
|
||||
import static io.anuke.mindustry.Vars.mobile;
|
||||
|
||||
public class SectorPresets{
|
||||
private final GridMap<SectorPreset> presets = new GridMap<>();
|
||||
private final GridMap<Array<Item>> orePresets = new GridMap<>();
|
||||
|
||||
public SectorPresets(){
|
||||
|
||||
//base tutorial mission
|
||||
add(new SectorPreset(0, 0,
|
||||
TutorialSector.getMissions(),
|
||||
Array.with(Items.copper, Items.coal, Items.lead)));
|
||||
|
||||
//command center mission
|
||||
add(new SectorPreset(0, 1,
|
||||
Array.ofRecursive(
|
||||
Missions.blockRecipe(UnitBlocks.daggerFactory),
|
||||
new UnitMission(UnitTypes.dagger),
|
||||
Missions.blockRecipe(UnitBlocks.commandCenter),
|
||||
new CommandMission(UnitCommand.retreat),
|
||||
new CommandMission(UnitCommand.attack),
|
||||
new BattleMission()
|
||||
),
|
||||
Array.with(Items.copper, Items.lead, Items.coal)));
|
||||
|
||||
//pad mission
|
||||
add(new SectorPreset(0, -2,
|
||||
Array.ofRecursive(
|
||||
Missions.blockRecipe(mobile ? UpgradeBlocks.alphaPad : UpgradeBlocks.dartPad),
|
||||
new MechMission(mobile ? Mechs.alpha : Mechs.dart),
|
||||
new WaveMission(15)
|
||||
),
|
||||
Array.with(Items.copper, Items.lead, Items.coal, Items.titanium)));
|
||||
|
||||
//oil mission
|
||||
add(new SectorPreset(-2, 0,
|
||||
Array.ofRecursive(
|
||||
Missions.blockRecipe(ProductionBlocks.cultivator),
|
||||
Missions.blockRecipe(ProductionBlocks.waterExtractor),
|
||||
new ContentMission(Items.biomatter),
|
||||
Missions.blockRecipe(CraftingBlocks.biomatterCompressor),
|
||||
new ContentMission(Liquids.oil),
|
||||
new BattleMission()
|
||||
),
|
||||
Array.with(Items.copper, Items.lead, Items.coal, Items.titanium)));
|
||||
}
|
||||
|
||||
public Array<Item> getOres(int x, int y){
|
||||
return orePresets.get(x, y);
|
||||
}
|
||||
|
||||
public SectorPreset get(int x, int y){
|
||||
return presets.get(x, y);
|
||||
}
|
||||
|
||||
public GridMap<SectorPreset> getPresets() { return presets; }
|
||||
|
||||
private void add(SectorPreset preset){
|
||||
presets.put(preset.x, preset.y, preset);
|
||||
orePresets.put(preset.x, preset.y, preset.ores);
|
||||
}
|
||||
|
||||
public static class SectorPreset{
|
||||
public final Array<Mission> missions;
|
||||
public final Array<Item> ores;
|
||||
public final int x, y;
|
||||
|
||||
public SectorPreset(int x, int y, Array<Mission> missions, Array<Item> ores){
|
||||
this.missions = missions;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.ores = ores;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,323 +0,0 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.Array.ArrayIterable;
|
||||
import io.anuke.arc.collection.GridMap;
|
||||
import io.anuke.arc.graphics.Pixmap;
|
||||
import io.anuke.arc.graphics.Pixmap.Format;
|
||||
import io.anuke.arc.graphics.Texture;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Geometry;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.util.Log;
|
||||
import io.anuke.arc.util.Pack;
|
||||
import io.anuke.arc.util.async.AsyncExecutor;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.Difficulty;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.io.SaveIO;
|
||||
import io.anuke.mindustry.maps.SectorPresets.SectorPreset;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult;
|
||||
import io.anuke.mindustry.maps.missions.BattleMission;
|
||||
import io.anuke.mindustry.maps.missions.Mission;
|
||||
import io.anuke.mindustry.maps.missions.Missions;
|
||||
import io.anuke.mindustry.maps.missions.WaveMission;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.type.Recipe.RecipeVisibility;
|
||||
import io.anuke.mindustry.world.ColorMapper;
|
||||
import io.anuke.mindustry.world.blocks.Floor;
|
||||
import io.anuke.mindustry.world.blocks.defense.Wall;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Sectors{
|
||||
public static final int sectorImageSize = 32;
|
||||
|
||||
private final GridMap<Sector> grid = new GridMap<>();
|
||||
private final SectorPresets presets = new SectorPresets();
|
||||
private final Array<Item> allOres = Item.getAllOres();
|
||||
private final AsyncExecutor executor = new AsyncExecutor(6);
|
||||
|
||||
public void playSector(Sector sector){
|
||||
if(!headless && sector.hasSave() && SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
sector.getSave().delete();
|
||||
ui.showInfo("$text.save.old");
|
||||
}
|
||||
|
||||
if(!sector.hasSave()){
|
||||
for(Mission mission : sector.missions){
|
||||
mission.reset();
|
||||
}
|
||||
world.loadSector(sector);
|
||||
logic.play();
|
||||
if(!headless){
|
||||
sector.saveID = control.saves.addSave("sector-" + sector.pos()).index;
|
||||
}
|
||||
world.sectors.save();
|
||||
world.setSector(sector);
|
||||
if(!sector.complete) sector.currentMission().onBegin();
|
||||
}else if(SaveIO.breakingVersions.contains(sector.getSave().getBuild())){
|
||||
ui.showInfo("$text.save.old");
|
||||
}else try{
|
||||
sector.getSave().load();
|
||||
world.setSector(sector);
|
||||
state.set(State.playing);
|
||||
if(!sector.complete) sector.currentMission().onBegin();
|
||||
}catch(Exception e){
|
||||
Log.err(e);
|
||||
sector.getSave().delete();
|
||||
|
||||
playSector(sector);
|
||||
|
||||
if(!headless){
|
||||
ui.showError("$text.sector.corrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**If a sector is not yet unlocked, returns null.*/
|
||||
public Sector get(int x, int y){
|
||||
return grid.get(x, y);
|
||||
}
|
||||
|
||||
public Sector get(int position){
|
||||
return grid.get(Pack.leftShort(position), Pack.rightShort(position));
|
||||
}
|
||||
|
||||
public Iterable<Sector> getSectors(){
|
||||
return grid.values();
|
||||
}
|
||||
|
||||
public Difficulty getDifficulty(Sector sector){
|
||||
if(sector.difficulty == 0){
|
||||
return Difficulty.hard;
|
||||
}else if(sector.difficulty < 4){
|
||||
return Difficulty.normal;
|
||||
}else if(sector.difficulty < 9){
|
||||
return Difficulty.hard;
|
||||
}else{
|
||||
return Difficulty.insane;
|
||||
}
|
||||
}
|
||||
|
||||
public Array<Item> getOres(int x, int y){
|
||||
return presets.getOres(x, y) == null ? allOres : presets.getOres(x, y);
|
||||
}
|
||||
|
||||
/**Unlocks a sector. This shows nearby sectors.*/
|
||||
public void completeSector(int x, int y){
|
||||
createSector(x, y);
|
||||
Sector sector = get(x, y);
|
||||
sector.complete = true;
|
||||
|
||||
for(Point2 g : Geometry.d4){
|
||||
createSector(x + g.x, y + g.y);
|
||||
}
|
||||
}
|
||||
|
||||
/**Creates a sector at a location if it is not present, but does not complete it.*/
|
||||
public void createSector(int x, int y){
|
||||
|
||||
if(grid.containsKey(x, y)) return;
|
||||
|
||||
Sector sector = new Sector();
|
||||
sector.x = (short)x;
|
||||
sector.y = (short)y;
|
||||
sector.complete = false;
|
||||
initSector(sector);
|
||||
|
||||
grid.put(sector.x, sector.y, sector);
|
||||
|
||||
if(sector.texture == null){
|
||||
createTexture(sector);
|
||||
}
|
||||
|
||||
if(sector.missions.size == 0){
|
||||
completeSector(sector.x, sector.y);
|
||||
}
|
||||
}
|
||||
|
||||
public void abandonSector(Sector sector){
|
||||
if(sector.hasSave()){
|
||||
sector.getSave().delete();
|
||||
}
|
||||
sector.completedMissions = 0;
|
||||
sector.complete = false;
|
||||
initSector(sector);
|
||||
|
||||
grid.put(sector.x, sector.y, sector);
|
||||
|
||||
createTexture(sector);
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void load(){
|
||||
for(Sector sector : grid.values()){
|
||||
sector.texture.dispose();
|
||||
}
|
||||
grid.clear();
|
||||
|
||||
Array<Sector> out = Core.settings.getObject("sector-data-2", Array.class, Array::new);
|
||||
|
||||
for(Sector sector : out){
|
||||
|
||||
createTexture(sector);
|
||||
initSector(sector);
|
||||
grid.put(sector.x, sector.y, sector);
|
||||
}
|
||||
|
||||
if(out.size == 0){
|
||||
createSector(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
grid.clear();
|
||||
save();
|
||||
createSector(0, 0);
|
||||
}
|
||||
|
||||
public void save(){
|
||||
Array<Sector> out = new Array<>();
|
||||
|
||||
for(Sector sector : grid.values()){
|
||||
if(sector != null && !out.contains(sector, true)){
|
||||
out.add(sector);
|
||||
}
|
||||
}
|
||||
|
||||
Core.settings.putObject("sector-data-2", out);
|
||||
Core.settings.save();
|
||||
}
|
||||
|
||||
private void initSector(Sector sector){
|
||||
sector.difficulty = (int)(Mathf.dst(sector.x, sector.y));
|
||||
|
||||
if(presets.get(sector.x, sector.y) != null){
|
||||
SectorPreset p = presets.get(sector.x, sector.y);
|
||||
sector.missions.addAll(p.missions);
|
||||
sector.x = (short)p.x;
|
||||
sector.y = (short)p.y;
|
||||
}else{
|
||||
generate(sector);
|
||||
}
|
||||
|
||||
sector.spawns = new Array<>();
|
||||
|
||||
for(Mission mission : sector.missions){
|
||||
sector.spawns.addAll(mission.getWaves(sector));
|
||||
}
|
||||
|
||||
//set starter items
|
||||
if(sector.difficulty > 12){ //now with titanium
|
||||
sector.startingItems = Array.with(new ItemStack(Items.copper, 1900), new ItemStack(Items.lead, 500), new ItemStack(Items.densealloy, 470), new ItemStack(Items.silicon, 460), new ItemStack(Items.titanium, 230));
|
||||
}else if(sector.difficulty > 8){ //just more resources
|
||||
sector.startingItems = Array.with(new ItemStack(Items.copper, 1500), new ItemStack(Items.lead, 400), new ItemStack(Items.densealloy, 340), new ItemStack(Items.silicon, 250));
|
||||
}else if(sector.difficulty > 5){ //now with silicon
|
||||
sector.startingItems = Array.with(new ItemStack(Items.copper, 950), new ItemStack(Items.lead, 300), new ItemStack(Items.densealloy, 190), new ItemStack(Items.silicon, 140));
|
||||
}else if(sector.difficulty > 3){ //now with carbide
|
||||
sector.startingItems = Array.with(new ItemStack(Items.copper, 700), new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 130));
|
||||
}else if(sector.difficulty > 2){ //more starter items for faster start
|
||||
sector.startingItems = Array.with(new ItemStack(Items.copper, 400), new ItemStack(Items.lead, 100));
|
||||
}else{ //empty default
|
||||
sector.startingItems = Array.with();
|
||||
}
|
||||
}
|
||||
|
||||
/**Generates a mission for a sector. This is deterministic and the same for each client.*/
|
||||
private void generate(Sector sector){
|
||||
|
||||
//50% chance to get a wave mission
|
||||
if(Mathf.randomSeed(sector.getSeed() + 7) < 0.5){
|
||||
//recipe mission (maybe)
|
||||
addRecipeMission(sector, 3);
|
||||
sector.missions.add(new WaveMission(sector.difficulty*5 + Mathf.randomSeed(sector.getSeed(), 1, 4)*5));
|
||||
}else{
|
||||
//battle missions don't get recipes
|
||||
sector.missions.add(new BattleMission());
|
||||
}
|
||||
|
||||
//possibly add another recipe mission
|
||||
addRecipeMission(sector, 11);
|
||||
|
||||
Generation gen = new Generation(sector, null, sectorSize, sectorSize, null);
|
||||
|
||||
Array<Point2> points = new Array<>();
|
||||
for(Mission mission : sector.missions){
|
||||
points.addAll(mission.getSpawnPoints(gen));
|
||||
}
|
||||
|
||||
GenResult result = new GenResult();
|
||||
|
||||
for(Point2 point : new ArrayIterable<>(points)){
|
||||
world.generator.generateTile(result, sector.x, sector.y, point.x, point.y, true, null, null);
|
||||
if(((Floor)result.floor).isLiquid || result.wall.solid){
|
||||
sector.missions.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addRecipeMission(Sector sector, int offset){
|
||||
//build list of locked recipes to add mission for obtaining it
|
||||
if(Mathf.randomSeed(sector.getSeed() + offset) < 0.5){
|
||||
Array<Recipe> recipes = new Array<>();
|
||||
for(Recipe r : content.recipes()){
|
||||
if(r.result instanceof Wall || (r.visibility != RecipeVisibility.all) || r.cost < 10f) continue;
|
||||
recipes.add(r);
|
||||
}
|
||||
float maxdiff = 8f;
|
||||
recipes.sort((r1, r2) -> Float.compare(r1.cost, r2.cost));
|
||||
int end = (int)(Mathf.clamp(sector.difficulty / maxdiff + 0.25f) * (recipes.size - 1));
|
||||
int start = (int)(Mathf.clamp(sector.difficulty / maxdiff) * (recipes.size / 2f));
|
||||
|
||||
if(recipes.size > 0 && end > start){
|
||||
Recipe recipe = recipes.get(Mathf.randomSeed(sector.getSeed() + 10, start, end));
|
||||
sector.missions.addAll(Missions.blockRecipe(recipe.result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createTexture(Sector sector){
|
||||
if(headless) return; //obviously not created or needed on server
|
||||
|
||||
if(sector.texture != null){
|
||||
sector.texture.dispose();
|
||||
}
|
||||
|
||||
executor.submit(() -> {
|
||||
Pixmap pixmap = new Pixmap(sectorImageSize, sectorImageSize, Format.RGBA8888);
|
||||
GenResult result = new GenResult();
|
||||
GenResult secResult = new GenResult();
|
||||
|
||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
||||
int toX = x * sectorSize / sectorImageSize;
|
||||
int toY = y * sectorSize / sectorImageSize;
|
||||
|
||||
world.generator.generateTile(result, sector.x, sector.y, toX, toY, false, null, null);
|
||||
world.generator.generateTile(secResult, sector.x, sector.y, toX, ((y+1) * sectorSize / sectorImageSize), false, null, null);
|
||||
|
||||
int color = ColorMapper.colorFor(result.floor, result.wall, Team.none, result.elevation, secResult.elevation > result.elevation ? (byte)(1 << 6) : (byte)0);
|
||||
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color);
|
||||
}
|
||||
}
|
||||
|
||||
Core.app.post(() -> {
|
||||
sector.texture = new Texture(pixmap);
|
||||
pixmap.dispose();
|
||||
});
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.blocks.CraftingBlocks;
|
||||
import io.anuke.mindustry.content.blocks.ProductionBlocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.content.blocks.UnitBlocks;
|
||||
import io.anuke.mindustry.maps.missions.BlockMission;
|
||||
import io.anuke.mindustry.maps.missions.ItemMission;
|
||||
import io.anuke.mindustry.maps.missions.Mission;
|
||||
import io.anuke.mindustry.maps.missions.WaveMission;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
/**Just a class for returning the list of tutorial missions.*/
|
||||
public class TutorialSector{
|
||||
private static int droneIndex;
|
||||
|
||||
public static Array<Mission> getMissions(){
|
||||
/*
|
||||
Array<Mission> missions = Array.with(
|
||||
new ItemMission(Items.copper, 60).setMessage("$tutorial.begin"),
|
||||
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drill"),
|
||||
|
||||
new BlockMission(DistributionBlocks.conveyor).setShowComplete(false).setMessage("$tutorial.conveyor"),
|
||||
|
||||
new ItemMission(Items.copper, 100).setMessage("$tutorial.morecopper"),
|
||||
|
||||
new BlockMission(TurretBlocks.duo).setMessage("$tutorial.turret"),
|
||||
/
|
||||
//new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.drillturret"),
|
||||
|
||||
// Create a wave mission which spawns the core at 60, 60 rather than in the center of the map
|
||||
new WaveMission(2, 60, 60).setMessage("$tutorial.waves"),
|
||||
|
||||
new ItemMission(Items.lead, 150).setMessage("$tutorial.lead"),
|
||||
new ItemMission(Items.copper, 250).setMessage("$tutorial.morecopper"),
|
||||
|
||||
new BlockMission(CraftingBlocks.smelter).setMessage("$tutorial.smelter"),
|
||||
|
||||
//drills for smelter
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
|
||||
new ItemMission(Items.densealloy, 20).setMessage("$tutorial.densealloy"),
|
||||
|
||||
new MarkerBlockMission(CraftingBlocks.siliconsmelter).setMessage("$tutorial.siliconsmelter"),
|
||||
|
||||
//coal line
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.silicondrill"),
|
||||
|
||||
//sand line
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
|
||||
|
||||
new BlockMission(PowerBlocks.combustionGenerator).setMessage("$tutorial.generator"),
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill).setMessage("$tutorial.generatordrill"),
|
||||
new BlockMission(PowerBlocks.powerNode).setMessage("$tutorial.node"),
|
||||
//TODO fix positions
|
||||
new ConditionMission(Core.bundle.get("text.mission.linknode"), () -> world.tile(54, 52).entity != null && world.tile(54, 52).entity.power != null && world.tile(54, 52).entity.power.amount >= 0.01f)
|
||||
.setMessage("$tutorial.nodelink"),
|
||||
|
||||
new ItemMission(Items.silicon, 70).setMessage("$tutorial.silicon"),
|
||||
|
||||
new BlockMission(UnitBlocks.daggerFactory).setMessage("$tutorial.daggerfactory"),
|
||||
|
||||
//power for dagger factory
|
||||
new BlockMission(PowerBlocks.powerNode),
|
||||
new BlockMission(PowerBlocks.powerNode),
|
||||
|
||||
new UnitMission(UnitTypes.dagger).setMessage("$tutorial.dagger"),
|
||||
new ActionMission(TutorialSector::generateBase),
|
||||
new BattleMission(){
|
||||
public void generate(Generation gen){} //no
|
||||
}.setMessage("$tutorial.battle")
|
||||
);
|
||||
|
||||
//find drone marker mission
|
||||
for(int i = 0; i < missions.size; i++){
|
||||
if(missions.get(i) instanceof MarkerBlockMission){
|
||||
droneIndex = i;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
return Array.with(
|
||||
//intentionally unlocalized
|
||||
new ItemMission(Items.copper, 50).setMessage("An updated tutorial will return next build.\nFor now, you'll have to deal with... this."),
|
||||
|
||||
new BlockMission(ProductionBlocks.mechanicalDrill),
|
||||
|
||||
new ItemMission(Items.copper, 100),
|
||||
new ItemMission(Items.lead, 50),
|
||||
|
||||
new BlockMission(CraftingBlocks.smelter),
|
||||
new ItemMission(Items.densealloy, 10),
|
||||
new WaveMission(5)
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean supressDrone(){
|
||||
return world.getSector() != null && world.getSector().x == 0 && world.getSector().y == 0 && world.getSector().completedMissions < droneIndex;
|
||||
}
|
||||
|
||||
private static void generateBase(){
|
||||
int x = sectorSize - 50, y = sectorSize - 50;
|
||||
world.setBlock(world.tile(x, y), StorageBlocks.core, waveTeam);
|
||||
world.setBlock(world.tile(x - 1, y + 2), UnitBlocks.daggerFactory, waveTeam);
|
||||
world.setBlock(world.tile(x - 1, y - 3), UnitBlocks.daggerFactory, waveTeam);
|
||||
|
||||
//since placed() is not called here, add core manually
|
||||
state.teams.get(waveTeam).cores.add(world.tile(x, y));
|
||||
}
|
||||
|
||||
private static class MarkerBlockMission extends BlockMission{
|
||||
public MarkerBlockMission(Block block){
|
||||
super(block);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package io.anuke.mindustry.maps.generation;
|
||||
package io.anuke.mindustry.maps;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.IntArray;
|
||||
@ -15,11 +15,7 @@ import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.content.blocks.OreBlocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.Map;
|
||||
import io.anuke.mindustry.maps.MapTileData;
|
||||
import io.anuke.mindustry.maps.MapTileData.TileDataMarker;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
import io.anuke.mindustry.maps.missions.Mission;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Pos;
|
||||
@ -141,7 +137,6 @@ public class WorldGenerator{
|
||||
|
||||
public void playRandomMap(){
|
||||
ui.loadLogic(() -> {
|
||||
world.setSector(null);
|
||||
logic.reset();
|
||||
|
||||
int sx = (short)Mathf.range(Short.MAX_VALUE/2);
|
||||
@ -246,57 +241,6 @@ public class WorldGenerator{
|
||||
}
|
||||
}
|
||||
|
||||
public void generateMap(Tile[][] tiles, Sector sector){
|
||||
int width = tiles.length, height = tiles[0].length;
|
||||
RandomXS128 rnd = new RandomXS128(sector.getSeed());
|
||||
Generation gena = new Generation(sector, tiles, tiles.length, tiles[0].length, rnd);
|
||||
Array<Point2> spawnpoints = sector.currentMission().getSpawnPoints(gena);
|
||||
Array<Item> ores = world.sectors.getOres(sector.x, sector.y);
|
||||
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
GenResult result = generateTile(this.result, sector.x, sector.y, x, y, true, spawnpoints, ores);
|
||||
Tile tile = new Tile(x, y, result.floor.id, result.wall.id, (byte)0, (byte)0, result.elevation);
|
||||
tiles[x][y] = tile;
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
Tile tile = tiles[x][y];
|
||||
|
||||
byte elevation = tile.getElevation();
|
||||
|
||||
for(Point2 point : Geometry.d4){
|
||||
if(!Structs.inBounds(x + point.x, y + point.y, width, height)) continue;
|
||||
if(tiles[x + point.x][y + point.y].getElevation() < elevation){
|
||||
|
||||
if(sim2.octaveNoise2D(1, 1, 1.0 / 8, x, y) > 0.8){
|
||||
tile.setElevation(-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int x = 0; x < tiles.length; x++){
|
||||
for(int y = 0; y < tiles[0].length; y++){
|
||||
Tile tile = tiles[x][y];
|
||||
|
||||
tile.updateOcclusion();
|
||||
}
|
||||
}
|
||||
|
||||
Generation gen = new Generation(sector, tiles, tiles.length, tiles[0].length, random);
|
||||
|
||||
for(Mission mission : sector.missions){
|
||||
mission.generate(gen);
|
||||
}
|
||||
|
||||
prepareTiles(tiles);
|
||||
}
|
||||
|
||||
public GenResult generateTile(int sectorX, int sectorY, int localX, int localY){
|
||||
return generateTile(sectorX, sectorY, localX, localY, true);
|
||||
}
|
@ -1,219 +0,0 @@
|
||||
package io.anuke.mindustry.maps.generation;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.IntIntMap;
|
||||
import io.anuke.arc.function.BiFunction;
|
||||
import io.anuke.arc.function.IntPositionConsumer;
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.function.TriFunction;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Geometry;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.Liquids;
|
||||
import io.anuke.mindustry.content.blocks.*;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Edges;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.PowerBlock;
|
||||
import io.anuke.mindustry.world.blocks.defense.Door;
|
||||
import io.anuke.mindustry.world.blocks.defense.ForceProjector;
|
||||
import io.anuke.mindustry.world.blocks.defense.MendProjector;
|
||||
import io.anuke.mindustry.world.blocks.defense.Wall;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.ItemTurret;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.LiquidTurret;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.PowerTurret;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.Turret;
|
||||
import io.anuke.mindustry.world.blocks.power.NuclearReactor;
|
||||
import io.anuke.mindustry.world.blocks.power.PowerGenerator;
|
||||
import io.anuke.mindustry.world.blocks.power.SolarGenerator;
|
||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
||||
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
||||
import io.anuke.mindustry.world.blocks.units.UnitFactory;
|
||||
|
||||
import static io.anuke.mindustry.Vars.content;
|
||||
|
||||
public class FortressGenerator{
|
||||
private final static int coreDst = 60;
|
||||
|
||||
private int enemyX, enemyY, coreX, coreY;
|
||||
private Team team;
|
||||
private Generation gen;
|
||||
|
||||
public void generate(Generation gen, Team team, int coreX, int coreY, int enemyX, int enemyY){
|
||||
this.enemyX = enemyX;
|
||||
this.enemyY = enemyY;
|
||||
this.coreX = coreX;
|
||||
this.coreY = coreY;
|
||||
this.gen = gen;
|
||||
this.team = team;
|
||||
|
||||
gen();
|
||||
}
|
||||
|
||||
void gen(){
|
||||
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
|
||||
gen.random.nextBoolean();
|
||||
|
||||
float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(0.25f), 0f, 0.9999f);
|
||||
float dscl2 = Mathf.clamp(0.5f + gen.sector.difficulty / 20f + gen.random.range(0.1f), 0f, 1.5f);
|
||||
|
||||
Array<Block> turrets = find(b -> b instanceof ItemTurret);
|
||||
Array<Block> powerTurrets = find(b -> b instanceof PowerTurret);
|
||||
Array<Block> walls = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 1);
|
||||
|
||||
Block wall = walls.get((int)(difficultyScl * walls.size));
|
||||
|
||||
Turret powerTurret = (Turret) powerTurrets.get((int)(difficultyScl * powerTurrets.size));
|
||||
Turret bigTurret = (Turret) turrets.get(Mathf.clamp((int)((difficultyScl+0.2f+gen.random.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||
Turret turret1 = (Turret) turrets.get(Mathf.clamp((int)((difficultyScl+gen.random.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||
Turret turret2 = (Turret) turrets.get(Mathf.clamp((int)((difficultyScl+gen.random.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||
float placeChance = difficultyScl*0.75f+0.25f;
|
||||
|
||||
IntIntMap ammoPerType = new IntIntMap();
|
||||
for(Block turret : turrets){
|
||||
if(!(turret instanceof ItemTurret)) continue;
|
||||
ItemTurret t = (ItemTurret)turret;
|
||||
int size = t.getAmmoTypes().length;
|
||||
ammoPerType.put(t.id, Mathf.clamp((int)(size* difficultyScl) + gen.random.range(1), 0, size - 1));
|
||||
}
|
||||
|
||||
TriFunction<Tile, Block, Predicate<Tile>, Boolean> checker = (current, block, pred) -> {
|
||||
for(Point2 point : Edges.getEdges(block.size)){
|
||||
Tile tile = gen.tile(current.x + point.x, current.y + point.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
if(tile.getTeamID() == team.ordinal() && pred.test(tile)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
BiFunction<Block, Predicate<Tile>, IntPositionConsumer> seeder = (block, pred) -> (x, y) -> {
|
||||
if(gen.canPlace(x, y, block) && ((block instanceof Wall && block.size == 1) || gen.random.chance(placeChance)) && checker.get(gen.tile(x, y), block, pred)){
|
||||
gen.setBlock(x, y, block, team);
|
||||
}
|
||||
};
|
||||
|
||||
BiFunction<Block, Float, IntPositionConsumer> placer = (block, chance) -> (x, y) -> {
|
||||
if(gen.canPlace(x, y, block) && gen.random.chance(chance)){
|
||||
gen.setBlock(x, y, block, team);
|
||||
}
|
||||
};
|
||||
|
||||
Array<IntPositionConsumer> passes = Array.with(
|
||||
//initial seeding solar panels
|
||||
placer.get(PowerBlocks.largeSolarPanel, 0.001f),
|
||||
|
||||
//extra seeding
|
||||
seeder.get(PowerBlocks.solarPanel, tile -> tile.block() == PowerBlocks.largeSolarPanel && gen.random.chance(0.3)),
|
||||
|
||||
//coal gens
|
||||
seeder.get(PowerBlocks.combustionGenerator, tile -> tile.block() instanceof SolarGenerator && gen.random.chance(0.2)),
|
||||
|
||||
//water extractors
|
||||
seeder.get(ProductionBlocks.waterExtractor, tile -> tile.block() instanceof NuclearReactor && gen.random.chance(0.5)),
|
||||
|
||||
//mend projectors
|
||||
seeder.get(DefenseBlocks.mendProjector, tile -> tile.block() instanceof PowerGenerator && gen.random.chance(0.04)),
|
||||
|
||||
//power turrets
|
||||
seeder.get(powerTurret, tile -> tile.block() instanceof PowerGenerator && gen.random.chance(0.04)),
|
||||
|
||||
//repair point
|
||||
seeder.get(UnitBlocks.repairPoint, tile -> tile.block() instanceof PowerGenerator && gen.random.chance(0.1)),
|
||||
|
||||
//turrets1
|
||||
seeder.get(turret1, tile -> tile.block() instanceof PowerBlock && gen.random.chance(0.22 - turret1.size*0.02)),
|
||||
|
||||
//turrets2
|
||||
seeder.get(turret2, tile -> tile.block() instanceof PowerBlock && gen.random.chance(0.12 - turret2.size*0.02)),
|
||||
|
||||
//shields
|
||||
seeder.get(DefenseBlocks.forceProjector, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof UnitFactory) && gen.random.chance(0.2 * dscl2)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.daggerFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.3 * dscl2)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.wraithFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.3 * dscl2)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.titanFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.23 * dscl2)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.ghoulFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && gen.random.chance(0.23 * dscl2)),
|
||||
|
||||
//vaults
|
||||
seeder.get(StorageBlocks.vault, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof ForceProjector) && gen.random.chance(0.4)),
|
||||
|
||||
//big turrets
|
||||
seeder.get(bigTurret, tile -> tile.block() instanceof StorageBlock && gen.random.chance(0.65)),
|
||||
|
||||
//walls
|
||||
(x, y) -> {
|
||||
if(!gen.canPlace(x, y, wall)) return;
|
||||
|
||||
for(Point2 point : Geometry.d8){
|
||||
Tile tile = gen.tile(x + point.x, y + point.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
if(tile.getTeamID() == team.ordinal() && !(tile.block() instanceof Wall) && !(tile.block() instanceof UnitFactory)){
|
||||
gen.setBlock(x, y, wall, team);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//mines
|
||||
placer.get(DefenseBlocks.shockMine, 0.02f * difficultyScl),
|
||||
|
||||
//fill up turrets w/ ammo
|
||||
(x, y) -> {
|
||||
Tile tile = gen.tile(x, y);
|
||||
Block block = tile.block();
|
||||
|
||||
if(block instanceof PowerTurret){
|
||||
tile.entity.power.satisfaction = 1.0f;
|
||||
}else if(block instanceof ItemTurret){
|
||||
ItemTurret turret = (ItemTurret)block;
|
||||
AmmoType[] type = turret.getAmmoTypes();
|
||||
int index = ammoPerType.get(block.id, 0);
|
||||
block.handleStack(type[index].item, block.acceptStack(type[index].item, 1000, tile, null), tile, null);
|
||||
}else if(block instanceof NuclearReactor){
|
||||
tile.entity.items.add(Items.thorium, 30);
|
||||
}else if(block instanceof LiquidTurret){
|
||||
tile.entity.liquids.add(Liquids.water, tile.block().liquidCapacity);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for(IntPositionConsumer i : passes){
|
||||
for(int x = 0; x < gen.width; x++){
|
||||
for(int y = 0; y < gen.height; y++){
|
||||
if(Mathf.dst(x, y, enemyX, enemyY) > coreDst){
|
||||
continue;
|
||||
}
|
||||
|
||||
i.accept(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Array<Block> find(Predicate<Block> pred){
|
||||
Array<Block> out = new Array<>();
|
||||
for(Block block : content.blocks()){
|
||||
if(pred.test(block) && Recipe.getByResult(block) != null){
|
||||
out.add(block);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
package io.anuke.mindustry.maps.generation;
|
||||
|
||||
import io.anuke.arc.math.RandomXS128;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.production.Drill;
|
||||
import io.anuke.arc.util.Structs;
|
||||
|
||||
public class Generation{
|
||||
public final Sector sector;
|
||||
public final Tile[][] tiles;
|
||||
public final int width, height;
|
||||
public final RandomXS128 random;
|
||||
|
||||
public Generation(Sector sector, Tile[][] tiles, int width, int height, RandomXS128 random){
|
||||
this.sector = sector;
|
||||
this.tiles = tiles;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
Tile tile(int x, int y){
|
||||
if(!Structs.inBounds(x, y, tiles)){
|
||||
return null;
|
||||
}
|
||||
return tiles[x][y];
|
||||
}
|
||||
|
||||
Item drillItem(int x, int y, Drill block){
|
||||
if(block.isMultiblock()){
|
||||
Item result = null;
|
||||
int offsetx = -(block.size - 1) / 2;
|
||||
int offsety = -(block.size - 1) / 2;
|
||||
|
||||
for(int dx = 0; dx < block.size; dx++){
|
||||
for(int dy = 0; dy < block.size; dy++){
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if(!Structs.inBounds(worldx, worldy, tiles)){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!block.isValid(tiles[worldx][worldy]) || tiles[worldx][worldy].floor().drops == null) continue;
|
||||
|
||||
Item drop = tiles[worldx][worldy].floor().drops.item;
|
||||
|
||||
if(result == null || drop.id < result.id){
|
||||
result = drop;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}else{
|
||||
return tiles[x][y].floor().drops == null ? null : tiles[x][y].floor().drops.item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean canPlace(int x, int y, Block block){
|
||||
if(block.isMultiblock()){
|
||||
int offsetx = -(block.size - 1) / 2;
|
||||
int offsety = -(block.size - 1) / 2;
|
||||
|
||||
for(int dx = 0; dx < block.size; dx++){
|
||||
for(int dy = 0; dy < block.size; dy++){
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if(!Structs.inBounds(worldx, worldy, tiles) || !tiles[worldx][worldy].block().alwaysReplace || tiles[worldx][worldy].floor().isLiquid){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
return tiles[x][y].block().alwaysReplace && !tiles[x][y].floor().isLiquid;
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlock(int x, int y, Block block, Team team){
|
||||
tiles[x][y].setBlock(block, team);
|
||||
if(block.isMultiblock()){
|
||||
int offsetx = -(block.size - 1) / 2;
|
||||
int offsety = -(block.size - 1) / 2;
|
||||
|
||||
for(int dx = 0; dx < block.size; dx++){
|
||||
for(int dy = 0; dy < block.size; dy++){
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if(!(worldx == x && worldy == y) && Structs.inBounds(worldx, worldy, tiles)){
|
||||
Tile toplace = tiles[worldx][worldy];
|
||||
if(toplace != null){
|
||||
toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety));
|
||||
toplace.setTeam(team);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
|
||||
/**A mission which simply runs a single action and is completed instantly.*/
|
||||
public class ActionMission extends Mission{
|
||||
protected Runnable runner;
|
||||
|
||||
public ActionMission(Runnable runner){
|
||||
this.runner = runner;
|
||||
}
|
||||
|
||||
public ActionMission(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(){
|
||||
runner.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return Core.bundle.get("text.loading");
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.mindustry.Vars;
|
||||
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.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.defaultTeam;
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
|
||||
public class BattleMission extends MissionWithStartingCore{
|
||||
final int spacing = 30;
|
||||
public static final int defaultXCorePos = 50;
|
||||
public static final int defaultYCorePos = 50;
|
||||
|
||||
/** Creates a battle mission with the player core being at (@defaultXCorePos, @defaultYCorePos) */
|
||||
public BattleMission(){
|
||||
this(defaultXCorePos, defaultYCorePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wave survival with the player core being at a custom location.
|
||||
* @param xCorePos The X coordinate of the custom core position.
|
||||
* @param yCorePos The Y coordinate of the custom core position.
|
||||
*/
|
||||
public BattleMission(int xCorePos, int yCorePos){
|
||||
super(xCorePos, yCorePos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(){
|
||||
return "icon-mission-battle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameMode getMode(){
|
||||
return GameMode.attack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return Core.bundle.get("text.mission.battle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array<Point2> getSpawnPoints(Generation gen){
|
||||
return Array.with(new Point2(50, 50), new Point2(gen.width - 1 - spacing, gen.height - 1 - spacing));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Generation gen){
|
||||
generateCoreAtFirstSpawnPoint(gen, defaultTeam);
|
||||
|
||||
if(state.teams.get(defaultTeam).cores.size == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
Tile core = state.teams.get(defaultTeam).cores.first();
|
||||
int enx = gen.width - 1 - spacing;
|
||||
int eny = gen.height - 1 - spacing;
|
||||
new FortressGenerator().generate(gen, Team.red, core.x, core.y, enx, eny);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
for(Team team : Vars.state.teams.enemiesOf(Vars.defaultTeam)){
|
||||
if(Vars.state.teams.isActive(team)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
import io.anuke.arc.math.Angles;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class BlockLocMission extends Mission{
|
||||
private final Block block;
|
||||
private final int x, y, rotation;
|
||||
|
||||
public BlockLocMission(Block block, int x, int y, int rotation){
|
||||
this.block = block;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public BlockLocMission(Block block, int x, int y){
|
||||
this.block = block;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOverlay(){
|
||||
Lines.stroke(2f);
|
||||
|
||||
Draw.color(Palette.accentBack);
|
||||
Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1f, block.size * tilesize/2f + 1f+ Mathf.absin(Time.time(), 6f, 2f));
|
||||
|
||||
Draw.color(Palette.accent);
|
||||
Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize/2f + 1f+ Mathf.absin(Time.time(), 6f, 2f));
|
||||
|
||||
|
||||
if(block.rotate){
|
||||
Draw.colorl(0.4f);
|
||||
Draw.rect(Core.atlas.find("icon-arrow"), x * tilesize + block.offset(), y * tilesize + block.offset() - 1f, rotation*90);
|
||||
Draw.colorl(0.6f);
|
||||
Draw.rect(Core.atlas.find("icon-arrow"), x * tilesize + block.offset(), y * tilesize + block.offset(), rotation*90);
|
||||
}
|
||||
|
||||
float rot = players[0].angleTo(x * tilesize + block.offset(), y * tilesize + block.offset());
|
||||
float len = 12f;
|
||||
|
||||
Draw.color(Palette.accentBack);
|
||||
Draw.rect(Core.atlas.find("icon-arrow"), players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len), rot);
|
||||
Draw.color(Palette.accent);
|
||||
Draw.rect(Core.atlas.find("icon-arrow"), players[0].x + Angles.trnsx(rot, len), players[0].y + Angles.trnsy(rot, len) + 1f, rot);
|
||||
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
return world.tile(x, y).block() == block && (!block.rotate || world.tile(x,y).getRotation() == rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return Core.bundle.format("text.mission.block", block.formalName);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
|
||||
/**A mission in which the player must place a block somewhere.*/
|
||||
public class BlockMission extends ContentMission{
|
||||
|
||||
public BlockMission(Block block) {
|
||||
super(Recipe.getByResult(block));
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.entities.units.UnitCommand;
|
||||
|
||||
public class CommandMission extends Mission{
|
||||
private final UnitCommand command;
|
||||
|
||||
public CommandMission(UnitCommand command){
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
for(BaseUnit unit : Vars.unitGroups[Vars.defaultTeam.ordinal()].all()){
|
||||
if(unit.isCommanded() && unit.getCommand() == command){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return Core.bundle.format("text.mission.command", command.localized());
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.function.BooleanProvider;
|
||||
|
||||
public class ConditionMission extends Mission{
|
||||
private final BooleanProvider complete;
|
||||
private final String display;
|
||||
|
||||
public ConditionMission(String display, BooleanProvider complete){
|
||||
this.complete = complete;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
return complete.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return display;
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
|
||||
public class ContentMission extends Mission {
|
||||
private final UnlockableContent content;
|
||||
private boolean done;
|
||||
|
||||
public ContentMission(UnlockableContent content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentUsed(UnlockableContent content) {
|
||||
if(content == this.content){
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return done;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
done = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString() {
|
||||
return Core.bundle.format("text.mission.create", content.localizedName());
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
|
||||
/**A mission that is completed when the player obtains items in their core.*/
|
||||
public class ItemMission extends Mission{
|
||||
private final Item item;
|
||||
private final int amount;
|
||||
|
||||
public ItemMission(Item item, int amount){
|
||||
this.item = item;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
for(Tile tile : state.teams.get(Vars.defaultTeam).cores){
|
||||
if(tile.entity.items.has(item, amount)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
TileEntity core = Vars.players[0].getClosestCore();
|
||||
if(core == null) return "imminent doom";
|
||||
return Core.bundle.format("text.mission.resource", item.localizedName(), core.items.get(item), amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String menuDisplayString(){
|
||||
return Core.bundle.format("text.mission.resource.menu", item.localizedName(), amount);
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.math.geom.Bresenham2;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
|
||||
public class LineBlockMission extends Mission{
|
||||
private Array<BlockLocMission> points = new Array<>();
|
||||
private int completeIndex;
|
||||
|
||||
public LineBlockMission(Block block, int x1, int y1, int x2, int y2, int rotation){
|
||||
Array<Point2> points = new Bresenham2().line(x1, y1, x2, y2);
|
||||
for(Point2 point : points){
|
||||
this.points.add(new BlockLocMission(block, point.x, point.y, rotation));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
while(completeIndex < points.size && points.get(completeIndex).isComplete()){
|
||||
completeIndex ++;
|
||||
}
|
||||
return completeIndex >= points.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOverlay(){
|
||||
if(completeIndex < points.size){
|
||||
points.get(completeIndex).drawOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(){
|
||||
completeIndex = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
if(completeIndex < points.size){
|
||||
return points.get(completeIndex).displayString();
|
||||
}
|
||||
return points.first().displayString();
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.type.Mech;
|
||||
|
||||
public class MechMission extends Mission{
|
||||
private final Mech mech;
|
||||
|
||||
public MechMission(Mech mech){
|
||||
this.mech = mech;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
for(Player player : Vars.playerGroup.all()){
|
||||
if(player.mech == mech){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return Core.bundle.format("text.mission.mech", mech.localizedName());
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.game.SpawnGroup;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
|
||||
import static io.anuke.mindustry.Vars.headless;
|
||||
import static io.anuke.mindustry.Vars.ui;
|
||||
|
||||
public abstract class Mission{
|
||||
private String extraMessage;
|
||||
private boolean showComplete = true;
|
||||
|
||||
public abstract boolean isComplete();
|
||||
|
||||
/**Returns the string that is displayed in-game near the menu.*/
|
||||
public abstract String displayString();
|
||||
|
||||
/**Returns the info string displayed in the sector dialog (menu)*/
|
||||
public String menuDisplayString(){
|
||||
return displayString();
|
||||
}
|
||||
|
||||
public String getIcon(){
|
||||
return "icon-mission-defense";
|
||||
}
|
||||
|
||||
public GameMode getMode(){
|
||||
return GameMode.attack;
|
||||
}
|
||||
|
||||
/**Sets the message displayed on mission begin. Returns this mission for chaining.*/
|
||||
public Mission setMessage(String message){
|
||||
this.extraMessage = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Mission setShowComplete(boolean complete){
|
||||
this.showComplete = complete;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**Called when a specified piece of content is 'used' by a block.*/
|
||||
public void onContentUsed(UnlockableContent content){
|
||||
|
||||
}
|
||||
|
||||
/**Draw mission overlay.*/
|
||||
public void drawOverlay(){
|
||||
|
||||
}
|
||||
|
||||
public void update(){
|
||||
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
|
||||
}
|
||||
|
||||
/**Shows the unique sector message.*/
|
||||
public void showMessage(){
|
||||
if(!headless && extraMessage != null){
|
||||
ui.hudfrag.showTextDialog(extraMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMessage(){
|
||||
return extraMessage != null;
|
||||
}
|
||||
|
||||
public void onBegin(){
|
||||
Time.runTask(60f, this::showMessage);
|
||||
}
|
||||
|
||||
public void onComplete(){
|
||||
if(showComplete && !headless){
|
||||
ui.hudfrag.showToast("[LIGHT_GRAY]"+menuDisplayString() + ":\n" + Core.bundle.get("text.mission.complete"));
|
||||
}
|
||||
}
|
||||
|
||||
public void display(Table table){
|
||||
table.add(displayString());
|
||||
}
|
||||
|
||||
public Array<SpawnGroup> getWaves(Sector sector){
|
||||
return new Array<>();
|
||||
}
|
||||
|
||||
public Array<Point2> getSpawnPoints(Generation gen){
|
||||
return Array.with();
|
||||
}
|
||||
|
||||
public void generate(Generation gen){}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
|
||||
public abstract class MissionWithStartingCore extends Mission{
|
||||
/** Stores a custom starting location for the core, or null if the default calculation (map center) shall be used. */
|
||||
private final Point2 customStartingPoint;
|
||||
|
||||
/** Default constructor. Missions created this way will have a player starting core in the center of the map. */
|
||||
MissionWithStartingCore(){
|
||||
this.customStartingPoint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mission with a core on a non-default location.
|
||||
* @param xCorePos The x coordinate of the custom core position.
|
||||
* @param yCorePos The y coordinate of the custom core position.
|
||||
*/
|
||||
MissionWithStartingCore(int xCorePos, int yCorePos){
|
||||
this.customStartingPoint = new Point2(xCorePos, yCorePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a player core based on generation parameters.
|
||||
* @param gen The generation parameters which provide the map size.
|
||||
* @param team The team to generate the core for.
|
||||
*/
|
||||
public void generateCoreAtFirstSpawnPoint(Generation gen, Team team){
|
||||
Array<Point2> spawnPoints = getSpawnPoints(gen);
|
||||
if(spawnPoints == null || spawnPoints.size == 0){
|
||||
throw new IllegalArgumentException("A MissionWithStartingCore subclass did not provide a spawn point in getSpawnPoints(). However, at least one point must always be provided.");
|
||||
}
|
||||
|
||||
Tile startingCoreTile = gen.tiles[spawnPoints.first().x][spawnPoints.first().y];
|
||||
startingCoreTile.setBlock(StorageBlocks.core);
|
||||
startingCoreTile.setTeam(team);
|
||||
state.teams.get(team).cores.add(startingCoreTile);
|
||||
|
||||
//makes sure there's a flat area around core
|
||||
for(int dx = -2; dx <= 2; dx++){
|
||||
for(int dy = -2; dy <= 2; dy++){
|
||||
gen.tiles[startingCoreTile.x + dx][startingCoreTile.y + dy].setElevation(startingCoreTile.getElevation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the spawn point in the center of the map or at a custom location which was provided through the constructor.
|
||||
* @param gen The generation parameters which provide the map size.
|
||||
* @return The center of the map or a custom location.
|
||||
* @implNote Must return an array with at least one entry.
|
||||
*/
|
||||
@Override
|
||||
public Array<Point2> getSpawnPoints(Generation gen){
|
||||
if(this.customStartingPoint == null){
|
||||
return Array.with(new Point2(gen.width / 2, gen.height / 2));
|
||||
}else{
|
||||
return Array.with(this.customStartingPoint);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
|
||||
public class Missions{
|
||||
|
||||
/**Returns an array of missions to obtain the items needed to make this block.
|
||||
* This array includes a mission to place this block.*/
|
||||
public static Array<Mission> blockRecipe(Block block){
|
||||
Recipe recipe = Recipe.getByResult(block);
|
||||
|
||||
Array<Mission> out = new Array<>();
|
||||
for(ItemStack stack : recipe.requirements){
|
||||
out.add(new ItemMission(stack.item, stack.amount));
|
||||
}
|
||||
out.add(new BlockMission(block));
|
||||
return out;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.entities.units.UnitType;
|
||||
|
||||
public class UnitMission extends Mission{
|
||||
private final UnitType type;
|
||||
|
||||
public UnitMission(UnitType type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
for(BaseUnit unit : Vars.unitGroups[Vars.defaultTeam.ordinal()].all()){
|
||||
if(unit.getType() == type){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return Core.bundle.format("text.mission.unit", type.localizedName());
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
|
||||
public class VictoryMission extends 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){
|
||||
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package io.anuke.mindustry.maps.missions;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
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 static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class WaveMission extends MissionWithStartingCore{
|
||||
private final int target;
|
||||
|
||||
/**
|
||||
* Creates a wave survival mission with the player core being in the center of the map.
|
||||
* @param target The number of waves to be survived.
|
||||
*/
|
||||
public WaveMission(int target){
|
||||
super();
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wave survival with the player core being at a custom location.
|
||||
* @param target The number of waves to be survived.
|
||||
* @param xCorePos The X coordinate of the custom core position.
|
||||
* @param yCorePos The Y coordinate of the custom core position.
|
||||
*/
|
||||
public WaveMission(int target, int xCorePos, int yCorePos){
|
||||
super(xCorePos, yCorePos);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array<SpawnGroup> getWaves(Sector sector){
|
||||
return Waves.getSpawns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Generation gen){
|
||||
generateCoreAtFirstSpawnPoint(gen, Team.blue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBegin(){
|
||||
super.onBegin();
|
||||
|
||||
world.pathfinder.activateTeamPath(waveTeam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameMode getMode(){
|
||||
return GameMode.waves;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayString(){
|
||||
return state.wave > target ?
|
||||
Core.bundle.format(
|
||||
state.enemies() > 1 ?
|
||||
"text.mission.wave.enemies" :
|
||||
"text.mission.wave.enemy", target, target, state.enemies()) :
|
||||
Core.bundle.format("text.mission.wave", state.wave, target, (int)(state.wavetime/60));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String menuDisplayString(){
|
||||
return Core.bundle.format("text.mission.wave.menu", target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(state.wave > target){
|
||||
state.mode = GameMode.attack;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(){
|
||||
return state.wave > target && state.enemies() == 0;
|
||||
}
|
||||
}
|
@ -32,8 +32,6 @@ public class NetworkIO{
|
||||
//--GENERAL STATE--
|
||||
stream.writeByte(state.mode.ordinal()); //gamemode
|
||||
stream.writeUTF(world.getMap().name); //map name
|
||||
stream.writeInt(world.getSector() == null ? invalidSector : world.getSector().pos()); //sector ID
|
||||
stream.writeInt(world.getSector() == null ? 0 : world.getSector().completedMissions);
|
||||
|
||||
//write tags
|
||||
ObjectMap<String, String> tags = world.getMap().meta.tags;
|
||||
@ -126,16 +124,6 @@ public class NetworkIO{
|
||||
//general state
|
||||
byte mode = stream.readByte();
|
||||
String map = stream.readUTF();
|
||||
int sector = stream.readInt();
|
||||
int missions = stream.readInt();
|
||||
|
||||
if(sector != invalidSector){
|
||||
world.sectors.createSector(Pack.leftShort(sector), Pack.rightShort(sector));
|
||||
world.setSector(world.sectors.get(sector));
|
||||
world.getSector().completedMissions = missions;
|
||||
}else{
|
||||
world.setSector(null);
|
||||
}
|
||||
|
||||
ObjectMap<String, String> tags = new ObjectMap<>();
|
||||
|
||||
|
@ -14,7 +14,7 @@ public class Packets{
|
||||
|
||||
public enum KickReason{
|
||||
kick, clientOutdated, serverOutdated, banned, gameover(true), recentKick,
|
||||
nameInUse, idInUse, nameEmpty, customClient, sectorComplete, serverClose;
|
||||
nameInUse, idInUse, nameEmpty, customClient, serverClose;
|
||||
|
||||
public final boolean quiet;
|
||||
|
||||
|
@ -15,7 +15,7 @@ import io.anuke.arc.scene.event.InputListener;
|
||||
import io.anuke.arc.util.async.AsyncExecutor;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.generation.WorldGenerator.GenResult;
|
||||
import io.anuke.mindustry.maps.WorldGenerator.GenResult;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.ColorMapper;
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
|
||||
public class MissionDialog extends FloatingDialog{
|
||||
|
||||
public MissionDialog(){
|
||||
super("$text.mission.complete");
|
||||
setFillParent(false);
|
||||
}
|
||||
|
||||
public void show(Sector sector){
|
||||
buttons().clear();
|
||||
content().clear();
|
||||
|
||||
buttons().addButton("$text.nextmission", () -> {
|
||||
hide();
|
||||
Vars.ui.paused.runExitSave();
|
||||
Vars.ui.sectors.show();
|
||||
}).size(190f, 64f);
|
||||
|
||||
buttons().addButton("$text.continue", this::hide).size(190f, 64f);
|
||||
|
||||
content().add(Core.bundle.format("text.mission.complete.body", sector.x, sector.y)).pad(10);
|
||||
show();
|
||||
}
|
||||
}
|
@ -31,10 +31,6 @@ public class PausedDialog extends FloatingDialog{
|
||||
void rebuild(){
|
||||
missionTable.clear();
|
||||
missionTable.background((Drawable) null);
|
||||
if(world.getSector() != null){
|
||||
missionTable.background("underline");
|
||||
missionTable.add(Core.bundle.format("text.sector", world.getSector().x + ", " + world.getSector().y));
|
||||
}
|
||||
}
|
||||
|
||||
void setup(){
|
||||
@ -58,7 +54,7 @@ public class PausedDialog extends FloatingDialog{
|
||||
content().addButton("$text.settings", ui.settings::show);
|
||||
|
||||
content().row();
|
||||
content().addButton("$text.savegame", save::show).disabled(s -> world.getSector() != null);
|
||||
content().addButton("$text.savegame", save::show);
|
||||
content().addButton("$text.loadgame", load::show).disabled(b -> Net.active());
|
||||
|
||||
content().row();
|
||||
@ -79,11 +75,9 @@ public class PausedDialog extends FloatingDialog{
|
||||
content().defaults().size(120f).pad(5);
|
||||
float isize = 14f * 4;
|
||||
|
||||
content().addRowImageTextButton("$text.back", "icon-play-2", isize, () -> {
|
||||
hide();
|
||||
});
|
||||
content().addRowImageTextButton("$text.back", "icon-play-2", isize, this::hide);
|
||||
content().addRowImageTextButton("$text.settings", "icon-tools", isize, ui.settings::show);
|
||||
content().addRowImageTextButton("$text.save", "icon-save", isize, save::show).disabled(b -> world.getSector() != null);
|
||||
content().addRowImageTextButton("$text.save", "icon-save", isize, save::show);
|
||||
|
||||
content().row();
|
||||
|
||||
|
@ -3,7 +3,6 @@ package io.anuke.mindustry.ui.dialogs;
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@ -34,7 +33,7 @@ public class RestartDialog extends FloatingDialog{
|
||||
state.set(State.menu);
|
||||
logic.reset();
|
||||
}).size(130f, 60f);
|
||||
}else if(world.getSector() == null){
|
||||
}else{
|
||||
if(control.isHighScore()){
|
||||
content().add("$text.highscore").pad(6);
|
||||
content().row();
|
||||
@ -46,19 +45,6 @@ public class RestartDialog extends FloatingDialog{
|
||||
state.set(State.menu);
|
||||
logic.reset();
|
||||
}).size(130f, 60f);
|
||||
}else{
|
||||
content().add("$text.sector.gameover");
|
||||
buttons().addButton("$text.menu", () -> {
|
||||
hide();
|
||||
state.set(State.menu);
|
||||
logic.reset();
|
||||
}).size(130f, 60f);
|
||||
|
||||
buttons().addButton("$text.sector.retry", () -> {
|
||||
Sector sector = world.getSector();
|
||||
ui.loadLogic(() -> world.sectors.playSector(sector));
|
||||
hide();
|
||||
}).size(130f, 60f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,271 +0,0 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.math.geom.Geometry;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.scene.Element;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.event.InputEvent;
|
||||
import io.anuke.arc.scene.event.InputListener;
|
||||
import io.anuke.arc.scene.event.Touchable;
|
||||
import io.anuke.arc.scene.ui.layout.Cell;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.scene.ui.layout.Unit;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.maps.Sector;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class SectorsDialog extends FloatingDialog{
|
||||
private static final float sectorSize = Unit.dp.scl(32*5);
|
||||
private Sector selected;
|
||||
private Table table;
|
||||
private SectorView view;
|
||||
|
||||
public SectorsDialog(){
|
||||
super("");
|
||||
|
||||
table = new Table(){
|
||||
@Override
|
||||
public float getPrefWidth(){
|
||||
return sectorSize*2f;
|
||||
}
|
||||
};
|
||||
table.visible(() -> selected != null);
|
||||
table.update(() -> {
|
||||
if(selected != null){
|
||||
|
||||
int offsetX = (int)(view.panX / sectorSize);
|
||||
int offsetY = (int)(view.panY / sectorSize);
|
||||
float drawX = x + width/2f+ selected.x * (sectorSize-2) - offsetX * sectorSize - view.panX % sectorSize + sectorSize/2f;
|
||||
float drawY = y + height/2f + selected.y * (sectorSize-2) - offsetY * sectorSize - view.panY % sectorSize + sectorSize/2f;
|
||||
|
||||
table.setPosition(drawX, drawY - sectorSize/2f + 1, Align.top);
|
||||
}
|
||||
});
|
||||
|
||||
Group container = new Group();
|
||||
container.touchable(Touchable.childrenOnly);
|
||||
container.addChild(table);
|
||||
|
||||
margin(0);
|
||||
getTitleTable().clear();
|
||||
clear();
|
||||
stack(content(), container, buttons()).grow();
|
||||
|
||||
shown(this::setup);
|
||||
}
|
||||
|
||||
void setup(){
|
||||
selected = null;
|
||||
|
||||
table.clear();
|
||||
content().clear();
|
||||
buttons().clear();
|
||||
buttons().bottom().margin(15);
|
||||
|
||||
addCloseButton();
|
||||
content().add(view = new SectorView()).grow();
|
||||
}
|
||||
|
||||
void selectSector(Sector sector){
|
||||
selected = sector;
|
||||
|
||||
table.clear();
|
||||
table.background("button").margin(5);
|
||||
|
||||
table.defaults().pad(3);
|
||||
table.add(Core.bundle.format("text.sector", sector.x + ", " + sector.y));
|
||||
table.row();
|
||||
|
||||
if(selected.completedMissions < selected.missions.size && !selected.complete){
|
||||
table.labelWrap(Core.bundle.format("text.mission", selected.getDominantMission().menuDisplayString())).growX();
|
||||
table.row();
|
||||
}
|
||||
|
||||
if(selected.hasSave()){
|
||||
table.labelWrap(Core.bundle.format("text.sector.time", selected.getSave().getPlayTime())).growX();
|
||||
table.row();
|
||||
}
|
||||
|
||||
table.table(t -> {
|
||||
Cell<?> cell = t.addImageTextButton(sector.hasSave() ? "$text.sector.resume" : "$text.sector.deploy", "icon-play", 10*3, () -> {
|
||||
hide();
|
||||
Vars.ui.loadLogic(() -> world.sectors.playSector(selected));
|
||||
}).height(60f);
|
||||
|
||||
if(selected.hasSave()){
|
||||
t.addImageTextButton("$text.sector.abandon", "icon-cancel", 16 * 2, () ->
|
||||
Vars.ui.showConfirm("$text.confirm", "$text.sector.abandon.confirm", () -> {
|
||||
world.sectors.abandonSector(selected);
|
||||
// Simulate a sector selection so the buttons get updated.
|
||||
selectSector(selected);
|
||||
})
|
||||
).width(sectorSize / Unit.dp.scl(1f)).height(60f);
|
||||
cell.width(sectorSize / Unit.dp.scl(1f));
|
||||
}else{
|
||||
cell.width(sectorSize*2f / Unit.dp.scl(1f));
|
||||
}
|
||||
}).pad(-5).growX().padTop(0);
|
||||
|
||||
table.pack();
|
||||
table.act(Core.graphics.getDeltaTime());
|
||||
}
|
||||
|
||||
public Sector getSelected(){
|
||||
return selected;
|
||||
}
|
||||
|
||||
class SectorView extends Element{
|
||||
float lastX, lastY;
|
||||
boolean clicked = false;
|
||||
float panX = sectorSize/2f, panY = sectorSize/2f;
|
||||
|
||||
SectorView(){
|
||||
addListener(new InputListener(){
|
||||
@Override
|
||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
|
||||
if(pointer != 0) return false;
|
||||
//Cursors.setHand();
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void touchDragged(InputEvent event, float x, float y, int pointer){
|
||||
if(pointer != 0) return;
|
||||
panX -= x - lastX;
|
||||
panY -= y - lastY;
|
||||
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){
|
||||
if(pointer != 0) return;
|
||||
//Cursors.restoreCursor();
|
||||
}
|
||||
});
|
||||
|
||||
clicked(() -> clicked = true);
|
||||
|
||||
this.focus();
|
||||
}
|
||||
|
||||
private void focus(){
|
||||
Sector focusSector = null;
|
||||
long newestTimestamp = 0;
|
||||
for(Sector sector : world.sectors.getSectors()){
|
||||
if(sector.hasSave()){
|
||||
long timestamp = sector.getSave().getTimestamp();
|
||||
if(timestamp > newestTimestamp){
|
||||
focusSector = sector;
|
||||
newestTimestamp = timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(focusSector != null) {
|
||||
panX = (focusSector.x + 0.5f) * sectorSize;
|
||||
panY = (focusSector.y + 0.5f) * sectorSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.alpha(parentAlpha);
|
||||
|
||||
int shownSectorsX = (int)(width/sectorSize);
|
||||
int shownSectorsY = (int)(height/sectorSize);
|
||||
|
||||
int offsetX = (int)(panX / sectorSize);
|
||||
int offsetY = (int)(panY / sectorSize);
|
||||
|
||||
Vector2 mouse = Core.input.mouse();
|
||||
|
||||
for(int x = -shownSectorsX; x <= shownSectorsX; x++){
|
||||
for(int y = -shownSectorsY; y <= shownSectorsY; y++){
|
||||
int sectorX = offsetX + x;
|
||||
int sectorY = offsetY + y;
|
||||
|
||||
float drawX = x + width/2f+ sectorX * (sectorSize-2) - offsetX * sectorSize - panX % sectorSize + sectorSize/2f;
|
||||
float drawY = y + height/2f + sectorY * (sectorSize-2) - offsetY * sectorSize - panY % sectorSize + sectorSize/2f;
|
||||
|
||||
Sector sector = world.sectors.get(sectorX, sectorY);
|
||||
|
||||
if(sector == null || sector.texture == null){
|
||||
Draw.reset();
|
||||
Draw.rect(("empty-sector"), drawX, drawY, sectorSize, sectorSize);
|
||||
|
||||
int i = 0;
|
||||
for(Point2 point : Geometry.d4){
|
||||
Sector other = world.sectors.get(sectorX + point.x, sectorY + point.y);
|
||||
if(other != null){
|
||||
Draw.rect(("sector-edge"), drawX, drawY, sectorSize, sectorSize, i*90);
|
||||
}
|
||||
|
||||
i ++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Draw.colorl(!sector.complete ? 0.3f : 1f);
|
||||
Draw.rect(Draw.wrap(sector.texture), drawX, drawY, sectorSize, sectorSize);
|
||||
|
||||
if(sector.missions.size == 0) continue;
|
||||
|
||||
String region = sector.getDominantMission().getIcon();
|
||||
|
||||
if(sector.complete){
|
||||
region = "icon-mission-done";
|
||||
}
|
||||
|
||||
Color iconColor = Color.WHITE;
|
||||
Color backColor = Color.BLACK;
|
||||
Color selectColor = Color.CLEAR;
|
||||
|
||||
if(sector == selected){
|
||||
selectColor = Palette.accent;
|
||||
}else if(mouse.x > drawX - sectorSize / 2f && mouse.y > drawY - sectorSize / 2f
|
||||
&& mouse.x < drawX + sectorSize / 2f && mouse.y < drawY + sectorSize / 2f){
|
||||
if(clicked){
|
||||
selectSector(sector);
|
||||
}
|
||||
selectColor = Color.WHITE;
|
||||
}else if(sector.hasSave()){
|
||||
iconColor = Palette.command;
|
||||
}else{
|
||||
iconColor = Color.GRAY;
|
||||
}
|
||||
|
||||
if(sector.complete){
|
||||
iconColor = backColor = Color.CLEAR;
|
||||
}
|
||||
|
||||
Draw.color(selectColor);
|
||||
Draw.rect(("sector-select"), drawX, drawY, sectorSize, sectorSize);
|
||||
|
||||
Draw.color(backColor);
|
||||
Draw.alpha(0.75f * backColor.a);
|
||||
Draw.rect(("icon-mission-background"), drawX, drawY, Unit.dp.scl(18f * 5), Unit.dp.scl(18f * 5));
|
||||
|
||||
float size = Unit.dp.scl(10f * 5);
|
||||
|
||||
Draw.color(iconColor);
|
||||
Draw.rect((region), drawX, drawY, size, size);
|
||||
}
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
|
||||
clicked = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -143,13 +143,6 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
dialog.setFillParent(false);
|
||||
dialog.content().defaults().size(230f, 60f).pad(3);
|
||||
dialog.addCloseButton();
|
||||
dialog.content().addButton("$text.settings.clearsectors", () -> {
|
||||
ui.showConfirm("$text.confirm", "$text.settings.clear.confirm", () -> {
|
||||
world.sectors.clear();
|
||||
dialog.hide();
|
||||
});
|
||||
});
|
||||
dialog.content().row();
|
||||
dialog.content().addButton("$text.settings.clearunlocks", () -> {
|
||||
ui.showConfirm("$text.confirm", "$text.settings.clear.confirm", () -> {
|
||||
control.unlocks.reset();
|
||||
|
@ -31,7 +31,6 @@ import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.Packets.AdminAction;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.ui.IntFormat;
|
||||
import io.anuke.mindustry.ui.Minimap;
|
||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@ -370,7 +369,6 @@ public class HudFragment extends Fragment{
|
||||
table.touchable(Touchable.enabled);
|
||||
|
||||
table.labelWrap(() ->
|
||||
world.getSector() == null ?
|
||||
(state.enemies() > 0 && state.mode.disableWaveTimer ?
|
||||
wavef.get(state.wave) + "\n" + (state.enemies() == 1 ?
|
||||
enemyf.get(state.enemies()) :
|
||||
@ -378,17 +376,11 @@ public class HudFragment extends Fragment{
|
||||
wavef.get(state.wave) + "\n" +
|
||||
(!state.mode.disableWaveTimer ?
|
||||
Core.bundle.format("text.wave.waiting", (int)(state.wavetime/60)) :
|
||||
Core.bundle.get("text.waiting"))) :
|
||||
Core.bundle.format("text.mission.display", world.getSector().currentMission().displayString())).growX().pad(8f);
|
||||
Core.bundle.get("text.waiting")))
|
||||
).growX().pad(8f);
|
||||
|
||||
table.clicked(() -> {
|
||||
if(world.getSector() != null && world.getSector().currentMission().hasMessage()){
|
||||
world.getSector().currentMission().showMessage();
|
||||
}
|
||||
});
|
||||
|
||||
table.setDisabled(() -> !(world.getSector() != null && world.getSector().currentMission().hasMessage()));
|
||||
table.visible(() -> !((world.getSector() == null && state.mode.disableWaves) || !state.mode.showMission || (world.getSector() != null && world.getSector().complete)));
|
||||
table.setDisabled(true);
|
||||
table.visible(() -> !(state.mode.disableWaves || !state.mode.showMission));
|
||||
}
|
||||
|
||||
private void addPlayButton(Table table){
|
||||
|
@ -148,7 +148,7 @@ public class MenuFragment extends Fragment{
|
||||
|
||||
dialog.content().add(new MenuButton("icon-play-2", "$text.sectors", () -> {
|
||||
dialog.hide();
|
||||
ui.sectors.show();
|
||||
ui.showInfo("aaaaaaaaaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa");
|
||||
})).width(bw).colspan(2);
|
||||
dialog.content().row();
|
||||
|
||||
|
@ -23,7 +23,6 @@ import io.anuke.mindustry.entities.units.UnitType;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Shaders;
|
||||
import io.anuke.mindustry.maps.TutorialSector;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
@ -206,7 +205,7 @@ public class CoreBlock extends StorageBlock{
|
||||
}
|
||||
}
|
||||
|
||||
if(!found && !TutorialSector.supressDrone()){
|
||||
if(!found){
|
||||
BaseUnit unit = droneType.create(tile.getTeam());
|
||||
unit.setSpawner(tile);
|
||||
unit.setDead(true);
|
||||
|
@ -48,7 +48,6 @@ public class ServerControl implements ApplicationListener{
|
||||
private final FileHandle logFolder = Core.files.local("logs/");
|
||||
|
||||
private FileHandle currentLogFile;
|
||||
private int gameOvers;
|
||||
private boolean inExtraRound;
|
||||
private Task lastTask;
|
||||
|
||||
@ -58,8 +57,6 @@ public class ServerControl implements ApplicationListener{
|
||||
"shufflemode", "normal",
|
||||
"bans", "",
|
||||
"admins", "",
|
||||
"sector_x", 2,
|
||||
"sector_y", 1,
|
||||
"shuffle", true,
|
||||
"crashreport", false,
|
||||
"port", port,
|
||||
@ -128,57 +125,31 @@ public class ServerControl implements ApplicationListener{
|
||||
warn("&lyIt is highly advised to specify which version you're using by building with gradle args &lc-Pbuildversion=&lm<build>&ly.");
|
||||
}
|
||||
|
||||
Events.on(SectorCompleteEvent.class, event -> {
|
||||
info("Sector complete.");
|
||||
world.sectors.completeSector(world.getSector().x, world.getSector().y);
|
||||
world.sectors.save();
|
||||
gameOvers = 0;
|
||||
inExtraRound = true;
|
||||
Core.settings.put("sector_x", world.getSector().x + 1);
|
||||
Core.settings.save();
|
||||
|
||||
Call.onInfoMessage("[accent]Sector conquered![]\n" + roundExtraTime + " seconds until deployment in next sector.");
|
||||
|
||||
playSectorMap();
|
||||
});
|
||||
|
||||
Events.on(GameOverEvent.class, event -> {
|
||||
if(inExtraRound) return;
|
||||
info("Game over!");
|
||||
|
||||
if(Core.settings.getBool("shuffle")){
|
||||
if(world.getSector() == null){
|
||||
if(world.maps.all().size > 0){
|
||||
Array<Map> maps = world.maps.customMaps().size == 0 ? world.maps.defaultMaps() : world.maps.customMaps();
|
||||
if(world.maps.all().size > 0){
|
||||
Array<Map> maps = world.maps.customMaps().size == 0 ? world.maps.defaultMaps() : world.maps.customMaps();
|
||||
|
||||
Map previous = world.getMap();
|
||||
Map map = previous;
|
||||
if(maps.size > 1){
|
||||
while(map == previous) map = maps.random();
|
||||
}
|
||||
|
||||
Call.onInfoMessage((state.mode.isPvp
|
||||
? "[YELLOW]The " + event.winner.name() + " team is victorious![]" : "[SCARLET]Game over![]")
|
||||
+ "\nNext selected map:[accent] "+map.name+"[]"
|
||||
+ (map.meta.author() != null ? " by[accent] " + map.meta.author() + "[]" : "") + "."+
|
||||
"\nNew game begins in " + roundExtraTime + " seconds.");
|
||||
|
||||
info("Selected next map to be {0}.", map.name);
|
||||
|
||||
Map fmap = map;
|
||||
|
||||
play(true, () -> world.loadMap(fmap));
|
||||
Map previous = world.getMap();
|
||||
Map map = previous;
|
||||
if(maps.size > 1){
|
||||
while(map == previous) map = maps.random();
|
||||
}
|
||||
}else{
|
||||
Call.onInfoMessage("[SCARLET]Sector has been lost.[]\nRe-deploying in " + roundExtraTime + " seconds.");
|
||||
if(gameOvers >= 2){
|
||||
Core.settings.put("sector_y", Core.settings.getInt("sector_y") < 0 ? Core.settings.getInt("sector_y") + 1 : Core.settings.getInt("sector_y") - 1);
|
||||
Core.settings.save();
|
||||
gameOvers = 0;
|
||||
}
|
||||
gameOvers ++;
|
||||
playSectorMap();
|
||||
info("Re-trying sector map: {0} {1}", Core.settings.getInt("sector_x"), Core.settings.getInt("sector_y"));
|
||||
|
||||
Call.onInfoMessage((state.mode.isPvp
|
||||
? "[YELLOW]The " + event.winner.name() + " team is victorious![]" : "[SCARLET]Game over![]")
|
||||
+ "\nNext selected map:[accent] "+map.name+"[]"
|
||||
+ (map.meta.author() != null ? " by[accent] " + map.meta.author() + "[]" : "") + "."+
|
||||
"\nNew game begins in " + roundExtraTime + " seconds.");
|
||||
|
||||
info("Selected next map to be {0}.", map.name);
|
||||
|
||||
Map fmap = map;
|
||||
|
||||
play(true, () -> world.loadMap(fmap));
|
||||
}
|
||||
}else{
|
||||
netServer.kickAll(KickReason.gameover);
|
||||
@ -259,8 +230,8 @@ public class ServerControl implements ApplicationListener{
|
||||
logic.play();
|
||||
|
||||
}else{
|
||||
info("&fiNo map specified. Loading sector {0}, {1}.", Core.settings.getInt("sector_x"), Core.settings.getInt("sector_y"));
|
||||
playSectorMap(false);
|
||||
//TODO
|
||||
info("TODO play generated map");
|
||||
}
|
||||
|
||||
info("Map loaded.");
|
||||
@ -337,17 +308,6 @@ public class ServerControl implements ApplicationListener{
|
||||
}
|
||||
});
|
||||
|
||||
handler.register("setsector", "<x> <y>", "Sets the next sector to be played. Does not affect current game.", arg -> {
|
||||
try{
|
||||
Core.settings.put("sector_x", Integer.parseInt(arg[0]));
|
||||
Core.settings.put("sector_y", Integer.parseInt(arg[1]));
|
||||
Core.settings.save();
|
||||
info("Sector position set.");
|
||||
}catch(NumberFormatException e){
|
||||
err("Invalid coordinates.");
|
||||
}
|
||||
});
|
||||
|
||||
handler.register("fillitems", "[team]", "Fill the core with 2000 items.", arg -> {
|
||||
if(!state.is(State.playing)){
|
||||
err("Not playing. Host first.");
|
||||
@ -705,21 +665,6 @@ public class ServerControl implements ApplicationListener{
|
||||
}
|
||||
}
|
||||
|
||||
private void playSectorMap(){
|
||||
playSectorMap(true);
|
||||
}
|
||||
|
||||
private void playSectorMap(boolean wait){
|
||||
int x = Core.settings.getInt("sector_x"), y = Core.settings.getInt("sector_y");
|
||||
if(world.sectors.get(x, y) == null){
|
||||
world.sectors.createSector(x, y);
|
||||
}
|
||||
|
||||
world.sectors.get(x, y).completedMissions = 0;
|
||||
|
||||
play(wait, () -> world.loadSector(world.sectors.get(x, y)));
|
||||
}
|
||||
|
||||
private void play(boolean wait, Runnable run){
|
||||
inExtraRound = true;
|
||||
Runnable r = () -> {
|
||||
|
@ -101,12 +101,6 @@ public class ApplicationTests{
|
||||
assertTrue(content.getContentMap().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadSector(){
|
||||
world.sectors.createSector(0, 0);
|
||||
world.sectors.playSector(world.sectors.get(0, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void playMap(){
|
||||
assertTrue(world.maps.all().size > 0);
|
||||
|
@ -1,54 +0,0 @@
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.ContentLoader;
|
||||
import io.anuke.mindustry.maps.SectorPresets;
|
||||
import io.anuke.mindustry.maps.generation.Generation;
|
||||
import io.anuke.mindustry.maps.missions.Mission;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/** This class is responsible for testing predefined sectors. */
|
||||
public class SectorTests{
|
||||
|
||||
private SectorPresets presets;
|
||||
private Generation fakeGen;
|
||||
|
||||
@BeforeAll
|
||||
static void initializeDependencies(){
|
||||
Vars.content = new ContentLoader();
|
||||
Vars.content.load();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void initTest(){
|
||||
this.presets = new SectorPresets();
|
||||
|
||||
// Fake away the Generation dependency
|
||||
this.fakeGen = new Generation(null, null, 250, 250, null);
|
||||
}
|
||||
|
||||
/** Returns true if at least one mission provides a spawn point. */
|
||||
private boolean spawnPointIsDefined(Array<Mission> missions){
|
||||
for(Mission mission : missions){
|
||||
if(mission.getSpawnPoints(this.fakeGen).size > 0){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// No spawn point provided
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that every predefined sector has a position for the player core defined.
|
||||
* This is achieved by adding at least one mission which defines a spawn point.
|
||||
*/
|
||||
@Test
|
||||
void sectorHasACore(){
|
||||
for(SectorPresets.SectorPreset preset : this.presets.getPresets().values()){
|
||||
assertTrue(spawnPointIsDefined(preset.missions), "Sector at (" + preset.x + "|" + preset.y + ") contains no missions which define a spawn point. Add a battle or wave mission.");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user