Added new wave spawning system

This commit is contained in:
Anuken
2018-06-27 10:56:39 -04:00
parent c89123b18a
commit e799187aaf
19 changed files with 260 additions and 160 deletions

View File

@@ -1,47 +0,0 @@
package io.anuke.mindustry.game;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.state;
public class EnemySpawn{
/**The enemy type spawned*/
public final UnitType 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 = 17;
/**How many more enemies there are, every time the tier increases*/
protected int tierscaleback = 0;
/**The tier this spawn starts at.*/
protected int tier = 1;
/**Maximum amount of enemies that spawn*/
protected int max = 60;
/**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(UnitType type){
this.type = type;
}
//TODO
public int evaluate(int wave, int lane){
if(wave < after || wave > before || (wave - after) % spacing != 0){
return 0;
}
float scaling = this.scaling * state.difficulty.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, 5);
}
}

View File

@@ -0,0 +1,93 @@
package io.anuke.mindustry.game;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.GroundUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.mindustry.type.Weapon;
import static io.anuke.mindustry.Vars.state;
/**A spawn group defines spawn information for a specific type of unit, with optional extra information like
* weapon equipped, ammo used, and status effects.
* Each spawn group can have multiple sub-groups spawned in different areas of the map.*/
public class SpawnGroup {
/**The unit type spawned*/
public final UnitType type;
/**When this spawn should end*/
protected int end = Integer.MAX_VALUE;
/**When this spawn should start*/
protected int begin;
/**The spacing, in waves, of spawns. For example, 2 = spawns every other wave*/
protected int spacing = 1;
/**Maximum amount of units that spawn*/
protected int max = 60;
/**How many waves need to pass before the amount of units spawned increases by 1*/
protected float unitScaling = 9999f;
/**How many waves need to pass before the amount of instances of this group increases by 1*/
protected float groupScaling = 9999f;
/**Amount of enemies spawned initially, with no scaling*/
protected int unitAmount = 1;
/**Amount of enemies spawned initially, with no scaling*/
protected int groupAmount = 1;
/**Weapon used by the spawned unit. Null to disable. Only applicable to ground units.*/
protected Weapon weapon;
/**Status effect applied to the spawned unit. Null to disable.*/
protected StatusEffect effect;
/**Items this unit spawns with. Null to disable.*/
protected ItemStack items;
/**Ammo type this unit spawns with. Null to use the first available ammo.*/
protected Item ammoItem;
public SpawnGroup(UnitType type){
this.type = type;
}
/**Returns the amount of units spawned on a specific wave.*/
public int getUnitsSpawned(int wave){
if(wave < begin || wave > end || (wave - begin) % spacing != 0){
return 0;
}
float scaling = this.unitScaling * state.difficulty.enemyScaling;
return Math.min(unitAmount-1 + Math.max((int)((wave / spacing) / scaling), 1), max);
}
/**Returns the amount of different unit groups at a specific wave.*/
public int getGroupsSpawned(int wave){
if(wave < begin || wave > end || (wave - begin) % spacing != 0){
return 0;
}
float scaling = this.groupScaling;
return Math.min(groupAmount-1 + Math.max((int)((wave / spacing) / groupScaling), 1), max);
}
/**Creates a unit, and assigns correct values based on this group's data.
* This method does not add() the unit.*/
public BaseUnit createUnit(Team team){
BaseUnit unit = type.create(team);
if(unit instanceof GroundUnit && weapon != null){
((GroundUnit) unit).setWeapon(weapon);
}
if(effect != null){
unit.applyEffect(effect, 1f);
}
if(items != null){
unit.inventory.addItem(items.item, items.amount);
}
if(ammoItem != null){
unit.inventory.addAmmo(unit.getWeapon().getAmmoType(ammoItem));
}else{
unit.inventory.addAmmo(unit.getWeapon().getAmmoType(unit.getWeapon().getAcceptedItems().iterator().next()));
}
return unit;
}
}

View File

@@ -1,26 +1,48 @@
package io.anuke.mindustry.game;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.type.ItemStack;
public class WaveCreator{
public static Array<EnemySpawn> getSpawns(){
//TODO
return null;
public static Array<SpawnGroup> getSpawns(){
return Array.with(
new SpawnGroup(UnitTypes.scout){{
end = 5;
}},
new SpawnGroup(UnitTypes.titan){{
begin = 6;
}},
new SpawnGroup(UnitTypes.scout){{
begin = 6;
items = new ItemStack(Items.thermite, 100);
}},
new SpawnGroup(UnitTypes.vtol){{
begin = 8;
}},
new SpawnGroup(UnitTypes.monsoon){{
begin = 16;
}}
);
}
public static void testWaves(int from, int to){
Array<EnemySpawn> spawns = getSpawns();
Array<SpawnGroup> 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);
for(SpawnGroup spawn : spawns){
int a = spawn.getUnitsSpawned(i);
total += a;
if(a > 0){
System.out.print(a+"x" + spawn.type.name + "-" + t + " ");
System.out.print(a+"x" + spawn.type.name);
}
}
System.out.print(" (" + total + ")");