477 lines
10 KiB
Java
477 lines
10 KiB
Java
package io.anuke.mindustry;
|
|
|
|
import static io.anuke.mindustry.Vars.*;
|
|
|
|
import com.badlogic.gdx.Application.ApplicationType;
|
|
import com.badlogic.gdx.Gdx;
|
|
import com.badlogic.gdx.Input.Keys;
|
|
import com.badlogic.gdx.input.GestureDetector;
|
|
import com.badlogic.gdx.utils.Array;
|
|
import com.badlogic.gdx.utils.ObjectMap;
|
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
import com.badlogic.gdx.utils.reflect.Constructor;
|
|
|
|
import io.anuke.mindustry.GameState.State;
|
|
import io.anuke.mindustry.ai.Pathfind;
|
|
import io.anuke.mindustry.entities.EnemySpawn;
|
|
import io.anuke.mindustry.entities.Player;
|
|
import io.anuke.mindustry.entities.enemies.*;
|
|
import io.anuke.mindustry.input.AndroidInput;
|
|
import io.anuke.mindustry.input.GestureHandler;
|
|
import io.anuke.mindustry.input.Input;
|
|
import io.anuke.mindustry.io.SaveIO;
|
|
import io.anuke.mindustry.resource.Item;
|
|
import io.anuke.mindustry.resource.ItemStack;
|
|
import io.anuke.mindustry.resource.Weapon;
|
|
import io.anuke.mindustry.world.*;
|
|
import io.anuke.ucore.UCore;
|
|
import io.anuke.ucore.core.*;
|
|
import io.anuke.ucore.entities.Entities;
|
|
import io.anuke.ucore.entities.Entity;
|
|
import io.anuke.ucore.graphics.Atlas;
|
|
import io.anuke.ucore.modules.Module;
|
|
import io.anuke.ucore.util.Mathf;
|
|
|
|
public class Control extends Module{
|
|
int targetscale = baseCameraScale;
|
|
|
|
Tutorial tutorial = new Tutorial();
|
|
boolean hiscore = false;
|
|
|
|
final Array<Weapon> weapons = new Array<>();
|
|
final ObjectMap<Item, Integer> items = new ObjectMap<>();
|
|
|
|
Array<EnemySpawn> spawns = new Array<>();
|
|
int wave = 1;
|
|
float wavetime;
|
|
float extrawavetime;
|
|
int enemies = 0;
|
|
|
|
float respawntime;
|
|
|
|
public Control(){
|
|
if(Mindustry.args.contains("-debug", false)){
|
|
Vars.debug = true;
|
|
}
|
|
|
|
UCore.log("Total blocks loaded: " + Block.getAllBlocks().size);
|
|
|
|
Gdx.input.setCatchBackKey(true);
|
|
|
|
if(android){
|
|
Inputs.addProcessor(new GestureDetector(20, 0.5f, 2, 0.15f, new GestureHandler()));
|
|
Inputs.addProcessor(new AndroidInput());
|
|
}
|
|
|
|
Effects.setShakeFalloff(10000f);
|
|
|
|
Core.atlas = new Atlas("sprites.atlas");
|
|
|
|
Sounds.load("shoot.wav", "place.wav", "explosion.wav", "enemyshoot.wav",
|
|
"corexplode.wav", "break.wav", "spawn.wav", "flame.wav", "die.wav",
|
|
"respawn.wav", "purchase.wav", "flame2.wav");
|
|
|
|
Sounds.setFalloff(9000f);
|
|
|
|
Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3");
|
|
|
|
World.loadMaps();
|
|
|
|
KeyBinds.defaults(
|
|
"up", Keys.W,
|
|
"left", Keys.A,
|
|
"down", Keys.S,
|
|
"right", Keys.D,
|
|
"rotate", Keys.R,
|
|
"rotate_back", Keys.E,
|
|
"menu", Gdx.app.getType() == ApplicationType.Android ? Keys.BACK : Keys.ESCAPE,
|
|
"pause", Keys.SPACE
|
|
);
|
|
|
|
Settings.loadAll("io.anuke.moment");
|
|
|
|
for(Map map : Map.values()){
|
|
Settings.defaults("hiscore" + map.name(), 0);
|
|
}
|
|
|
|
player = new Player();
|
|
|
|
spawns = Array.with(
|
|
|
|
new EnemySpawn(Enemy.class){{
|
|
scaling = 3;
|
|
tierscaleback = 3;
|
|
}},
|
|
new EnemySpawn(FastEnemy.class){{
|
|
after = 2;
|
|
scaling = 3;
|
|
}},
|
|
new EnemySpawn(FlamerEnemy.class){{
|
|
after = 14;
|
|
spacing = 5;
|
|
scaling = 2;
|
|
}},
|
|
new EnemySpawn(BlastEnemy.class){{
|
|
after = 12;
|
|
spacing = 2;
|
|
scaling = 3;
|
|
}},
|
|
new EnemySpawn(RapidEnemy.class){{
|
|
after = 7;
|
|
spacing = 3;
|
|
scaling = 3;
|
|
}},
|
|
new EnemySpawn(TankEnemy.class){{
|
|
after = 4;
|
|
spacing = 2;
|
|
scaling = 3;
|
|
}},
|
|
new EnemySpawn(MortarEnemy.class){{
|
|
after = 20;
|
|
spacing = 3;
|
|
scaling = 5;
|
|
}}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
public void reset(){
|
|
weapons.clear();
|
|
Vars.renderer.clearTiles();
|
|
|
|
weapons.add(Weapon.blaster);
|
|
player.weapon = weapons.first();
|
|
|
|
wave = 1;
|
|
extrawavetime = maxwavespace;
|
|
wavetime = waveSpacing();
|
|
Entities.clear();
|
|
enemies = 0;
|
|
|
|
if(!android)
|
|
player.add();
|
|
|
|
player.heal();
|
|
clearItems();
|
|
World.spawnpoints.clear();
|
|
respawntime = -1;
|
|
hiscore = false;
|
|
|
|
ui.updateItems();
|
|
ui.updateWeapons();
|
|
}
|
|
|
|
public void play(){
|
|
Vars.renderer.clearTiles();
|
|
|
|
player.x = World.core.worldx();
|
|
player.y = World.core.worldy() - Vars.tilesize*2 - ((int)(Gdx.graphics.getWidth() / (float)Core.cameraScale * 2) % 2 == 0 ? 0.5f : 0);
|
|
|
|
Core.camera.position.set(player.x, player.y, 0);
|
|
|
|
//multiplying by 2 so you start with more time in the beginning
|
|
wavetime = waveSpacing()*2;
|
|
|
|
GameState.set(State.playing);
|
|
}
|
|
|
|
public void playMap(Map map){
|
|
Vars.ui.showLoading();
|
|
|
|
Timers.run(16, ()->{
|
|
Vars.control.reset();
|
|
World.loadMap(map);
|
|
Vars.control.play();
|
|
});
|
|
|
|
Timers.run(18, ()->{
|
|
Vars.ui.hideLoading();
|
|
});
|
|
}
|
|
|
|
public boolean hasWeapon(Weapon weapon){
|
|
return weapons.contains(weapon, true);
|
|
}
|
|
|
|
public void addWeapon(Weapon weapon){
|
|
weapons.add(weapon);
|
|
}
|
|
|
|
public Array<Weapon> getWeapons(){
|
|
return weapons;
|
|
}
|
|
|
|
public void setWaveData(int enemies, int wave, float wavetime){
|
|
this.wave = wave;
|
|
this.wavetime = wavetime;
|
|
this.enemies = enemies;
|
|
this.extrawavetime = maxwavespace;
|
|
}
|
|
|
|
void runWave(){
|
|
Sounds.play("spawn");
|
|
|
|
Pathfind.updatePath();
|
|
|
|
for(EnemySpawn spawn : spawns){
|
|
for(int lane = 0; lane < World.spawnpoints.size; lane ++){
|
|
int fl = lane;
|
|
Tile tile = World.spawnpoints.get(lane);
|
|
int spawnamount = spawn.evaluate(wave, lane);
|
|
|
|
for(int i = 0; i < spawnamount; i ++){
|
|
int index = i;
|
|
|
|
Timers.run(index*50f, ()->{
|
|
try{
|
|
Constructor c = ClassReflection.getConstructor(spawn.type, int.class);
|
|
Enemy enemy = (Enemy)c.newInstance(fl);
|
|
enemy.set(tile.worldx(), tile.worldy());
|
|
enemy.tier = spawn.tier(wave, fl);
|
|
Effects.effect("spawn", enemy);
|
|
enemy.add();
|
|
|
|
enemies ++;
|
|
}catch (Exception e){
|
|
throw new RuntimeException(e);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
wave ++;
|
|
|
|
int last = Settings.getInt("hiscore" + World.getMap().name());
|
|
|
|
if(wave > last){
|
|
Settings.putInt("hiscore" + World.getMap().name(), wave);
|
|
Settings.save();
|
|
hiscore = true;
|
|
}
|
|
|
|
wavetime = waveSpacing();
|
|
extrawavetime = maxwavespace;
|
|
}
|
|
|
|
void printEnemies(int wave){
|
|
int total = 0;
|
|
for(EnemySpawn spawn : spawns){
|
|
int spawnamount = spawn.evaluate(wave, 0);
|
|
total += spawnamount;
|
|
|
|
if(spawnamount > 0){
|
|
UCore.log(ClassReflection.getSimpleName(spawn.type) + " t" + spawn.tier(wave, 0) + " x" + spawnamount);
|
|
}
|
|
}
|
|
|
|
UCore.log("Total: " + total);
|
|
}
|
|
|
|
public void enemyDeath(){
|
|
enemies --;
|
|
}
|
|
|
|
public void coreDestroyed(){
|
|
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
|
|
Sounds.play("corexplode");
|
|
Tile core = World.core;
|
|
for(int i = 0; i < 16; i ++){
|
|
Timers.run(i*2, ()->{
|
|
Effects.effect("explosion", core.worldx()+Mathf.range(40), core.worldy()+Mathf.range(40));
|
|
});
|
|
}
|
|
Effects.effect("coreexplosion", core.worldx(), core.worldy());
|
|
|
|
Timers.run(60, ()->{
|
|
ui.showRestart();
|
|
});
|
|
}
|
|
|
|
float waveSpacing(){
|
|
int scale = Settings.getInt("difficulty");
|
|
float out = (scale == 0 ? 2f : scale == 1f ? 1f : 0.5f);
|
|
return wavespace*out;
|
|
}
|
|
|
|
public boolean isHighScore(){
|
|
return hiscore;
|
|
}
|
|
|
|
public int getEnemiesRemaining(){
|
|
return enemies;
|
|
}
|
|
|
|
public float getWaveCountdown(){
|
|
return wavetime;
|
|
}
|
|
|
|
public float getRespawnTime(){
|
|
return respawntime;
|
|
}
|
|
|
|
public void setRespawnTime(float respawntime){
|
|
this.respawntime = respawntime;
|
|
}
|
|
|
|
public int getWave(){
|
|
return wave;
|
|
}
|
|
|
|
public Tutorial getTutorial(){
|
|
return tutorial;
|
|
}
|
|
|
|
public void clearItems(){
|
|
items.clear();
|
|
|
|
items.put(Item.stone, 40);
|
|
|
|
if(debug){
|
|
for(Item item : Item.values())
|
|
items.put(item, 2000000);
|
|
}
|
|
}
|
|
|
|
public int getAmount(Item item){
|
|
return items.get(item, 0);
|
|
}
|
|
|
|
public void addItem(Item item, int amount){
|
|
items.put(item, items.get(item, 0)+amount);
|
|
ui.updateItems();
|
|
}
|
|
|
|
public boolean hasItems(ItemStack[] items){
|
|
for(ItemStack stack : items)
|
|
if(!hasItem(stack))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
public boolean hasItem(ItemStack req){
|
|
return items.get(req.item, 0) >= req.amount;
|
|
}
|
|
|
|
public void removeItem(ItemStack req){
|
|
items.put(req.item, items.get(req.item, 0)-req.amount);
|
|
ui.updateItems();
|
|
}
|
|
|
|
public void removeItems(ItemStack... reqs){
|
|
for(ItemStack req : reqs)
|
|
items.put(req.item, items.get(req.item, 0)-req.amount);
|
|
ui.updateItems();
|
|
}
|
|
|
|
public ObjectMap<Item, Integer> getItems(){
|
|
return items;
|
|
}
|
|
|
|
@Override
|
|
public void init(){
|
|
Musics.shuffleAll();
|
|
|
|
Entities.initPhysics();
|
|
|
|
Entities.setCollider(tilesize, (x, y)->{
|
|
return World.solid(x, y);
|
|
});
|
|
|
|
EffectCreator.create();
|
|
}
|
|
|
|
@Override
|
|
public void update(){
|
|
|
|
if(debug){
|
|
if(Inputs.keyUp(Keys.O)){
|
|
Timers.mark();
|
|
SaveIO.write(Gdx.files.local("mapsave.mins"));
|
|
log("Save time taken: " + Timers.elapsed());
|
|
}
|
|
|
|
if(Inputs.keyUp(Keys.P)){
|
|
Timers.mark();
|
|
SaveIO.load(Gdx.files.local("mapsave.mins"));
|
|
log("Load time taken: " + Timers.elapsed());
|
|
Vars.renderer.clearTiles();
|
|
}
|
|
|
|
if(Inputs.keyUp(Keys.C)){
|
|
for(Entity entity : Entities.all()){
|
|
if(entity instanceof Enemy){
|
|
entity.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
if(Inputs.keyUp(Keys.Y)){
|
|
new FastEnemy(0).set(player.x, player.y).add();
|
|
}
|
|
}
|
|
|
|
if(!GameState.is(State.menu)){
|
|
|
|
if(Inputs.keyUp("pause") && (GameState.is(State.paused) || GameState.is(State.playing))){
|
|
GameState.set(GameState.is(State.playing) ? State.paused : State.playing);
|
|
}
|
|
|
|
if(Inputs.keyUp("menu")){
|
|
if(GameState.is(State.paused)){
|
|
ui.hideMenu();
|
|
GameState.set(State.playing);
|
|
}else{
|
|
ui.showMenu();
|
|
GameState.set(State.paused);
|
|
}
|
|
}
|
|
|
|
if(!GameState.is(State.paused)){
|
|
|
|
if(respawntime > 0){
|
|
|
|
respawntime -= delta();
|
|
|
|
if(respawntime <= 0){
|
|
player.set(World.core.worldx(), World.core.worldy()-Vars.tilesize*2);
|
|
player.heal();
|
|
player.add();
|
|
Effects.sound("respawn");
|
|
ui.fadeRespawn(false);
|
|
}
|
|
}
|
|
|
|
if(!tutorial.active()){
|
|
extrawavetime -= delta();
|
|
|
|
if(enemies <= 0){
|
|
wavetime -= delta();
|
|
}
|
|
}else{
|
|
tutorial.update();
|
|
}
|
|
|
|
if(wavetime <= 0 || (debug && Inputs.keyUp(Keys.F)) || extrawavetime <= 0){
|
|
runWave();
|
|
}
|
|
|
|
Entities.update();
|
|
}
|
|
|
|
if(!android){
|
|
Input.doInput();
|
|
}else{
|
|
AndroidInput.doInput();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void dispose(){
|
|
World.disposeMaps();
|
|
}
|
|
|
|
}
|