diff --git a/core/src/io/anuke/mindustry/Mindustry.java b/core/src/io/anuke/mindustry/Mindustry.java index 5c50f133b7..b100ffbfbe 100644 --- a/core/src/io/anuke/mindustry/Mindustry.java +++ b/core/src/io/anuke/mindustry/Mindustry.java @@ -8,6 +8,7 @@ import io.anuke.mindustry.core.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.io.PlatformFunction; import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.BlockLoader; import io.anuke.ucore.UCore; import io.anuke.ucore.core.Core; @@ -16,6 +17,8 @@ import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; import io.anuke.ucore.modules.ModuleCore; +import static io.anuke.mindustry.Vars.*; + import java.util.Locale; public class Mindustry extends ModuleCore { @@ -26,23 +29,26 @@ public class Mindustry extends ModuleCore { @Override public void init(){ + if(args.contains("-debug", false)) debug = true; + Settings.defaults("locale", "default"); Settings.load("io.anuke.moment"); loadBundle(); BlockLoader.load(); + UCore.log("Total blocks loaded: " + Block.getAllBlocks().size); - module(Vars.world = new World()); - module(Vars.control = new Control()); - module(Vars.logic = new Logic()); - module(Vars.renderer = new Renderer()); - module(Vars.ui = new UI()); - module(Vars.netServer = new NetServer()); - module(Vars.netClient = new NetClient()); + module(world = new World()); + module(control = new Control()); + module(logic = new Logic()); + module(renderer = new Renderer()); + module(ui = new UI()); + module(netServer = new NetServer()); + module(netClient = new NetClient()); } @Override public void dispose() { - GameState.set(State.menu); + state.set(State.menu); platforms.onGameExit(); Net.dispose(); super.dispose(); @@ -91,7 +97,7 @@ public class Mindustry extends ModuleCore { @Override public void postInit(){ - Vars.control.reset(); + control.reset(); } @Override diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 869d671470..71a5d9ee0e 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -3,10 +3,15 @@ package io.anuke.mindustry; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; - import io.anuke.mindustry.core.*; +import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.effect.Shield; +import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.ucore.UCore; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.scene.ui.layout.Unit; public class Vars{ @@ -76,7 +81,9 @@ public class Vars{ //server port public static final int port = 6567; public static final int webPort = 6568; - + + public static final GameState state = new GameState(); + public static Control control; public static Logic logic; public static Renderer renderer; @@ -86,4 +93,10 @@ public class Vars{ public static NetClient netClient; public static Player player; + + public static final EntityGroup playerGroup = Entities.addGroup(Player.class).enableMapping(); + public static final EntityGroup enemyGroup = Entities.addGroup(Enemy.class).enableMapping(); + public static final EntityGroup tileGroup = Entities.addGroup(TileEntity.class, false); + public static final EntityGroup bulletGroup = Entities.addGroup(Bullet.class); + public static final EntityGroup shieldGroup = Entities.addGroup(Shield.class); } diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 3a83166a24..3d25e8ab0a 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -122,7 +122,7 @@ public class Pathfind{ //go through each spawnpoint, and if it's not found a path yet, update it for(SpawnPoint point : Vars.control.getSpawnPoints()){ - if(point.request == null){ + if(point.request == null || point.finder == null){ resetPathFor(point); } @@ -150,13 +150,13 @@ public class Pathfind{ //warmup for(int i = 0; i < 100; i ++){ - point.finder.searchNodePath(point.start, Vars.control.getCore(), Vars.control.getDifficulty().heuristic, point.path); + point.finder.searchNodePath(point.start, Vars.world.getCore(), Vars.control.getDifficulty().heuristic, point.path); point.path.clear(); } Timers.mark(); for(int i = 0; i < amount; i ++){ - point.finder.searchNodePath(point.start, Vars.control.getCore(), Vars.control.getDifficulty().heuristic, point.path); + point.finder.searchNodePath(point.start, Vars.world.getCore(), Vars.control.getDifficulty().heuristic, point.path); point.path.clear(); } UCore.log("Time elapsed: " + Timers.elapsed() + "ms\nAverage MS per path: " + Timers.elapsed()/amount); @@ -176,7 +176,7 @@ public class Pathfind{ point.pathTiles = null; - point.request = new PathFinderRequest<>(point.start, Vars.control.getCore(), Vars.control.getDifficulty().heuristic, point.path); + point.request = new PathFinderRequest<>(point.start, Vars.world.getCore(), Vars.control.getDifficulty().heuristic, point.path); point.request.statusChanged = true; //IMPORTANT! } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 77e20a68c8..2a62a896a2 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -1,99 +1,63 @@ package io.anuke.mindustry.core; -import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Buttons; -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.effect.Shield; -import io.anuke.mindustry.entities.enemies.Enemy; -import io.anuke.mindustry.entities.enemies.EnemyTypes; -import io.anuke.mindustry.game.*; +import io.anuke.mindustry.game.DefaultKeybinds; +import io.anuke.mindustry.game.EventType.GameOver; +import io.anuke.mindustry.game.EventType.PlayEvent; +import io.anuke.mindustry.game.EventType.ResetEvent; +import io.anuke.mindustry.game.EventType.WaveEvent; +import io.anuke.mindustry.game.Tutorial; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.DesktopInput; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.io.Saves; import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.resource.Item; -import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Weapon; -import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Map; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.ProductionBlocks; import io.anuke.ucore.UCore; import io.anuke.ucore.core.*; -import io.anuke.ucore.core.Inputs.Axis; import io.anuke.ucore.core.Inputs.DeviceType; import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.modules.Module; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.Atlas; -import io.anuke.ucore.util.Input; import io.anuke.ucore.util.InputProxy; import io.anuke.ucore.util.Mathf; -import java.util.Arrays; - import static io.anuke.mindustry.Vars.*; +/**Control module. + * Handles all input, saving, keybinds and keybinds. + * Should not handle any game-critical state. + * This class is not created in the headless server. + */ public class Control extends Module{ - Tutorial tutorial = new Tutorial(); - boolean hiscore = false; - - final Array weapons = new Array<>(); - final int[] items = new int[Item.getAllItems().size]; + private Tutorial tutorial = new Tutorial(); + private boolean hiscore = false; - public final EntityGroup playerGroup = Entities.addGroup(Player.class).enableMapping(); - public final EntityGroup enemyGroup = Entities.addGroup(Enemy.class).enableMapping(); - public final EntityGroup tileGroup = Entities.addGroup(TileEntity.class, false); - public final EntityGroup bulletGroup = Entities.addGroup(Bullet.class); - public final EntityGroup shieldGroup = Entities.addGroup(Shield.class); - - Array spawns; - int wave = 1; - int lastUpdated = -1; - float wavetime; - float extrawavetime; - int enemies = 0; - GameMode mode = GameMode.waves; - Difficulty difficulty = Difficulty.normal; - - Tile core; - Array spawnpoints = new Array<>(); - boolean shouldUpdateItems = false; - boolean wasPaused = false; + private boolean shouldUpdateItems = false; + private boolean wasPaused = false; - Saves saves; + private Saves saves; - float respawntime; - InputHandler input; - boolean friendlyFire; + private float respawntime; + private InputHandler input; private InputProxy proxy; private float controlx, controly; private boolean controlling; public Control(){ - if(Mindustry.args.contains("-debug", false)) - Vars.debug = true; saves = new Saves(); Inputs.useControllers(!Vars.gwt); - log("Total blocks loaded: " + Block.getAllBlocks().size); - - Lines.setCircleVertices(14); - Gdx.input.setCatchBackKey(true); if(android){ @@ -138,55 +102,8 @@ public class Control extends Module{ Sounds.setFalloff(9000f); Musics.load("1.ogg", "2.ogg", "3.ogg", "4.ogg"); - - KeyBinds.defaults( - "move_x", new Axis(Input.A, Input.D), - "move_y", new Axis(Input.S, Input.W), - "select", Input.MOUSE_LEFT, - "break", Input.MOUSE_RIGHT, - "shoot", Input.MOUSE_LEFT, - "zoom_hold", Input.CONTROL_LEFT, - "zoom", new Axis(Input.SCROLL), - "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, - "pause", Input.SPACE, - "dash", Input.SHIFT_LEFT, - "rotate_alt", new Axis(Input.R, Input.E), - "rotate", new Axis(Input.SCROLL), - "player_list", Input.TAB, - "chat", Input.ENTER, - "weapon_1", Input.NUM_1, - "weapon_2", Input.NUM_2, - "weapon_3", Input.NUM_3, - "weapon_4", Input.NUM_4, - "weapon_5", Input.NUM_5, - "weapon_6", Input.NUM_6 - ); - KeyBinds.defaults( - DeviceType.controller, - "move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS), - "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), - "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), - "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), - "select", Input.CONTROLLER_R_BUMPER, - "break", Input.CONTROLLER_L_BUMPER, - "shoot", Input.CONTROLLER_R_TRIGGER, - "zoom_hold", Input.ANY_KEY, - "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), - "menu", Input.CONTROLLER_X, - "pause", Input.CONTROLLER_L_TRIGGER, - "dash", Input.CONTROLLER_Y, - "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), - "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), - "player_list", Input.CONTROLLER_START, - "chat", Input.ENTER, - "weapon_1", Input.NUM_1, - "weapon_2", Input.NUM_2, - "weapon_3", Input.NUM_3, - "weapon_4", Input.NUM_4, - "weapon_5", Input.NUM_5, - "weapon_6", Input.NUM_6 - ); + DefaultKeybinds.load(); for(int i = 0; i < Vars.saveSlots; i ++){ Settings.defaults("save-" + i + "-autosave", !Vars.gwt); @@ -211,61 +128,59 @@ public class Control extends Module{ player.name = Settings.getString("name"); player.isAndroid = Vars.android; player.isLocal = true; - - spawns = WaveCreator.getSpawns(); saves.load(); - } - - public void reset(){ - weapons.clear(); - - weapons.add(Weapon.blaster); - player.weaponLeft = player.weaponRight = weapons.first(); - - lastUpdated = -1; - wave = 1; - extrawavetime = maxwavespace; - wavetime = waveSpacing(); - Entities.clear(); - enemies = 0; - player.add(); - - player.heal(); - clearItems(); - spawnpoints.clear(); - respawntime = -1; - hiscore = false; - - for(Block block : Block.getAllBlocks()){ - block.onReset(); - } + Events.on(PlayEvent.class, () -> { + renderer.clearTiles(); - ui.hudfrag.updateItems(); - ui.hudfrag.updateWeapons(); - } - - public void play(){ - if(core == null) return; - renderer.clearTiles(); - - player.x = core.worldx(); - player.y = core.worldy() - Vars.tilesize*2; - - Core.camera.position.set(player.x, player.y, 0); - - //multiplying by 2 so you start with more time in the beginning - wavetime = waveSpacing()*2; + player.x = world.getCore().worldx(); + player.y = world.getCore().worldy() - Vars.tilesize*2; - //hacky, but I doubt anyone will use this many resources - if(mode.infiniteResources){ - Arrays.fill(items, 999999999); - } + Core.camera.position.set(player.x, player.y, 0); - ui.hudfrag.updateItems(); - - GameState.set(State.playing); + ui.hudfrag.updateItems(); + + state.set(State.playing); + }); + + Events.on(ResetEvent.class, () -> { + player.weaponLeft = player.weaponRight = Weapon.blaster; + + player.add(); + player.heal(); + + respawntime = -1; + hiscore = false; + + ui.hudfrag.updateItems(); + ui.hudfrag.updateWeapons(); + }); + + Events.on(WaveEvent.class, () -> { + Sounds.play("spawn"); + + int last = Settings.getInt("hiscore" + world.getMap().name); + + if(state.wave > last && !state.mode.infiniteResources && !state.mode.toggleWaves){ + Settings.putInt("hiscore" + world.getMap().name, state.wave); + Settings.save(); + hiscore = true; + } + + Mindustry.platforms.updateRPC(); + }); + + Events.on(GameOver.class, () -> { + Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); + Sounds.play("corexplode"); + for(int i = 0; i < 16; i ++){ + Timers.run(i*2, ()-> Effects.effect(Fx.explosion, world.getCore().worldx()+Mathf.range(40), world.getCore().worldy()+Mathf.range(40))); + } + Effects.effect(Fx.coreexplosion, world.getCore().worldx(), world.getCore().worldy()); + + ui.restart.show(); + }); } public Saves getSaves(){ @@ -275,179 +190,28 @@ public class Control extends Module{ public boolean showCursor(){ return controlling; } - - public boolean isFriendlyFire() { - return friendlyFire; - } - - public void setFriendlyFire(boolean friendlyFire) { - if(this.friendlyFire != friendlyFire && Net.active() && Net.server()){ - Vars.netServer.handleFriendlyFireChange(friendlyFire); - } - this.friendlyFire = friendlyFire; - } - - public Tile getCore(){ - return core; - } - public Array getSpawnPoints(){ - return spawnpoints; - } - - public void setCore(Tile tile){ - this.core = tile; - } - - public InputHandler getInput(){ + public InputHandler input(){ return input; } - public void addSpawnPoint(Tile tile){ - SpawnPoint point = new SpawnPoint(); - point.start = tile; - spawnpoints.add(point); - } - public void playMap(Map map){ ui.loadfrag.show(); saves.resetSave(); Timers.run(16, ()->{ - reset(); + logic.reset(); world.loadMap(map); - play(); + logic.play(); }); Timers.run(18, ()-> ui.loadfrag.hide()); } - public GameMode getMode(){ - return mode; - } - - public void setMode(GameMode mode){ - this.mode = mode; - } - - public boolean hasWeapon(Weapon weapon){ - return weapons.contains(weapon, true); - } - - public void addWeapon(Weapon weapon){ - weapons.add(weapon); - } - - public Array getWeapons(){ - return weapons; - } - - public void setWaveData(int enemies, int wave, float wavetime){ - this.wave = wave; - this.wavetime = wavetime; - this.enemies = enemies; - this.extrawavetime = maxwavespace; - } - - public void runWave(){ - - if(Net.client() && Net.active()){ - return; - } - - Sounds.play("spawn"); - - if(lastUpdated < wave + 1){ - world.pathfinder().resetPaths(); - lastUpdated = wave + 1; - } - - for(EnemySpawn spawn : spawns){ - for(int lane = 0; lane < spawnpoints.size; lane ++){ - int fl = lane; - Tile tile = spawnpoints.get(lane).start; - int spawnamount = spawn.evaluate(wave, lane); - - for(int i = 0; i < spawnamount; i ++){ - float range = 12f; - - Timers.run(i*5f, () -> { - - Enemy enemy = new Enemy(spawn.type); - enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range)); - enemy.lane = fl; - enemy.tier = spawn.tier(wave, fl); - enemy.add(); - - Effects.effect(Fx.spawn, enemy); - - enemies ++; - }); - } - } - } - - wave ++; - - int last = Settings.getInt("hiscore" + world.getMap().name); - - if(wave > last && !mode.infiniteResources && !mode.toggleWaves){ - Settings.putInt("hiscore" + world.getMap().name, wave); - Settings.save(); - hiscore = true; - } - - wavetime = waveSpacing(); - extrawavetime = maxwavespace; - - Mindustry.platforms.updateRPC(); - } - - public void enemyDeath(){ - enemies --; - } - - public void coreDestroyed(){ - - Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); - Sounds.play("corexplode"); - for(int i = 0; i < 16; i ++){ - Timers.run(i*2, ()-> Effects.effect(Fx.explosion, core.worldx()+Mathf.range(40), core.worldy()+Mathf.range(40))); - } - Effects.effect(Fx.coreexplosion, core.worldx(), core.worldy()); - - ui.restart.show(); - if(Net.active() && Net.server()) netServer.handleGameOver(); - } - - public boolean isGameOver(){ - return core != null && core.block() != ProductionBlocks.core; - } - - float waveSpacing(){ - return wavespace * getDifficulty().timeScaling; - } - - public Difficulty getDifficulty(){ - return difficulty; - } - - public void setDifficulty(Difficulty d){ - this.difficulty = d; - } - public boolean isHighScore(){ return hiscore; } - - public int getEnemiesRemaining(){ - return enemies; - } - - public float getWaveCountdown(){ - return wavetime; - } - + public float getRespawnTime(){ return respawntime; } @@ -456,80 +220,20 @@ public class Control extends Module{ this.respawntime = respawntime; } - public int getWave(){ - return wave; - } - public Tutorial getTutorial(){ return tutorial; } - public void clearItems(){ - Arrays.fill(items, 0); - - addItem(Item.stone, 40); - - if(debug){ - Arrays.fill(items, 99999); - } - } - - public int getAmount(Item item){ - return items[item.id]; - } - - public void addItem(Item item, int amount){ - items[item.id] += amount; - shouldUpdateItems = true; - } - - public boolean hasItems(ItemStack[] items){ - for(ItemStack stack : items) - if(!hasItem(stack)) - return false; - return true; - } - - public boolean hasItems(ItemStack[] items, int scaling){ - for(ItemStack stack : items) - if(!hasItem(stack.item, stack.amount * scaling)) - return false; - return true; - } - - public boolean hasItem(ItemStack req){ - return items[req.item.id] >= req.amount; - } - - public boolean hasItem(Item item, int amount){ - return items[item.id] >= amount; - } - - public void removeItem(ItemStack req){ - items[req.item.id] -= req.amount; - if(items[req.item.id] < 0) items[req.item.id] = 0; //prevents negative item glitches in multiplayer - shouldUpdateItems = true; - } - - public void removeItems(ItemStack... reqs){ - for(ItemStack req : reqs) - removeItem(req); - } - - public int[] getItems(){ - return items; - } - @Override public void pause(){ - wasPaused = GameState.is(State.paused); - if(GameState.is(State.playing)) GameState.set(State.paused); + wasPaused = state.is(State.paused); + if(state.is(State.playing)) state.set(State.paused); } @Override public void resume(){ - if(GameState.is(State.paused) && !wasPaused){ - GameState.set(State.playing); + if(state.is(State.paused) && !wasPaused){ + state.set(State.playing); } } @@ -588,86 +292,40 @@ public class Control extends Module{ saves.update(); - if(debug && GameState.is(State.playing)){ - //debug actions - if(Inputs.keyTap(Keys.P)){ - Effects.effect(Fx.shellsmoke, player); - Effects.effect(Fx.shellexplosion, player); - } - - if(Inputs.keyTap(Keys.C)){ - enemyGroup.clear(); - enemies = 0; - } - - if(Inputs.keyTap(Keys.F)){ - wavetime = 0f; - } - - if(Inputs.keyTap(Keys.G)){ - Vars.world.pathfinder().benchmark(); - } - - if(Inputs.keyDown(Keys.I)){ - wavetime -= delta() * 10f; - } - - if(Inputs.keyTap(Keys.U)){ - Vars.showPaths = !Vars.showPaths; - } - - if(Inputs.keyTap(Keys.O)){ - Vars.noclip = !Vars.noclip; - } - - if(Inputs.keyTap(Keys.Y)){ - if(Inputs.keyDown(Keys.SHIFT_LEFT)){ - new Enemy(EnemyTypes.healer).set(player.x, player.y).add(); - }else{ - float px = player.x, py = player.y; - Timers.run(30f, ()-> new Enemy(EnemyTypes.fortress).set(px, py).add()); - } - } - } - - if(shouldUpdateItems && (Timers.get("updateItems", 8) || GameState.is(State.paused))){ + if(shouldUpdateItems && (Timers.get("updateItems", 8) || state.is(State.paused))){ ui.hudfrag.updateItems(); shouldUpdateItems = false; } - if(!GameState.is(State.menu)){ + if(!state.is(State.menu)){ input.update(); - - if(core.block() != ProductionBlocks.core && !ui.restart.isShown()){ - coreDestroyed(); - } - if(Inputs.keyTap("pause") && !ui.restart.isShown() && !Net.active() && (GameState.is(State.paused) || GameState.is(State.playing))){ - GameState.set(GameState.is(State.playing) ? State.paused : State.playing); + if(Inputs.keyTap("pause") && !ui.restart.isShown() && !Net.active() && (state.is(State.paused) || state.is(State.playing))){ + state.set(state.is(State.playing) ? State.paused : State.playing); } if(Inputs.keyTap("menu")){ - if(GameState.is(State.paused)){ + if(state.is(State.paused)){ ui.paused.hide(); - GameState.set(State.playing); + state.set(State.playing); }else if (!ui.restart.isShown()){ if(ui.chatfrag.chatOpen()) { ui.chatfrag.hide(); }else{ ui.paused.show(); - GameState.set(State.paused); + state.set(State.paused); } } } - if(!GameState.is(State.paused) || Net.active()){ + if(!state.is(State.paused) || Net.active()){ if(respawntime > 0){ respawntime -= delta(); if(respawntime <= 0){ - player.set(core.worldx(), core.worldy()-Vars.tilesize*2); + player.set(world.getSpawnX(), world.getSpawnY()); player.heal(); player.add(); Effects.sound("respawn"); @@ -678,34 +336,6 @@ public class Control extends Module{ if(tutorial.active()){ tutorial.update(); } - - if(!tutorial.active() && !mode.toggleWaves){ - - if(enemies <= 0){ - wavetime -= delta(); - - if(lastUpdated < wave + 1 && wavetime < Vars.aheadPathfinding){ //start updating beforehand - world.pathfinder().resetPaths(); - lastUpdated = wave + 1; - } - }else{ - extrawavetime -= delta(); - } - } - - if(wavetime <= 0 || extrawavetime <= 0){ - runWave(); - } - - Entities.update(Entities.defaultGroup()); - Entities.update(bulletGroup); - Entities.update(enemyGroup); - Entities.update(tileGroup); - Entities.update(shieldGroup); - Entities.update(playerGroup); - - Entities.collideGroups(enemyGroup, bulletGroup); - Entities.collideGroups(playerGroup, bulletGroup); } } } diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index c4b1951573..ba5126759f 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -1,21 +1,33 @@ package io.anuke.mindustry.core; -import io.anuke.mindustry.Mindustry; -import io.anuke.ucore.core.Timers; +import io.anuke.mindustry.game.Difficulty; +import io.anuke.mindustry.game.EventType.StateChange; +import io.anuke.mindustry.game.GameMode; +import io.anuke.mindustry.game.Inventory; +import io.anuke.ucore.core.Events; public class GameState{ - private static State state = State.menu; + private State state = State.menu; + + public final Inventory inventory = new Inventory(); + + int wave = 1; + int lastUpdated = -1; + float wavetime; + float extrawavetime; + int enemies = 0; + boolean gameOver = false; + GameMode mode = GameMode.waves; + Difficulty difficulty = Difficulty.normal; + boolean friendlyFire; - public static void set(State astate){ - - if((astate == State.playing && state == State.menu) || (astate == State.menu && state != State.menu)){ - Timers.runTask(5f, Mindustry.platforms::updateRPC); - } - + public void set(State astate){ + //TODO update RPC handler + Events.fire(StateChange.class, state, astate); state = astate; } - public static boolean is(State astate){ + public boolean is(State astate){ return state == astate; } diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 7129f10a69..0f58790b5c 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -3,50 +3,33 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Bullet; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.effect.Shield; import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.game.*; +import io.anuke.mindustry.game.EventType.GameOver; +import io.anuke.mindustry.game.EventType.PlayEvent; +import io.anuke.mindustry.game.EventType.ResetEvent; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.resource.Item; -import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.ProductionBlocks; import io.anuke.ucore.core.Effects; +import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.modules.Module; import io.anuke.ucore.util.Mathf; -import java.util.Arrays; - import static io.anuke.mindustry.Vars.*; +/**Logic module. + * Handles all logic for entities and waves. + * Handles game state events. + * Does not store any game state itself. + * + * This class should not call any outside methods to change state of modules, but instead fire events. + */ public class Logic extends Module { - public final EntityGroup playerGroup = Entities.addGroup(Player.class).enableMapping(); - public final EntityGroup enemyGroup = Entities.addGroup(Enemy.class).enableMapping(); - public final EntityGroup tileGroup = Entities.addGroup(TileEntity.class, false); - public final EntityGroup bulletGroup = Entities.addGroup(Bullet.class); - public final EntityGroup shieldGroup = Entities.addGroup(Shield.class); - - public final int[] items = new int[Item.getAllItems().size]; - - Array spawns = WaveCreator.getSpawns(); - int wave = 1; - int lastUpdated = -1; - float wavetime; - float extrawavetime; - int enemies = 0; - GameMode mode = GameMode.waves; - Difficulty difficulty = Difficulty.normal; - boolean friendlyFire; - - Tile core; - Array spawnpoints = new Array<>(); + private final Array spawns = WaveCreator.getSpawns(); @Override public void init(){ @@ -55,44 +38,43 @@ public class Logic extends Module { } public void play(){ - wavetime = wavespace * difficulty.timeScaling * 2; + state.wavetime = wavespace * state.difficulty.timeScaling * 2; - if(mode.infiniteResources){ - Arrays.fill(items, 999999999); + if(state.mode.infiniteResources){ + state.inventory.fill(); } + + Events.fire(PlayEvent.class); } public void reset(){ - lastUpdated = -1; - wave = 1; - extrawavetime = maxwavespace; - wavetime = wavespace * difficulty.timeScaling; - enemies = 0; + state.wave = 1; + state.extrawavetime = maxwavespace; + state.wavetime = wavespace * state.difficulty.timeScaling; + state.enemies = 0; + state.lastUpdated = -1; + state.gameOver = false; + state.inventory.clearItems(); + Entities.clear(); - Arrays.fill(items, 0); - spawnpoints.clear(); - - for(Block block : Block.getAllBlocks()){ - block.onReset(); - } - - ui.hudfrag.updateItems(); - ui.hudfrag.updateWeapons(); + Events.fire(ResetEvent.class); } public void runWave(){ - if(lastUpdated < wave + 1){ + if(state.lastUpdated < state.wave + 1){ world.pathfinder().resetPaths(); - lastUpdated = wave + 1; + state.lastUpdated = state.wave + 1; } for(EnemySpawn spawn : spawns){ - for(int lane = 0; lane < spawnpoints.size; lane ++){ + Array spawns = world.getSpawns(); + + for(int lane = 0; lane < spawns.size; lane ++){ int fl = lane; - Tile tile = spawnpoints.get(lane).start; - int spawnamount = spawn.evaluate(wave, lane); + Tile tile = spawns.get(lane).start; + int spawnamount = spawn.evaluate(state.wave, lane); for(int i = 0; i < spawnamount; i ++){ float range = 12f; @@ -102,51 +84,47 @@ public class Logic extends Module { Enemy enemy = new Enemy(spawn.type); enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range)); enemy.lane = fl; - enemy.tier = spawn.tier(wave, fl); + enemy.tier = spawn.tier(state.wave, fl); enemy.add(); Effects.effect(Fx.spawn, enemy); - enemies ++; + state.enemies ++; }); } } } - wave ++; - - wavetime = wavespace * difficulty.timeScaling; - extrawavetime = maxwavespace; - } - - public void coreDestroyed(){ - if(Net.active() && Net.server()) netServer.handleGameOver(); + state.wave ++; + state.wavetime = wavespace * state.difficulty.timeScaling; + state.extrawavetime = maxwavespace; } public void updateLogic(){ - if(!GameState.is(State.menu)){ + if(!state.is(State.menu)){ - if(core.block() != ProductionBlocks.core && !ui.restart.isShown()){ - coreDestroyed(); + if(world.getCore().block() != ProductionBlocks.core && !state.gameOver){ + state.gameOver = true; + Events.fire(GameOver.class); } - if(!GameState.is(State.paused) || Net.active()){ + if(!state.is(State.paused) || Net.active()){ - if(!mode.toggleWaves){ + if(!state.mode.toggleWaves){ - if(enemies <= 0){ - wavetime -= delta(); + if(state.enemies <= 0){ + state.wavetime -= delta(); - if(lastUpdated < wave + 1 && wavetime < Vars.aheadPathfinding){ //start updating beforehand + if(state.lastUpdated < state.wave + 1 && state.wavetime < Vars.aheadPathfinding){ //start updating beforehand world.pathfinder().resetPaths(); - lastUpdated = wave + 1; + state.lastUpdated = state.wave + 1; } }else{ - extrawavetime -= delta(); + state.extrawavetime -= delta(); } } - if(wavetime <= 0 || extrawavetime <= 0){ + if(state.wavetime <= 0 || state.extrawavetime <= 0){ runWave(); } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index e7c66c9499..d531b91b75 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -48,6 +48,7 @@ public class NetClient extends Module { boolean gotData = false; boolean kicked = false; IntSet recieved = new IntSet(); + IntSet dead = new IntSet(); float playerSyncTime = 2; float dataTimeout = 60*18; //18 seconds timeout @@ -56,6 +57,7 @@ public class NetClient extends Module { Net.handle(Connect.class, packet -> { Net.setClientLoaded(false); recieved.clear(); + dead.clear(); connecting = true; gotData = false; kicked = false; @@ -84,7 +86,7 @@ public class NetClient extends Module { Timers.runFor(3f, Vars.ui.loadfrag::hide); - GameState.set(State.menu); + state.set(State.menu); Vars.ui.showError("$text.disconnect"); connecting = false; @@ -174,7 +176,7 @@ public class NetClient extends Module { Net.handle(EnemySpawnPacket.class, spawn -> { //duplicates. if (Vars.control.enemyGroup.getByID(spawn.id) != null || - recieved.contains(spawn.id)) return; + recieved.contains(spawn.id) || dead.contains(spawn.id)) return; recieved.add(spawn.id); @@ -192,6 +194,7 @@ public class NetClient extends Module { Net.handle(EnemyDeathPacket.class, spawn -> { Enemy enemy = Vars.control.enemyGroup.getByID(spawn.id); if (enemy != null) enemy.onDeath(); + dead.add(spawn.id); }); Net.handle(BulletPacket.class, packet -> { @@ -289,7 +292,7 @@ public class NetClient extends Module { Net.handle(KickPacket.class, packet -> { kicked = true; Net.disconnect(); - GameState.set(State.menu); + state.set(State.menu); Vars.ui.showError("$text.server.kicked." + packet.reason.name()); Vars.ui.loadfrag.hide(); }); @@ -341,7 +344,7 @@ public class NetClient extends Module { private void finishConnecting(){ Net.send(new ConnectConfirmPacket(), SendMode.tcp); - GameState.set(State.playing); + state.set(State.playing); Net.setClientLoaded(true); connecting = false; Vars.ui.loadfrag.hide(); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 63bda321cc..788f740937 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -265,7 +265,7 @@ public class NetServer extends Module{ public void handleGameOver(){ Net.send(new GameOverPacket(), SendMode.tcp); - Timers.runTask(30f, () -> GameState.set(State.menu)); + Timers.runTask(30f, () -> state.set(State.menu)); } public void handleBullet(BulletType type, Entity owner, float x, float y, float angle, short damage){ diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 95de6aac16..9f8ff4c1cc 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -53,6 +53,8 @@ public class Renderer extends RendererModule{ private BlockRenderer blocks = new BlockRenderer(); public Renderer() { + Lines.setCircleVertices(14); + Core.cameraScale = baseCameraScale; Effects.setEffectProvider((name, color, x, y, rotation) -> { if(Settings.getBool("effects")){ @@ -353,7 +355,7 @@ public class Renderer extends RendererModule{ tiley = Mathf.scl2(vec.y, tilesize); } - InputHandler input = control.getInput(); + InputHandler input = control.input(); //draw placement box if((input.recipe != null && Vars.control.hasItems(input.recipe.requirements) && (!ui.hasMouse() || android) diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 1d98b3acdd..9e387e787e 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -7,12 +7,13 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.ai.Pathfind; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.io.Maps; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.WorldGenerator; import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.WorldGenerator; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.DistributionBlocks; import io.anuke.mindustry.world.blocks.ProductionBlocks; @@ -23,17 +24,20 @@ import io.anuke.ucore.modules.Module; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Tmp; -import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.world; public class World extends Module{ private int seed; private Map currentMap; private Tile[][] tiles; - private Tile[] temptiles = new Tile[4]; private Pathfind pathfind = new Pathfind(); - private io.anuke.mindustry.io.Maps maps = new io.anuke.mindustry.io.Maps(); + private Maps maps = new Maps(); + private Tile core; + private Array spawns = new Array<>(); + + private Tile[] temptiles = new Tile[4]; public World(){ maps.loadMaps(); @@ -50,6 +54,14 @@ public class World extends Module{ public void dispose(){ maps.dispose(); } + + public Array getSpawns(){ + return spawns; + } + + public Tile getCore(){ + return core; + } public Maps maps(){ return maps; @@ -58,6 +70,14 @@ public class World extends Module{ public Pathfind pathfinder(){ return pathfind; } + + public float getSpawnX(){ + return core.worldx(); + } + + public float getSpawnY(){ + return core.worldy() - Vars.tilesize/2; + } public boolean solid(int x, int y){ Tile tile = tile(x, y); @@ -175,28 +195,27 @@ public class World extends Module{ createTiles(); } - Vars.control.getSpawnPoints().clear(); + spawns.clear(); Entities.resizeTree(0, 0, map.getWidth() * tilesize, map.getHeight() * tilesize); this.seed = seed; - WorldGenerator.generate(map.pixmap, tiles); - if(control.getCore() == null) return; + core = WorldGenerator.generate(map.pixmap, tiles, spawns); - control.getInput().placeBlock(control.getCore().x, control.getCore().y, ProductionBlocks.core, 0, false, false); + placeBlock(core.x, core.y, ProductionBlocks.core, 0); if(!map.name.equals("tutorial")){ setDefaultBlocks(); }else{ - Vars.control.getTutorial().setDefaultBlocks(control.getCore().x, control.getCore().y); + Vars.control.getTutorial().setDefaultBlocks(core.x, core.y); } pathfind.resetPaths(); } void setDefaultBlocks(){ - int x = control.getCore().x, y = control.getCore().y; + int x = core.x, y = core.y; int flip = Mathf.sign(!currentMap.flipBase); int fr = currentMap.flipBase ? 2 : 0; @@ -248,6 +267,32 @@ public class World extends Module{ } } } + + public void placeBlock(int x, int y, Block result, int rotation){ + Tile tile = world.tile(x, y); + + //just in case + if(tile == null) return; + + tile.setBlock(result, rotation); + + if(result.isMultiblock()){ + int offsetx = -(result.width-1)/2; + int offsety = -(result.height-1)/2; + + for(int dx = 0; dx < result.width; dx ++){ + for(int dy = 0; dy < result.height; dy ++){ + int worldx = dx + offsetx + x; + int worldy = dy + offsety + y; + if(!(worldx == x && worldy == y)){ + Tile toplace = world.tile(worldx, worldy); + if(toplace != null) + toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety)); + } + } + } + } + } public TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){ Entity closest = null; @@ -282,7 +327,8 @@ public class World extends Module{ return (TileEntity) closest; } - + + /**Raycast, but with world coordinates.*/ public GridPoint2 raycastWorld(float x, float y, float x2, float y2){ return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize), Mathf.scl2(x2, tilesize), Mathf.scl2(y2, tilesize)); @@ -290,8 +336,7 @@ public class World extends Module{ /** * Input is in block coordinates, not world coordinates. - * @return null if no collisions found, block position otherwise. - */ + * @return null if no collisions found, block position otherwise.*/ public GridPoint2 raycast(int x0f, int y0f, int x1, int y1){ int x0 = x0f; int y0 = y0f; diff --git a/core/src/io/anuke/mindustry/entities/Bullet.java b/core/src/io/anuke/mindustry/entities/Bullet.java index 6089fd4cc0..9c21295444 100644 --- a/core/src/io/anuke/mindustry/entities/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/Bullet.java @@ -82,7 +82,7 @@ public class Bullet extends BulletEntity{ @Override public Bullet add(){ - return super.add(Vars.control.bulletGroup); + return super.add(Vars.bulletGroup); } } diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 7a10f758f1..20c3c9f525 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -54,7 +54,7 @@ public class Player extends SyncEntity{ public boolean collides(SolidEntity other){ if(other instanceof Bullet){ Bullet b = (Bullet)other; - if(!Vars.control.isFriendlyFire() && b.owner instanceof Player){ + if(!Vars.logic.friendlyFire && b.owner instanceof Player){ return false; } } @@ -91,7 +91,7 @@ public class Player extends SyncEntity{ set(-9999, -9999); Timers.run(respawnduration, () -> { heal(); - set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy()); + set(logic.getSpawnX(), logic.getSpawnY()); }); } @@ -159,8 +159,8 @@ public class Player extends SyncEntity{ vector.y += ya*speed; vector.x += xa*speed; - boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.getInput().recipe == null - && !ui.hasMouse() && !control.getInput().onConfigurable(); + boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.input().recipe == null + && !ui.hasMouse() && !control.input().onConfigurable(); if(shooting){ weaponLeft.update(player, true); diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index e2c6e61982..f6522d2829 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -88,7 +88,7 @@ public class Enemy extends SyncEntity { @Override public Enemy add(){ - return add(Vars.control.enemyGroup); + return add(Vars.enemyGroup); } @Override diff --git a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java index 59452857b2..bb7d5071ab 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java +++ b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java @@ -21,7 +21,7 @@ import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Tmp; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; public class EnemyType { @@ -80,11 +80,11 @@ public class EnemyType { Graphics.flush(); - if(Vars.showPaths){ + if(showPaths){ Draw.tscl(0.25f); Draw.text((int)enemy.idletime + "\n" + Strings.toFixed(enemy.totalMove.x, 2) + ", " + Strings.toFixed(enemy.totalMove.x, 2), enemy.x, enemy.y); - Draw.tscl(Vars.fontscale); + Draw.tscl(fontscale); } Shaders.outline.lighten = 0f; @@ -134,8 +134,8 @@ public class EnemyType { enemy.angle = Mathf.slerp(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed * Timers.delta()); } - enemy.x = Mathf.clamp(enemy.x, 0, Vars.world.width() * Vars.tilesize); - enemy.y = Mathf.clamp(enemy.y, 0, Vars.world.height() * Vars.tilesize); + enemy.x = Mathf.clamp(enemy.x, 0, world.width() * tilesize); + enemy.y = Mathf.clamp(enemy.y, 0, world.height() * tilesize); } public void move(Enemy enemy){ @@ -147,7 +147,7 @@ public class EnemyType { return; } - Tile core = Vars.control.getCore(); + Tile core = world.getCore(); if(enemy.idletime > maxIdleLife){ enemy.onDeath(); @@ -161,7 +161,7 @@ public class EnemyType { vec = Tmp.v1.setZero(); if(targetCore) enemy.target = core.entity; }else{ - vec = Vars.world.pathfinder().find(enemy); + vec = world.pathfinder().find(enemy); vec.sub(enemy.x, enemy.y).limit(speed); } @@ -171,7 +171,7 @@ public class EnemyType { float attractRange = avoidRange + 7f; float avoidSpeed = this.speed/2.7f; - Entities.getNearby(Vars.control.enemyGroup, enemy.x, enemy.y, range, en -> { + Entities.getNearby(enemyGroup, enemy.x, enemy.y, range, en -> { Enemy other = (Enemy)en; if(other == enemy) return; float dst = other.distanceTo(enemy); @@ -202,14 +202,14 @@ public class EnemyType { } if(enemy.timer.get(timerTarget, 15) && !nearCore){ - enemy.target = Vars.world.findTileTarget(enemy.x, enemy.y, null, range, false); + enemy.target = world.findTileTarget(enemy.x, enemy.y, null, range, false); //no tile found if(enemy.target == null){ - enemy.target = Entities.getClosest(Vars.control.playerGroup, enemy.x, enemy.y, range, e -> !((Player)e).isAndroid); + enemy.target = Entities.getClosest(playerGroup, enemy.x, enemy.y, range, e -> !((Player)e).isAndroid); } }else if(nearCore){ - enemy.target = Vars.control.getCore().entity; + enemy.target = world.getCore().entity; } if(enemy.target != null && bullet != null){ @@ -220,7 +220,7 @@ public class EnemyType { public void updateShooting(Enemy enemy){ float reload = this.reload / Math.max(enemy.tier / 1.5f, 1f); - if(enemy.timer.get(timerReload, reload * Vars.multiplier)){ + if(enemy.timer.get(timerReload, reload * multiplier)){ shoot(enemy); } } @@ -234,7 +234,7 @@ public class EnemyType { public void onDeath(Enemy enemy){ if(Net.active() && Net.server()){ - Vars.netServer.handleEnemyDeath(enemy); + netServer.handleEnemyDeath(enemy); } Effects.effect(Fx.explosion, enemy); @@ -249,7 +249,7 @@ public class EnemyType { if(enemy.spawner != null){ enemy.spawner.spawned --; }else{ - Vars.control.enemyDeath(); + Vars.control.enemyDeath(); //TODO } } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java b/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java index 08f3ecc340..7f3eab5017 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java +++ b/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java @@ -30,8 +30,8 @@ public class FortressType extends EnemyType { @Override public void move(Enemy enemy){ - if(enemy.distanceTo(Vars.control.getCore().worldx(), - Vars.control.getCore().worldy()) <= 90f){ + if(enemy.distanceTo(Vars.world.getCore().worldx(), + Vars.world.getCore().worldy()) <= 90f){ if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){ Angles.translation(enemy.angle, 20f); diff --git a/core/src/io/anuke/mindustry/game/DefaultKeybinds.java b/core/src/io/anuke/mindustry/game/DefaultKeybinds.java new file mode 100644 index 0000000000..73005e7f12 --- /dev/null +++ b/core/src/io/anuke/mindustry/game/DefaultKeybinds.java @@ -0,0 +1,62 @@ +package io.anuke.mindustry.game; + +import com.badlogic.gdx.Application.ApplicationType; +import com.badlogic.gdx.Gdx; +import io.anuke.ucore.core.Inputs.Axis; +import io.anuke.ucore.core.Inputs.DeviceType; +import io.anuke.ucore.core.KeyBinds; +import io.anuke.ucore.util.Input; + +public class DefaultKeybinds { + + public static void load(){ + KeyBinds.defaults( + "move_x", new Axis(Input.A, Input.D), + "move_y", new Axis(Input.S, Input.W), + "select", Input.MOUSE_LEFT, + "break", Input.MOUSE_RIGHT, + "shoot", Input.MOUSE_LEFT, + "zoom_hold", Input.CONTROL_LEFT, + "zoom", new Axis(Input.SCROLL), + "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, + "pause", Input.SPACE, + "dash", Input.SHIFT_LEFT, + "rotate_alt", new Axis(Input.R, Input.E), + "rotate", new Axis(Input.SCROLL), + "player_list", Input.TAB, + "chat", Input.ENTER, + "weapon_1", Input.NUM_1, + "weapon_2", Input.NUM_2, + "weapon_3", Input.NUM_3, + "weapon_4", Input.NUM_4, + "weapon_5", Input.NUM_5, + "weapon_6", Input.NUM_6 + ); + + KeyBinds.defaults( + DeviceType.controller, + "move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS), + "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), + "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), + "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), + "select", Input.CONTROLLER_R_BUMPER, + "break", Input.CONTROLLER_L_BUMPER, + "shoot", Input.CONTROLLER_R_TRIGGER, + "zoom_hold", Input.ANY_KEY, + "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), + "menu", Input.CONTROLLER_X, + "pause", Input.CONTROLLER_L_TRIGGER, + "dash", Input.CONTROLLER_Y, + "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), + "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), + "player_list", Input.CONTROLLER_START, + "chat", Input.ENTER, + "weapon_1", Input.NUM_1, + "weapon_2", Input.NUM_2, + "weapon_3", Input.NUM_3, + "weapon_4", Input.NUM_4, + "weapon_5", Input.NUM_5, + "weapon_6", Input.NUM_6 + ); + } +} diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java new file mode 100644 index 0000000000..0c9da94619 --- /dev/null +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -0,0 +1,27 @@ +package io.anuke.mindustry.game; + +import io.anuke.mindustry.core.GameState.State; +import io.anuke.ucore.function.Event; + +public class EventType { + + public interface PlayEvent extends Event{ + void handle(); + } + + public interface ResetEvent extends Event{ + void handle(); + } + + public interface WaveEvent extends Event{ + void handle(); + } + + public interface GameOver extends Event{ + void handle(); + } + + public interface StateChange extends Event{ + void handle(State from, State to); + } +} diff --git a/core/src/io/anuke/mindustry/game/Inventory.java b/core/src/io/anuke/mindustry/game/Inventory.java new file mode 100644 index 0000000000..7054bdb6fd --- /dev/null +++ b/core/src/io/anuke/mindustry/game/Inventory.java @@ -0,0 +1,70 @@ +package io.anuke.mindustry.game; + +import io.anuke.mindustry.resource.Item; +import io.anuke.mindustry.resource.ItemStack; + +import java.util.Arrays; + +import static io.anuke.mindustry.Vars.debug; + +public class Inventory { + private final int[] items = new int[Item.getAllItems().size]; + + public void clearItems(){ + Arrays.fill(items, 0); + + addItem(Item.stone, 40); + + if(debug){ + Arrays.fill(items, 99999); + } + } + + public void fill(){ + Arrays.fill(items, 999999999); + } + + public int getAmount(Item item){ + return items[item.id]; + } + + public void addItem(Item item, int amount){ + items[item.id] += amount; + } + + public boolean hasItems(ItemStack[] items){ + for(ItemStack stack : items) + if(!hasItem(stack)) + return false; + return true; + } + + public boolean hasItems(ItemStack[] items, int scaling){ + for(ItemStack stack : items) + if(!hasItem(stack.item, stack.amount * scaling)) + return false; + return true; + } + + public boolean hasItem(ItemStack req){ + return items[req.item.id] >= req.amount; + } + + public boolean hasItem(Item item, int amount){ + return items[item.id] >= amount; + } + + public void removeItem(ItemStack req){ + items[req.item.id] -= req.amount; + if(items[req.item.id] < 0) items[req.item.id] = 0; //prevents negative item glitches in multiplayer + } + + public void removeItems(ItemStack... reqs){ + for(ItemStack req : reqs) + removeItem(req); + } + + public int[] getItems(){ + return items; + } +} diff --git a/core/src/io/anuke/mindustry/game/SpawnPoint.java b/core/src/io/anuke/mindustry/game/SpawnPoint.java index 3c647cab63..62e41e70bb 100644 --- a/core/src/io/anuke/mindustry/game/SpawnPoint.java +++ b/core/src/io/anuke/mindustry/game/SpawnPoint.java @@ -12,4 +12,8 @@ public class SpawnPoint{ public PathFinder finder; public SmoothGraphPath path = new SmoothGraphPath(); public PathFinderRequest request; + + public SpawnPoint(Tile start){ + this.start = start; + } } diff --git a/core/src/io/anuke/mindustry/game/Tutorial.java b/core/src/io/anuke/mindustry/game/Tutorial.java index 847b5f0f35..041a8b79f7 100644 --- a/core/src/io/anuke/mindustry/game/Tutorial.java +++ b/core/src/io/anuke/mindustry/game/Tutorial.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.game; import com.badlogic.gdx.math.GridPoint2; -import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.resource.Item; @@ -19,8 +18,7 @@ import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Tmp; -import static io.anuke.mindustry.Vars.control; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; public class Tutorial{ private Stage stage; @@ -32,7 +30,7 @@ public class Tutorial{ } public boolean active(){ - return world.getMap() != null && world.getMap().name.equals("tutorial") && !GameState.is(State.menu); + return world.getMap() != null && world.getMap().name.equals("tutorial") && !state.is(State.menu); } public void buildUI(table table){ @@ -73,7 +71,7 @@ public class Tutorial{ //info.setText(stage.text); if(stage.showBlock){ - Tile tile = world.tile(control.getCore().x + stage.blockPlaceX, control.getCore().y + stage.blockPlaceY); + Tile tile = world.tile(world.getCore().x + stage.blockPlaceX, world.getCore().y + stage.blockPlaceY); if(tile.block() == stage.targetBlock && (tile.getRotation() == stage.blockRotation || stage.blockRotation == -1)){ move(true); @@ -88,7 +86,7 @@ public class Tutorial{ public void complete(){ //new TextDialog("Congratulations!", "You have completed the tutorial!").padText(Unit.dp.inPixels(10f)).show(); - GameState.set(State.menu); + state.set(State.menu); reset(); } @@ -104,7 +102,7 @@ public class Tutorial{ if(current < 0 || current >= Stage.values().length){ break; - }else if(Vars.android == Stage.values()[current].androidOnly || Vars.android != Stage.values()[current].desktopOnly){ + }else if(android == Stage.values()[current].androidOnly || android != Stage.values()[current].desktopOnly){ stage = Stage.values()[current]; stage.onSwitch(); break; @@ -121,7 +119,7 @@ public class Tutorial{ if(current < 0 || current >= Stage.values().length){ return false; - }else if(Vars.android == Stage.values()[current].androidOnly || Vars.android != Stage.values()[current].desktopOnly){ + }else if(android == Stage.values()[current].androidOnly || android != Stage.values()[current].desktopOnly){ return true; } } @@ -198,7 +196,7 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttondistribution").fireClick(); + ui.find("sectionbuttondistribution").fireClick(); } }, placeConveyorDesktop{ @@ -232,7 +230,7 @@ public class Tutorial{ } void onSwitch(){ - //Vars.player.recipe = null; + //player.recipe = null; } }, placeDrill{ @@ -247,7 +245,7 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttonproduction").fireClick(); + ui.find("sectionbuttonproduction").fireClick(); } }, blockInfo{ @@ -273,7 +271,7 @@ public class Tutorial{ } void onSwitch(){ - control.getInput().recipe = null; + control.input().recipe = null; } }, drillInfo{ @@ -291,12 +289,12 @@ public class Tutorial{ void onSwitch(){ for(int flip : new int[]{1, -1}){ - world.tile(control.getCore().x + flip, control.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); - world.tile(control.getCore().x + flip*2, control.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); - world.tile(control.getCore().x + flip*2, control.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 2 * flip); - world.tile(control.getCore().x + flip*2, control.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 1); - world.tile(control.getCore().x + flip*2, control.getCore().y - 4).setFloor(Blocks.stone); - world.tile(control.getCore().x + flip*2, control.getCore().y - 4).setBlock(ProductionBlocks.stonedrill); + world.tile(world.getCore().x + flip, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); + world.tile(world.getCore().x + flip*2, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); + world.tile(world.getCore().x + flip*2, world.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 2 * flip); + world.tile(world.getCore().x + flip*2, world.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 1); + world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setFloor(Blocks.stone); + world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setBlock(ProductionBlocks.stonedrill); } } @@ -335,7 +333,7 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttonweapon").fireClick(); + ui.find("sectionbuttonweapon").fireClick(); } }, placedTurretAmmo{ @@ -345,10 +343,10 @@ public class Tutorial{ void onSwitch(){ for(int i = 0; i < 4; i ++){ - world.tile(control.getCore().x + 2, control.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1); + world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1); } - control.getInput().recipe = null; + control.input().recipe = null; } }, turretExplanation{ @@ -375,31 +373,7 @@ public class Tutorial{ } }, //TODO re-add tutorial on weapons - /* - purchaseWeapons{ - { - desktopOnly = true; - canBack = false; - } - - void onSwitch(){ - Vars.control.addItem(Item.steel, 60); - Vars.control.addItem(Item.iron, 60); - } - }, - switchWeapons{ - { - canBack = false; - desktopOnly = true; - } - - void onSwitch(){ - if(!Vars.control.getWeapons().contains(Weapon.triblaster, true)){ - Vars.control.getWeapons().add(Weapon.triblaster); - Vars.ui.hudfrag.updateWeapons(); - } - } - },*/ + spawnWave{ float warmup = 0f; { @@ -409,14 +383,14 @@ public class Tutorial{ void update(Tutorial t){ warmup += Timers.delta(); - if(Vars.control.getEnemiesRemaining() == 0 && warmup > 60f){ + if(state.enemies == 0 && warmup > 60f){ t.move(true); } } void onSwitch(){ warmup = 0f; - Vars.control.runWave(); + logic.runWave(); } }, pumpDesc{ @@ -436,9 +410,9 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttonproduction").fireClick(); - Vars.control.addItem(Item.steel, 60); - Vars.control.addItem(Item.iron, 60); + ui.find("sectionbuttonproduction").fireClick(); + state.inventory.addItem(Item.steel, 60); + state.inventory.addItem(Item.iron, 60); } }, conduitUse{ @@ -454,8 +428,8 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttondistribution").fireClick(); - world.tile(blockPlaceX + control.getCore().x, blockPlaceY + control.getCore().y).setBlock(Blocks.air); + ui.find("sectionbuttondistribution").fireClick(); + world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); } }, conduitUse2{ @@ -471,7 +445,7 @@ public class Tutorial{ } void onSwitch(){ - world.tile(blockPlaceX + control.getCore().x, blockPlaceY + control.getCore().y).setBlock(Blocks.air); + world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); } }, conduitUse3{ @@ -487,7 +461,7 @@ public class Tutorial{ } void onSwitch(){ - world.tile(blockPlaceX + control.getCore().x, blockPlaceY + control.getCore().y).setBlock(Blocks.air); + world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); } }, generator{ @@ -502,10 +476,10 @@ public class Tutorial{ } void onSwitch(){ - world.tile(blockPlaceX + control.getCore().x, blockPlaceY + control.getCore().y).setBlock(Blocks.air); - Vars.ui.find("sectionbuttonpower").fireClick(); - Vars.control.addItem(Item.steel, 60); - Vars.control.addItem(Item.iron, 60); + world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); + ui.find("sectionbuttonpower").fireClick(); + state.inventory.addItem(Item.steel, 60); + state.inventory.addItem(Item.iron, 60); } }, generatorExplain{ @@ -526,7 +500,7 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttonpower").fireClick(); + ui.find("sectionbuttonpower").fireClick(); } }, laserExplain{ @@ -552,7 +526,7 @@ public class Tutorial{ } void onSwitch(){ - Vars.ui.find("sectionbuttonpower").fireClick(); + ui.find("sectionbuttonpower").fireClick(); } }, healingTurretExplain{ @@ -573,9 +547,9 @@ public class Tutorial{ } void onSwitch(){ - Vars.control.addItem(Item.stone, 40); - Vars.control.addItem(Item.iron, 40); - Vars.ui.find("sectionbuttoncrafting").fireClick(); + state.inventory.addItem(Item.stone, 40); + state.inventory.addItem(Item.iron, 40); + ui.find("sectionbuttoncrafting").fireClick(); } }, @@ -586,18 +560,18 @@ public class Tutorial{ void onSwitch(){ for(int i = 0; i < 5; i ++){ - world.tile(control.getCore().x, control.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1); + world.tile(world.getCore().x, world.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1); } - world.tile(control.getCore().x, control.getCore().y - 6 + 1).setBlock(DistributionBlocks.tunnel, 3); - world.tile(control.getCore().x, control.getCore().y - 6 + 2).setBlock(DefenseBlocks.stonewall, 0); - world.tile(control.getCore().x, control.getCore().y - 6 + 3).setBlock(DistributionBlocks.tunnel, 1); + world.tile(world.getCore().x, world.getCore().y - 6 + 1).setBlock(DistributionBlocks.tunnel, 3); + world.tile(world.getCore().x, world.getCore().y - 6 + 2).setBlock(DefenseBlocks.stonewall, 0); + world.tile(world.getCore().x, world.getCore().y - 6 + 3).setBlock(DistributionBlocks.tunnel, 1); - world.tile(control.getCore().x+1, control.getCore().y - 8).setBlock(ProductionBlocks.irondrill); - world.tile(control.getCore().x-1, control.getCore().y - 8).setBlock(ProductionBlocks.coaldrill); + world.tile(world.getCore().x+1, world.getCore().y - 8).setBlock(ProductionBlocks.irondrill); + world.tile(world.getCore().x-1, world.getCore().y - 8).setBlock(ProductionBlocks.coaldrill); - world.tile(control.getCore().x+1, control.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2); - world.tile(control.getCore().x-1, control.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0); + world.tile(world.getCore().x+1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2); + world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0); } }, tunnelExplain{ diff --git a/core/src/io/anuke/mindustry/game/UpgradeInventory.java b/core/src/io/anuke/mindustry/game/UpgradeInventory.java new file mode 100644 index 0000000000..24fadf2d12 --- /dev/null +++ b/core/src/io/anuke/mindustry/game/UpgradeInventory.java @@ -0,0 +1,25 @@ +package io.anuke.mindustry.game; + +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.resource.Weapon; + +public class UpgradeInventory { + private final Array weapons = new Array<>(); + + public boolean hasWeapon(Weapon weapon){ + return weapons.contains(weapon, true); + } + + public void addWeapon(Weapon weapon){ + weapons.add(weapon); + } + + public Array getWeapons(){ + return weapons; + } + + public void reset(){ + weapons.clear(); + weapons.add(Weapon.blaster); + } +} diff --git a/core/src/io/anuke/mindustry/input/GestureHandler.java b/core/src/io/anuke/mindustry/input/GestureHandler.java index c04a94ed2a..f4c356ebca 100644 --- a/core/src/io/anuke/mindustry/input/GestureHandler.java +++ b/core/src/io/anuke/mindustry/input/GestureHandler.java @@ -31,14 +31,14 @@ public class GestureHandler extends GestureAdapter{ public boolean tap (float x, float y, int count, int button) { if(ui.hasMouse() || input.brokeBlock) return false; - if(!control.getInput().placeMode.pan || control.getInput().recipe == null){ + if(!control.input().placeMode.pan || control.input().recipe == null){ input.mousex = x; input.mousey = y; - if(control.getInput().recipe == null) - control.getInput().breakMode.tapped(input.getBlockX(), input.getBlockY()); + if(control.input().recipe == null) + control.input().breakMode.tapped(input.getBlockX(), input.getBlockY()); else - control.getInput().placeMode.tapped(input.getBlockX(), input.getBlockY()); + control.input().placeMode.tapped(input.getBlockX(), input.getBlockY()); } return false; } @@ -47,13 +47,13 @@ public class GestureHandler extends GestureAdapter{ public boolean pan(float x, float y, float deltaX, float deltaY){ if(Vars.control.showCursor() && !Inputs.keyDown("select")) return false; - if(!Vars.control.showCursor() && !(control.getInput().recipe != null && Vars.control.hasItems(control.getInput().recipe.requirements) && control.getInput().placeMode.lockCamera) && - !(control.getInput().recipe == null && control.getInput().breakMode.lockCamera)){ + if(!Vars.control.showCursor() && !(control.input().recipe != null && Vars.control.hasItems(control.input().recipe.requirements) && control.input().placeMode.lockCamera) && + !(control.input().recipe == null && control.input().breakMode.lockCamera)){ float dx = deltaX*Core.camera.zoom/Core.cameraScale, dy = deltaY*Core.camera.zoom/Core.cameraScale; player.x -= dx; player.y += dy; player.targetAngle = Mathf.atan2(dx, -dy); - }else if(control.getInput().placeMode.lockCamera && (control.getInput().placeMode.pan && control.getInput().recipe != null)){ + }else if(control.input().placeMode.lockCamera && (control.input().placeMode.pan && control.input().recipe != null)){ input.mousex += deltaX; input.mousey += deltaY; } @@ -63,7 +63,7 @@ public class GestureHandler extends GestureAdapter{ @Override public boolean pinch (Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) { - if(control.getInput().recipe == null && !control.getInput().breakMode.lockCamera) + if(control.input().recipe == null && !control.input().breakMode.lockCamera) return false; if(pinch1.x < 0){ diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 94ff64ac30..0508ee77b3 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -129,7 +129,7 @@ public abstract class InputHandler extends InputAdapter{ int rotation = Vars.control.getTutorial().getPlaceRotation(); Block block = Vars.control.getTutorial().getPlaceBlock(); - if(type != block || point.x != x - control.getCore().x || point.y != y - control.getCore().y + if(type != block || point.x != x - world.getCore().x || point.y != y - world.getCore().y || (rotation != -1 && rotation != this.rotation)){ return false; } @@ -173,7 +173,7 @@ public abstract class InputHandler extends InputAdapter{ int rotation = Vars.control.getTutorial().getPlaceRotation(); Block block = Vars.control.getTutorial().getPlaceBlock(); - if(block != Blocks.air || point.x != x - control.getCore().x || point.y != y - control.getCore().y + if(block != Blocks.air || point.x != x - world.getCore().x || point.y != y - world.getCore().y || (rotation != -1 && rotation != this.rotation)){ return false; } diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index a7806eff7e..e1d58d8768 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -30,23 +30,23 @@ public enum PlaceMode{ float x = tilex * Vars.tilesize; float y = tiley * Vars.tilesize; - boolean valid = control.getInput().validPlace(tilex, tiley, control.getInput().recipe.result) && (android || control.getInput().cursorNear()); + boolean valid = control.input().validPlace(tilex, tiley, control.input().recipe.result) && (android || control.input().cursorNear()); - Vector2 offset = control.getInput().recipe.result.getPlaceOffset(); + Vector2 offset = control.input().recipe.result.getPlaceOffset(); float si = MathUtils.sin(Timers.time() / 6f) + 1.5f; Draw.color(valid ? Colors.get("place") : Colors.get("placeInvalid")); Lines.stroke(2f); - Lines.crect(x + offset.x, y + offset.y, tilesize * control.getInput().recipe.result.width + si, - tilesize * control.getInput().recipe.result.height + si); + Lines.crect(x + offset.x, y + offset.y, tilesize * control.input().recipe.result.width + si, + tilesize * control.input().recipe.result.height + si); - control.getInput().recipe.result.drawPlace(tilex, tiley, control.getInput().rotation, valid); + control.input().recipe.result.drawPlace(tilex, tiley, control.input().rotation, valid); Lines.stroke(2f); - if(control.getInput().recipe.result.rotate){ + if(control.input().recipe.result.rotate){ Draw.color(Colors.get("placeRotate")); - Tmp.v1.set(7, 0).rotate(control.getInput().rotation * 90); + Tmp.v1.set(7, 0).rotate(control.input().rotation * 90); Lines.line(x, y, x + Tmp.v1.x, y + Tmp.v1.y); } @@ -57,7 +57,7 @@ public enum PlaceMode{ } public void tapped(int tilex, int tiley){ - control.getInput().tryPlaceBlock(tilex, tiley, true); + control.input().tryPlaceBlock(tilex, tiley, true); } }, touch{ @@ -69,7 +69,7 @@ public enum PlaceMode{ } public void tapped(int x, int y){ - control.getInput().tryPlaceBlock(x, y, true); + control.input().tryPlaceBlock(x, y, true); } }, none{ @@ -89,12 +89,12 @@ public enum PlaceMode{ public void draw(int tilex, int tiley, int endx, int endy){ Tile tile = world.tile(tilex, tiley); - if(tile != null && control.getInput().validBreak(tilex, tiley)){ + if(tile != null && control.input().validBreak(tilex, tiley)){ if(tile.isLinked()) tile = tile.getLinked(); - float fract = control.getInput().breaktime / tile.getBreakTime(); + float fract = control.input().breaktime / tile.getBreakTime(); - if(android && control.getInput().breaktime > 0){ + if(android && control.input().breaktime > 0){ Draw.color(Colors.get("breakStart"), Colors.get("break"), fract); Lines.poly(tile.drawx(), tile.drawy(), 25, 4 + (1f - fract) * 26); } @@ -112,7 +112,7 @@ public enum PlaceMode{ } public void tapped(int x, int y){ - control.getInput().tryDeleteBlock(x, y, true); + control.input().tryDeleteBlock(x, y, true); } }, areaDelete{ @@ -155,7 +155,7 @@ public enum PlaceMode{ Tile tile = Vars.world.tile(cx, cy); if(tile != null && tile.getLinked() != null) tile = tile.getLinked(); - if(tile != null && control.getInput().validBreak(tile.x, tile.y)){ + if(tile != null && control.input().validBreak(tile.x, tile.y)){ Lines.crect(tile.drawx(), tile.drawy(), tile.block().width * t, tile.block().height * t); } @@ -163,7 +163,7 @@ public enum PlaceMode{ } Lines.stroke(2f); - Draw.color(control.getInput().cursorNear() ? Colors.get("break") : Colors.get("breakInvalid")); + Draw.color(control.input().cursorNear() ? Colors.get("break") : Colors.get("breakInvalid")); Lines.rect(x, y, x2 - x, y2 - y); Draw.alpha(0.3f); Draw.crect("blank", x, y, x2 - x, y2 - y); @@ -192,7 +192,7 @@ public enum PlaceMode{ for(int cx = tilex; cx <= endx; cx ++){ for(int cy = tiley; cy <= endy; cy ++){ - if(control.getInput().tryDeleteBlock(cx, cy, first)){ + if(control.input().tryDeleteBlock(cx, cy, first)){ first = false; } } @@ -247,7 +247,7 @@ public enum PlaceMode{ } float t = Vars.tilesize; - Block block = control.getInput().recipe.result; + Block block = control.input().recipe.result; Vector2 offset = block.getPlaceOffset(); process(tilex, tiley, endx, endy); @@ -276,7 +276,7 @@ public enum PlaceMode{ cursor.draw(tilex, tiley, endx, endy); }else{ Lines.stroke(2f); - Draw.color(control.getInput().cursorNear() ? Colors.get("place") : Colors.get("placeInvalid")); + Draw.color(control.input().cursorNear() ? Colors.get("place") : Colors.get("placeInvalid")); Lines.rect(x, y, x2 - x, y2 - y); Draw.alpha(0.3f); Draw.crect("blank", x, y, x2 - x, y2 - y); @@ -289,15 +289,15 @@ public enum PlaceMode{ int px = tx + cx * Mathf.sign(ex - tx), py = ty + cy * Mathf.sign(ey - ty); - if(!control.getInput().validPlace(px, py, control.getInput().recipe.result) - || !control.hasItems(control.getInput().recipe.requirements, amount)){ + if(!control.input().validPlace(px, py, control.input().recipe.result) + || !control.hasItems(control.input().recipe.requirements, amount)){ Lines.crect(px * t + offset.x, py * t + offset.y, t*block.width, t*block.height); } amount ++; } } - if(control.getInput().recipe.result.rotate){ + if(control.input().recipe.result.rotate){ float cx = tx * t, cy = ty * t; Draw.color(Colors.get("placeRotate")); Tmp.v1.set(7, 0).rotate(rotation * 90); @@ -310,12 +310,12 @@ public enum PlaceMode{ public void released(int tilex, int tiley, int endx, int endy){ process(tilex, tiley, endx, endy); - control.getInput().rotation = this.rotation; + control.input().rotation = this.rotation; boolean first = true; for(int x = 0; x <= Math.abs(this.endx - this.tilex); x ++){ for(int y = 0; y <= Math.abs(this.endy - this.tiley); y ++){ - if(control.getInput().tryPlaceBlock( + if(control.input().tryPlaceBlock( tilex + x * Mathf.sign(endx - tilex), tiley + y * Mathf.sign(endy - tiley), first)){ first = false; @@ -349,7 +349,7 @@ public enum PlaceMode{ else if(endy < tiley) rotation = 3; else - rotation = control.getInput().rotation; + rotation = control.input().rotation; if(endx < tilex){ int t = endx; diff --git a/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java b/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java index aa66e65858..5884250cd5 100755 --- a/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java +++ b/core/src/io/anuke/mindustry/mapeditor/DrawOperation.java @@ -34,7 +34,7 @@ public class DrawOperation implements Disposable{ } public void disposeFrom(){ - from.dispose(); + if(from != null) from.dispose(); } } diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index d6af000781..f3b087a7bd 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -263,7 +263,7 @@ public class NetworkIO { Vars.world.loadMap(Vars.world.maps().getMap(mapid), seed); Vars.renderer.clearTiles(); - Vars.player.set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy()); + Vars.player.set(Vars.world.getCore().worldx(), Vars.world.getCore().worldy()); for(int x = 0; x < Vars.world.width(); x ++){ for(int y = 0; y < Vars.world.height(); y ++){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index cf60e0de5d..26065ece91 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -160,12 +160,12 @@ public class LoadDialog extends FloatingDialog{ hide(); try{ slot.load(); - GameState.set(State.playing); + state.set(State.playing); Vars.ui.paused.hide(); }catch(Exception e){ UCore.error(e); Vars.ui.paused.hide(); - GameState.set(State.menu); + state.set(State.menu); Vars.control.reset(); Vars.ui.showError("$text.save.corrupted"); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index 589ab0d6c9..7ce50c288a 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -34,7 +34,7 @@ public class PausedDialog extends FloatingDialog{ shown(() -> { wasPaused = GameState.is(State.paused); - if(!Net.active()) GameState.set(State.paused); + if(!Net.active()) state.set(State.paused); }); if(!Vars.android){ @@ -43,7 +43,7 @@ public class PausedDialog extends FloatingDialog{ content().addButton("$text.back", () -> { hide(); if((!wasPaused || Net.active()) && !GameState.is(State.menu)) - GameState.set(State.playing); + state.set(State.playing); }); content().row(); @@ -88,7 +88,7 @@ public class PausedDialog extends FloatingDialog{ new imagebutton("icon-play-2", isize, () -> { hide(); if(!wasPaused && !GameState.is(State.menu)) - GameState.set(State.playing); + state.set(State.playing); }).text("$text.back").padTop(4f); new imagebutton("icon-tools", isize, ui.settings::show).text("$text.settings").padTop(4f); @@ -130,7 +130,7 @@ public class PausedDialog extends FloatingDialog{ private void runExitSave(){ if(Vars.control.getSaves().getCurrent() == null || !Vars.control.getSaves().getCurrent().isAutosave()){ - GameState.set(State.menu); + state.set(State.menu); Vars.control.getTutorial().reset(); return; } @@ -145,7 +145,7 @@ public class PausedDialog extends FloatingDialog{ e = (e.getCause() == null ? e : e.getCause()); Vars.ui.showError("[orange]"+ Bundles.get("text.savefail")+"\n[white]" + ClassReflection.getSimpleName(e.getClass()) + ": " + e.getMessage() + "\n" + "at " + e.getStackTrace()[0].getFileName() + ":" + e.getStackTrace()[0].getLineNumber()); } - GameState.set(State.menu); + state.set(State.menu); }); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java index 6ec166071c..4413f152c3 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/RestartDialog.java @@ -24,7 +24,7 @@ public class RestartDialog extends Dialog { getButtonTable().addButton("$text.menu", ()-> { hide(); - GameState.set(State.menu); + state.set(State.menu); control.reset(); }).size(130f, 60f); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 5adff6d807..e47549e7a8 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -35,7 +35,7 @@ public class SettingsMenuDialog extends SettingsDialog{ hidden(()->{ if(!GameState.is(State.menu)){ if(!wasPaused || Net.active()) - GameState.set(State.playing); + state.set(State.playing); } }); @@ -45,7 +45,7 @@ public class SettingsMenuDialog extends SettingsDialog{ if(menu.getScene() != null){ wasPaused = ((PausedDialog)menu).wasPaused; } - if(!Net.active()) GameState.set(State.paused); + if(!Net.active()) state.set(State.paused); Vars.ui.paused.hide(); } }); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index 4b205e3abb..84e3557ef0 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -33,7 +33,7 @@ public class BlocksFragment implements Fragment{ private boolean shown = true; public void build(){ - InputHandler input = control.getInput(); + InputHandler input = control.input(); new table(){{ abottom(); @@ -197,7 +197,7 @@ public class BlocksFragment implements Fragment{ } void updateRecipe(){ - Recipe recipe = Vars.control.getInput().recipe; + Recipe recipe = Vars.control.input().recipe; desctable.clear(); desctable.setTouchable(Touchable.enabled); @@ -229,7 +229,7 @@ public class BlocksFragment implements Fragment{ desclabel.setWrap(true); boolean wasPaused = GameState.is(State.paused); - GameState.set(State.paused); + state.set(State.paused); FloatingDialog d = new FloatingDialog("$text.blocks.blockinfo"); Table table = new Table(); @@ -264,7 +264,7 @@ public class BlocksFragment implements Fragment{ } d.buttons().addButton("$text.ok", ()->{ - if(!wasPaused) GameState.set(State.playing); + if(!wasPaused) state.set(State.playing); d.hide(); }).size(110, 50).pad(10f); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index d4d5465c2c..abd076d810 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -69,7 +69,7 @@ public class HudFragment implements Fragment{ if (Net.active() && Vars.android) { ui.listfrag.visible = !ui.listfrag.visible; } else { - GameState.set(GameState.is(State.paused) ? State.playing : State.paused); + state.set(GameState.is(State.paused) ? State.playing : State.paused); } }).update(i -> { if (Net.active() && Vars.android) { diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index a438643841..52908a2eea 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -32,7 +32,7 @@ public class PlacementFragment implements Fragment{ public void build(){ if(!Vars.android) return; - InputHandler input = control.getInput(); + InputHandler input = control.input(); float s = 50f; float translation = Unit.dp.scl(54f); @@ -130,7 +130,7 @@ public class PlacementFragment implements Fragment{ defaults().padBottom(-5.5f); new imagebutton("icon-" + mode.name(), "toggle", 10 * 3, () -> { - control.getInput().resetCursor(); + control.input().resetCursor(); input.breakMode = mode; input.lastBreakMode = mode; if (!mode.both){ @@ -174,7 +174,7 @@ public class PlacementFragment implements Fragment{ if (!mode.shown || mode.delete) continue; new imagebutton("icon-" + mode.name(), "toggle", 10 * 3, () -> { - control.getInput().resetCursor(); + control.input().resetCursor(); input.placeMode = mode; input.lastPlaceMode = mode; modeText(Bundles.format("text.mode.place", mode.toString())); diff --git a/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java index 552a999f9c..7892a33b5a 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java @@ -20,7 +20,7 @@ public class ToolFragment implements Fragment{ public boolean confirming; public void build(){ - InputHandler input = control.getInput(); + InputHandler input = control.input(); float isize = 14*3; @@ -44,7 +44,7 @@ public class ToolFragment implements Fragment{ input.placeMode.released(px, py, px2, py2); confirming = false; }else{ - input.placeMode.tapped(control.getInput().getBlockX(), control.getInput().getBlockY()); + input.placeMode.tapped(control.input().getBlockX(), control.input().getBlockY()); } }); @@ -61,8 +61,8 @@ public class ToolFragment implements Fragment{ tools.setPosition(v.x, v.y, Align.top); }else{ - tools.setPosition(control.getInput().getCursorX(), - Gdx.graphics.getHeight() - control.getInput().getCursorY() - 15*Core.cameraScale, Align.top); + tools.setPosition(control.input().getCursorX(), + Gdx.graphics.getHeight() - control.input().getCursorY() - 15*Core.cameraScale, Align.top); } if(input.placeMode != PlaceMode.areaDelete){ diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 2b11cd99e9..ceefd401d6 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -127,10 +127,6 @@ public class Block{ return name; } - public void onReset(){ - - } - public boolean isSolidFor(Tile tile){ return false; } diff --git a/core/src/io/anuke/mindustry/world/WorldGenerator.java b/core/src/io/anuke/mindustry/world/WorldGenerator.java index 2140c46d4c..981cd7e7a6 100644 --- a/core/src/io/anuke/mindustry/world/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/WorldGenerator.java @@ -2,13 +2,13 @@ package io.anuke.mindustry.world; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.core.GameState; -import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.EnemyTypes; +import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.world.ColorMapper.BlockPair; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.SpecialBlocks; @@ -24,11 +24,11 @@ public class WorldGenerator { put(Blocks.blackstone, Blocks.blackrock); }}; - /**Returns world size.*/ - public static void generate(Pixmap pixmap, Tile[][] tiles){ - boolean hasenemies = true, hascore = false; - + /**Returns the core (starting) block. Should fill spawns with the correct spawnpoints.*/ + public static Tile generate(Pixmap pixmap, Tile[][] tiles, Array spawns){ Noise.setSeed(Vars.world.getSeed()); + + Tile core = null; for(int x = 0; x < pixmap.getWidth(); x ++){ for(int y = 0; y < pixmap.getHeight(); y ++){ @@ -45,12 +45,10 @@ public class WorldGenerator { if(block == SpecialBlocks.playerSpawn){ block = Blocks.air; - Vars.control.setCore(Vars.world.tile(x, y)); - hascore = true; + core = Vars.world.tile(x, y); }else if(block == SpecialBlocks.enemySpawn){ block = Blocks.air; - Vars.control.addSpawnPoint(Vars.world.tile(x, y)); - hasenemies = true; + spawns.add(new SpawnPoint(tiles[x][y])); } if(block == Blocks.air && Mathf.chance(0.025) && rocks.containsKey(floor)){ @@ -91,16 +89,8 @@ public class WorldGenerator { tiles[x][y].updateOcclusion(); } } - - if(!hascore){ - GameState.set(State.menu); - Vars.ui.showError("[orange]Invalid map:[] this map has no core!"); - } - - if(!hasenemies){ - GameState.set(State.menu); - Vars.ui.showError("[orange]Invalid map:[] this map has no enemy spawnpoints!"); - } + + return core; } private static IntMap map(Object...objects){