Many bugfixes for multiplayer, QoL, balancing, new difficulties
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
public enum Difficulty {
|
||||
easy(4f, 2f),
|
||||
normal(2f, 1f),
|
||||
hard(1.5f, 0.5f),
|
||||
insane(0.5f, 0.25f),
|
||||
purge(0.4f, 0.01f);
|
||||
|
||||
/**The scaling of how many waves it takes for one more enemy of a type to appear.
|
||||
* For example: with enemeyScaling = 2 and the default scaling being 2, it would take 4 waves for
|
||||
* an enemy spawn to go from 1->2 enemies.*/
|
||||
public final float enemyScaling;
|
||||
/**Multiplier of the time between waves.*/
|
||||
public final float timeScaling;
|
||||
|
||||
Difficulty(float enemyScaling, float timeScaling){
|
||||
this.enemyScaling = enemyScaling;
|
||||
this.timeScaling = timeScaling;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Bundles.get("setting.difficulty." + name());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
public class EnemySpawn{
|
||||
/**The enemy type spawned*/
|
||||
public final EnemyType type;
|
||||
/**When this spawns should end*/
|
||||
protected int before = Integer.MAX_VALUE;
|
||||
/**When this spawns should start*/
|
||||
protected int after;
|
||||
/**The spacing, in waves, of spawns. 2 = spawns every other wave*/
|
||||
protected int spacing = 1;
|
||||
/**How many waves need to pass after the start of this spawn for the tier to increase by one*/
|
||||
protected int tierscale = 14;
|
||||
/**How many less enemies there are, every time the tier increases*/
|
||||
protected int tierscaleback = 1;
|
||||
/**The tier this spawn starts at.*/
|
||||
protected int tier = 1;
|
||||
/**Maximum amount of enemies that spawn*/
|
||||
protected int max = 17;
|
||||
/**How many waves need to pass before the amount of enemies increases by 1*/
|
||||
protected float scaling = 9999f;
|
||||
/**Amount of enemies spawned initially, with no scaling*/
|
||||
protected int amount = 1;
|
||||
|
||||
public EnemySpawn(EnemyType type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int evaluate(int wave, int lane){
|
||||
if(wave < after || wave > before || (wave - after) % spacing != 0){
|
||||
return 0;
|
||||
}
|
||||
float scaling = this.scaling * Vars.control.getDifficulty().enemyScaling;
|
||||
|
||||
return Math.min(amount-1 + Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max);
|
||||
}
|
||||
|
||||
public int tier(int wave, int lane){
|
||||
return Mathf.clamp(tier + (wave-after)/tierscale, 1, EnemyType.maxtier);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
|
||||
public enum GameMode{
|
||||
waves,
|
||||
sandbox{
|
||||
{
|
||||
infiniteResources = true;
|
||||
toggleWaves = true;
|
||||
}
|
||||
},
|
||||
freebuild{
|
||||
{
|
||||
toggleWaves = true;
|
||||
}
|
||||
};
|
||||
public boolean infiniteResources;
|
||||
public boolean toggleWaves;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return Bundles.get("mode."+name()+".name");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import com.badlogic.gdx.ai.pfa.PathFinder;
|
||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
||||
|
||||
import io.anuke.mindustry.ai.SmoothGraphPath;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
public class SpawnPoint{
|
||||
public Tile start;
|
||||
public Tile[] pathTiles;
|
||||
public PathFinder<Tile> finder;
|
||||
public SmoothGraphPath path = new SmoothGraphPath();
|
||||
public PathFinderRequest<Tile> request;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package io.anuke.mindustry.game;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.entities.enemies.EnemyTypes;
|
||||
|
||||
public class WaveCreator{
|
||||
|
||||
public static Array<EnemySpawn> getSpawns(){
|
||||
|
||||
return Array.with(
|
||||
new EnemySpawn(EnemyTypes.standard){{
|
||||
scaling = 1;
|
||||
before = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.fast){{
|
||||
scaling = 1;
|
||||
after = 3;
|
||||
spacing = 5;
|
||||
amount = 3;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.blast){{
|
||||
after = 4;
|
||||
amount = 2;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.tank){{
|
||||
after = 5;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
amount = 2;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.rapid){{
|
||||
after = 7;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
amount = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.healer){{
|
||||
after = 5;
|
||||
spacing = 5;
|
||||
scaling = 1;
|
||||
amount = 1;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.standard){{
|
||||
scaling = 3;
|
||||
after = 8;
|
||||
spacing = 4;
|
||||
tier = 2;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.titan){{
|
||||
after = 6;
|
||||
amount = 2;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.flamer){{
|
||||
after = 12;
|
||||
amount = 2;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.emp){{
|
||||
after = 15;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.blast){{
|
||||
after = 4 + 5 + 5;
|
||||
amount = 3;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
//boss wave
|
||||
new EnemySpawn(EnemyTypes.fortress){{
|
||||
after = 16;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 1;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.titan){{
|
||||
after = 16;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
tierscaleback = 0;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.healer){{
|
||||
after = 16;
|
||||
spacing = 5;
|
||||
scaling = 2;
|
||||
amount = 2;
|
||||
}},
|
||||
//end boss wave
|
||||
|
||||
//enchanced boss wave
|
||||
new EnemySpawn(EnemyTypes.mortar){{
|
||||
after = 16 + 5;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}},
|
||||
|
||||
new EnemySpawn(EnemyTypes.emp){{
|
||||
after = 16 + 5;
|
||||
amount = 1;
|
||||
spacing = 5;
|
||||
scaling = 3;
|
||||
}}
|
||||
//end enchanced boss wave
|
||||
);
|
||||
}
|
||||
|
||||
public static void testWaves(int from, int to){
|
||||
Array<EnemySpawn> spawns = getSpawns();
|
||||
for(int i = from; i <= to; i ++){
|
||||
System.out.print(i+": ");
|
||||
int total = 0;
|
||||
for(EnemySpawn spawn : spawns){
|
||||
int a = spawn.evaluate(i, 0);
|
||||
int t = spawn.tier(i, 0);
|
||||
total += a;
|
||||
|
||||
if(a > 0){
|
||||
System.out.print(a+"x" + spawn.type.name + "-" + t + " ");
|
||||
}
|
||||
}
|
||||
System.out.print(" (" + total + ")");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user