New seed-based AI bases
This commit is contained in:
@@ -54,7 +54,7 @@ public class PowerBlocks extends BlockList implements ContentList{
|
||||
thoriumReactor = new NuclearReactor("thorium-reactor"){{
|
||||
size = 3;
|
||||
health = 700;
|
||||
powerMultiplier = 0.8f;
|
||||
powerMultiplier = 1.1f;
|
||||
}};
|
||||
|
||||
fusionReactor = new FusionReactor("fusion-reactor"){{
|
||||
|
||||
@@ -307,7 +307,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
||||
}
|
||||
|
||||
if(floor.isLiquid){
|
||||
Draw.tint(Color.WHITE, floor.liquidColor, drownTime * 0.4f);
|
||||
Draw.tint(Color.WHITE, floor.liquidColor, drownTime);
|
||||
}else{
|
||||
Draw.tint(Color.WHITE);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
package io.anuke.mindustry.maps.generation;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntIntMap;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.content.blocks.DistributionBlocks;
|
||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||
import io.anuke.mindustry.content.Liquids;
|
||||
import io.anuke.mindustry.content.blocks.*;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.maps.generation.pathfinding.AStarPathFinder;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Recipe;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Edges;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.defense.Door;
|
||||
import io.anuke.mindustry.world.blocks.defense.MendProjector;
|
||||
import io.anuke.mindustry.world.blocks.defense.Wall;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.ItemTurret;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.PowerTurret;
|
||||
import io.anuke.mindustry.world.blocks.distribution.Conveyor;
|
||||
import io.anuke.mindustry.world.blocks.power.SolarGenerator;
|
||||
import io.anuke.mindustry.world.blocks.defense.turrets.Turret;
|
||||
import io.anuke.mindustry.world.blocks.power.NuclearReactor;
|
||||
import io.anuke.mindustry.world.blocks.power.PowerGenerator;
|
||||
import io.anuke.mindustry.world.blocks.production.Drill;
|
||||
import io.anuke.mindustry.world.blocks.production.Pump;
|
||||
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
|
||||
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
|
||||
import io.anuke.mindustry.world.blocks.units.UnitPad;
|
||||
import io.anuke.mindustry.world.consumers.ConsumePower;
|
||||
import io.anuke.ucore.function.BiFunction;
|
||||
import io.anuke.ucore.function.IntPositionConsumer;
|
||||
import io.anuke.ucore.function.TriFunction;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
public class FortressGenerator{
|
||||
private final static int coreDst = 60;
|
||||
private final static int coreDst = 120;
|
||||
|
||||
private int enemyX, enemyY, coreX, coreY;
|
||||
private Team team;
|
||||
@@ -41,143 +53,186 @@ public class FortressGenerator{
|
||||
gen();
|
||||
}
|
||||
|
||||
enum Pass{
|
||||
walls((x, y) -> {
|
||||
|
||||
});
|
||||
|
||||
final IntPositionConsumer cons;
|
||||
|
||||
Pass(IntPositionConsumer cons){
|
||||
this.cons = cons;
|
||||
}
|
||||
}
|
||||
|
||||
void gen(){
|
||||
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
|
||||
|
||||
float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(1f/2f), 0f, 0.9999f);
|
||||
int coreDst = FortressGenerator.coreDst*gen.sector.size;
|
||||
|
||||
Array<Block> turrets = find(b -> (b instanceof ItemTurret && accepts(((ItemTurret) b).getAmmoTypes(), Items.copper) || b instanceof PowerTurret));
|
||||
Array<Block> turrets = find(b -> b instanceof ItemTurret);
|
||||
Array<Block> powerTurrets = find(b -> b instanceof PowerTurret);
|
||||
Array<Block> drills = find(b -> b instanceof Drill && !b.consumes.has(ConsumePower.class));
|
||||
Array<Block> gens = find(b -> b instanceof SolarGenerator);
|
||||
Array<Block> powerDrills = find(b -> b instanceof Drill && b.consumes.has(ConsumePower.class));
|
||||
Array<Block> walls = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 1);
|
||||
Array<Block> wallsLarge = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 2);
|
||||
|
||||
Block wall = walls.get((int)(difficultyScl * walls.size));
|
||||
Block wallLarge = wallsLarge.get((int)(difficultyScl * walls.size));
|
||||
Drill drill = (Drill) drills.get((int)(difficultyScl * drills.size));
|
||||
Item[] items = {Items.copper, Items.lead};
|
||||
Drill powerDrill = (Drill) powerDrills.get((int)(difficultyScl * powerDrills.size));
|
||||
|
||||
Turret powerTurret = (Turret) powerTurrets.get((int)(difficultyScl * powerTurrets.size));
|
||||
Turret bigTurret = (Turret) turrets.get(Mathf.clamp((int)((difficultyScl+0.3f+gen.random.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||
Turret turret1 = (Turret) turrets.get(Mathf.clamp((int)((difficultyScl+gen.random.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||
Turret turret2 = (Turret) turrets.get(Mathf.clamp((int)((difficultyScl+gen.random.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||
|
||||
AStarPathFinder finder = new AStarPathFinder(gen.tiles);
|
||||
|
||||
//place down drills
|
||||
for(int x = 0; x < gen.width; x++){
|
||||
for(int y = 0; y < gen.height; y++){
|
||||
if(Vector2.dst(x, y, enemyX, enemyY) > coreDst){
|
||||
continue;
|
||||
}
|
||||
|
||||
Item item = gen.drillItem(x, y, drill);
|
||||
Block generator = gens.get(gen.random.random(0, gens.size-1));
|
||||
|
||||
boolean contains = false;
|
||||
if(item != null){
|
||||
for(Item other : items){
|
||||
if(other == item){
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(item != null && contains && gen.canPlace(x, y, drill) && !gen.random.chance(0.5)){
|
||||
Array<Tile> out = new Array<>();
|
||||
finder.search(gen.tile(x, y), gen.tile(enemyX, enemyY - 2),
|
||||
tile -> (tile.block() instanceof Conveyor || (Math.abs(tile.x - enemyX) <= 2 && Math.abs(tile.y - enemyY) <= 2))
|
||||
&& (Math.abs(tile.x - enemyX) != Math.abs(tile.y - enemyY)),
|
||||
out);
|
||||
|
||||
byte last = 0;
|
||||
for (int i = 0; i < out.size; i++) {
|
||||
Tile current = out.get(i);
|
||||
|
||||
if(i != out.size - 1){
|
||||
Tile next = out.get(i + 1);
|
||||
byte rotation = current.relativeTo(next.x, next.y);
|
||||
current.setBlock(DistributionBlocks.conveyor, team);
|
||||
current.setRotation(rotation);
|
||||
last = rotation;
|
||||
}else{
|
||||
current.setBlock(DistributionBlocks.conveyor, team);
|
||||
current.setRotation(last);
|
||||
}
|
||||
}
|
||||
|
||||
gen.setBlock(x, y, drill, team);
|
||||
}else if(gen.canPlace(x, y, generator) && gen.random.chance(0.01)){
|
||||
gen.setBlock(x, y, generator, team);
|
||||
}
|
||||
}
|
||||
IntIntMap ammoPerType = new IntIntMap();
|
||||
for(Block turret : turrets){
|
||||
if(!(turret instanceof ItemTurret)) continue;
|
||||
ItemTurret t = (ItemTurret)turret;
|
||||
int size = t.getAmmoTypes().length;
|
||||
ammoPerType.put(t.id, Mathf.clamp((int)(size* difficultyScl) + gen.random.range(1), 0, size - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
TriFunction<Tile, Block, Predicate<Tile>, Boolean> checker = (current, block, pred) -> {
|
||||
for(GridPoint2 point : Edges.getEdges(block.size)){
|
||||
Tile tile = gen.tile(current.x + point.x, current.y + point.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
if(tile.getTeamID() == team.ordinal() && pred.evaluate(tile)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//Turret turret = (Turret) turrets.first();
|
||||
BiFunction<Block, Predicate<Tile>, IntPositionConsumer> seeder = (block, pred) -> (x, y) -> {
|
||||
if(gen.canPlace(x, y, block) && ((block instanceof Wall && block.size == 1) || gen.random.chance(difficultyScl/2f+0.5f)) && checker.get(gen.tile(x, y), block, pred)){
|
||||
gen.setBlock(x, y, block, team);
|
||||
}
|
||||
};
|
||||
|
||||
//place down turrets
|
||||
for(int x = 0; x < gen.width; x++){
|
||||
for(int y = 0; y < gen.height; y++){
|
||||
for(Block block : turrets){
|
||||
Turret turret = (Turret)block;
|
||||
if(Vector2.dst(x, y, enemyX, enemyY) > coreDst + 4 || !gen.canPlace(x, y, turret) || !gen.random.chance(0.5)){
|
||||
Array<IntPositionConsumer> passes = Array.with(
|
||||
//initial seeding solar panels
|
||||
(x, y) -> {
|
||||
Block block = PowerBlocks.largeSolarPanel;
|
||||
|
||||
if(gen.random.chance(0.001) && gen.canPlace(x, y, block)){
|
||||
gen.setBlock(x, y, block, team);
|
||||
}
|
||||
},
|
||||
|
||||
//extra seeding
|
||||
seeder.get(PowerBlocks.solarPanel, tile -> tile.block() == PowerBlocks.largeSolarPanel && gen.random.chance(0.3)),
|
||||
|
||||
//drills (not powered)
|
||||
(x, y) -> {
|
||||
if(!gen.random.chance(0.1)) return;
|
||||
|
||||
Item item = gen.drillItem(x, y, drill);
|
||||
if(item != null && item != Items.stone && item != Items.sand && gen.canPlace(x, y, drill)){
|
||||
gen.setBlock(x, y, drill, team);
|
||||
}
|
||||
},
|
||||
|
||||
//drills (not powered)
|
||||
(x, y) -> {
|
||||
if(!gen.random.chance(0.1)) return;
|
||||
|
||||
if(gen.tile(x, y).floor().isLiquid && gen.tile(x, y).floor().liquidDrop == Liquids.water){
|
||||
gen.setBlock(x, y, LiquidBlocks.mechanicalPump, team);
|
||||
}
|
||||
},
|
||||
|
||||
//coal gens
|
||||
seeder.get(PowerBlocks.combustionGenerator, tile -> tile.block() instanceof Drill && gen.drillItem(tile.x, tile.y, (Drill)tile.block()) == Items.coal && gen.random.chance(0.2)),
|
||||
|
||||
//drills (powered)
|
||||
(x, y) -> {
|
||||
if(gen.random.chance(0.4) && gen.canPlace(x, y, powerDrill) && gen.drillItem(x, y, powerDrill) == Items.thorium && checker.get(gen.tile(x, y), powerDrill, other -> other.block() instanceof PowerGenerator)){
|
||||
gen.setBlock(x, y, powerDrill, team);
|
||||
}
|
||||
},
|
||||
|
||||
//nuclear reactors
|
||||
seeder.get(PowerBlocks.thoriumReactor, tile -> tile.block() instanceof Drill && gen.random.chance(0.2) && gen.drillItem(tile.x, tile.y, (Drill)tile.block()) == Items.thorium && gen.random.chance(0.3)),
|
||||
|
||||
//water extractors
|
||||
seeder.get(ProductionBlocks.waterextractor, tile -> tile.block() instanceof NuclearReactor && gen.random.chance(0.5)),
|
||||
|
||||
//mend cores
|
||||
seeder.get(DefenseBlocks.mendProjector, tile -> tile.block() instanceof PowerGenerator && gen.random.chance(0.03)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.daggerPad, tile -> tile.block() instanceof MendProjector && gen.random.chance(0.3)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.interceptorPad, tile -> tile.block() instanceof MendProjector && gen.random.chance(0.3)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.titanPad, tile -> tile.block() instanceof MendProjector && gen.random.chance(0.23)),
|
||||
|
||||
//unit pads (assorted)
|
||||
seeder.get(UnitBlocks.monsoonPad, tile -> tile.block() instanceof MendProjector && gen.random.chance(0.23)),
|
||||
|
||||
//power turrets
|
||||
seeder.get(powerTurret, tile -> tile.block() instanceof PowerGenerator && gen.random.chance(0.04)),
|
||||
|
||||
//repair point
|
||||
seeder.get(UnitBlocks.repairPoint, tile -> tile.block() instanceof PowerGenerator && gen.random.chance(0.1)),
|
||||
|
||||
//turrets1
|
||||
seeder.get(turret1, tile -> tile.block() instanceof Pump && gen.random.chance(0.22 - turret1.size*0.02)),
|
||||
|
||||
//turrets2
|
||||
seeder.get(turret2, tile -> tile.block() instanceof Drill && gen.random.chance(0.12 - turret2.size*0.02)),
|
||||
|
||||
//vaults
|
||||
seeder.get(StorageBlocks.vault, tile -> tile.block() instanceof CoreBlock && gen.random.chance(0.4)),
|
||||
|
||||
//big turrets
|
||||
seeder.get(bigTurret, tile -> tile.block() instanceof StorageBlock && gen.random.chance(0.65)),
|
||||
|
||||
//walls (large)
|
||||
seeder.get(wallLarge, tile -> !(tile.block() instanceof Wall) && !(tile.block() instanceof UnitPad)),
|
||||
|
||||
//walls
|
||||
seeder.get(wall, tile -> !(tile.block() instanceof Wall) && !(tile.block() instanceof UnitPad)),
|
||||
|
||||
//fill up turrets w/ ammo
|
||||
(x, y) -> {
|
||||
Tile tile = gen.tile(x, y);
|
||||
Block block = tile.block();
|
||||
|
||||
if(block instanceof PowerTurret){
|
||||
tile.entity.power.amount = block.powerCapacity;
|
||||
}else if(block instanceof ItemTurret){
|
||||
ItemTurret turret = (ItemTurret)block;
|
||||
AmmoType[] type = turret.getAmmoTypes();
|
||||
int index = ammoPerType.get(block.id, 0);
|
||||
block.handleStack(type[index].item, block.acceptStack(type[index].item, 1000, tile, null), tile, null);
|
||||
}else if(block instanceof NuclearReactor){
|
||||
tile.entity.items.add(Items.thorium, 30);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for(IntPositionConsumer i : passes){
|
||||
for(int x = 0; x < gen.width; x++){
|
||||
for(int y = 0; y < gen.height; y++){
|
||||
if(Vector2.dst(x, y, enemyX, enemyY) > coreDst){
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
|
||||
for(GridPoint2 point : Edges.getEdges(turret.size)){
|
||||
Tile tile = gen.tile(x + point.x, y + point.y);
|
||||
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
|
||||
if(turret instanceof PowerTurret && tile.target().block() instanceof PowerGenerator){
|
||||
found = true;
|
||||
break;
|
||||
}else if(turret instanceof ItemTurret && tile.block() instanceof Drill && accepts(((ItemTurret) turret).getAmmoTypes(), gen.drillItem(tile.x, tile.y, (Drill) tile.block()))){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
gen.setBlock(x, y, turret, team);
|
||||
break;
|
||||
}
|
||||
i.accept(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//place down drills
|
||||
for(int x = 0; x < gen.width; x++){
|
||||
for(int y = 0; y < gen.height; y++){
|
||||
if(Vector2.dst(x, y, enemyX, enemyY) > coreDst || !gen.canPlace(x, y, wall)){
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for(GridPoint2 point : Edges.getEdges(wall.size)){
|
||||
Tile tile = gen.tile(x + point.x, y + point.y);
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
if(tile.getTeamID() == team.ordinal() && !(tile.block() instanceof Wall)){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
gen.setBlock(x, y, wall, team);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
boolean accepts(AmmoType[] types, Item item){
|
||||
for(AmmoType type : types){
|
||||
if(type.item == item){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Array<Block> find(Predicate<Block> pred){
|
||||
|
||||
@@ -19,8 +19,7 @@ import io.anuke.ucore.function.Consumer;
|
||||
import io.anuke.ucore.util.Bits;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
|
||||
public class Tile implements PosTrait, TargetTrait{
|
||||
@@ -261,6 +260,10 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnemyCheat(){
|
||||
return getTeam() == waveTeam && state.mode.autoSpawn;
|
||||
}
|
||||
|
||||
public boolean isLinked(){
|
||||
return link != 0;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ public abstract class LiquidTurret extends Turret{
|
||||
@Override
|
||||
public AmmoType useAmmo(Tile tile){
|
||||
TurretEntity entity = tile.entity();
|
||||
if(tile.isEnemyCheat()) return liquidAmmoMap.get(entity.liquids.current());
|
||||
AmmoType type = liquidAmmoMap.get(entity.liquids.current());
|
||||
entity.liquids.remove(type.liquid, type.quantityMultiplier);
|
||||
return type;
|
||||
|
||||
@@ -28,6 +28,7 @@ public abstract class PowerTurret extends CooledTurret{
|
||||
|
||||
@Override
|
||||
public AmmoType useAmmo(Tile tile){
|
||||
if(tile.isEnemyCheat()) return shootType;
|
||||
tile.entity.power.amount -= powerUsed;
|
||||
return shootType;
|
||||
}
|
||||
|
||||
@@ -226,10 +226,10 @@ public abstract class Turret extends Block{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume ammo and return a type.
|
||||
*/
|
||||
/**Consume ammo and return a type.*/
|
||||
public AmmoType useAmmo(Tile tile){
|
||||
if(tile.isEnemyCheat()) return peekAmmo(tile);
|
||||
|
||||
TurretEntity entity = tile.entity();
|
||||
AmmoEntry entry = entity.ammo.peek();
|
||||
entry.amount -= ammoPerShot;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package io.anuke.mindustry.world.blocks.effect;
|
||||
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
|
||||
public abstract class EffectCore extends Block{
|
||||
protected int range = 7;
|
||||
|
||||
public EffectCore(String name){
|
||||
super(name);
|
||||
update = true;
|
||||
solid = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSelect(Tile tile){
|
||||
Draw.color(Palette.accent);
|
||||
Lines.dashCircle(tile.drawx(), tile.drawy(), range * tilesize);
|
||||
Draw.reset();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.anuke.mindustry.world.blocks.effect;
|
||||
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class MendingCore extends EffectCore{
|
||||
/**
|
||||
* Mending speed as a percentage of block health, per frame.
|
||||
*/
|
||||
protected float mendSpeed = 0.8f;
|
||||
|
||||
public MendingCore(String name){
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tile tile){
|
||||
|
||||
for(int dx = Math.max(-range + tile.x, 0); dx <= Math.min(range + tile.y, world.width() - 1); dx++){
|
||||
for(int dy = Math.max(-range + tile.y, 0); dy <= Math.min(range + tile.y, world.height() - 1); dy++){
|
||||
Tile other = world.tile(dx, dy);
|
||||
|
||||
if(other.entity != null){
|
||||
other.entity.health = Mathf.clamp(other.entity.health + 1f / other.block().health * mendSpeed * Timers.delta(), 0, other.block().health);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,6 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.waveTeam;
|
||||
|
||||
public class UnitPad extends Block{
|
||||
protected float gracePeriodMultiplier = 23f;
|
||||
protected float speedupTime = 60f * 60f * 20;
|
||||
@@ -152,13 +149,11 @@ public class UnitPad extends Block{
|
||||
|
||||
entity.time += Timers.delta() * entity.speedScl;
|
||||
|
||||
boolean isEnemy = tile.getTeam() == waveTeam && state.mode.autoSpawn;
|
||||
|
||||
if(isEnemy){
|
||||
if(tile.isEnemyCheat()){
|
||||
entity.warmup += Timers.delta();
|
||||
}
|
||||
|
||||
if(!isEnemy){
|
||||
if(!tile.isEnemyCheat()){
|
||||
//player-made spawners have default behavior
|
||||
|
||||
if(hasRequirements(entity.items, entity.buildTime / produceTime) && entity.cons.valid()){
|
||||
|
||||
Reference in New Issue
Block a user