mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-31 15:09:07 +07:00
Broken attempt at per-enemy pathfinding; balancing
This commit is contained in:
Binary file not shown.
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 279 B |
@ -1,49 +1,47 @@
|
||||
package io.anuke.mindustry.ai;
|
||||
|
||||
import com.badlogic.gdx.ai.pfa.PathFinder;
|
||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
||||
import com.badlogic.gdx.ai.pfa.PathSmoother;
|
||||
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.effect.Fx;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.World;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
public class Pathfind{
|
||||
static MHueristic heuristic = new MHueristic();
|
||||
static PassTileGraph passgraph = new PassTileGraph();
|
||||
static PathFinder<Tile> passpathfinder;
|
||||
static Array<SmoothGraphPath> paths = new Array<>();
|
||||
static Tile[][] pathSequences;
|
||||
static PassTileGraph graph = new PassTileGraph();
|
||||
static PathFinder<Tile> finder = new IndexedAStarPathFinder<Tile>(graph);
|
||||
static PathSmoother<Tile, Vector2> smoother = new PathSmoother<Tile, Vector2>(new Raycaster());
|
||||
static Vector2 vector = new Vector2();
|
||||
|
||||
static public Vector2 find(Enemy enemy){
|
||||
if(enemy.node == -1){
|
||||
findNode(enemy);
|
||||
}
|
||||
findNode(enemy);
|
||||
|
||||
if(enemy.node <= -1) return vector.set(enemy.x, enemy.y);
|
||||
|
||||
//-1 is only possible here if both pathfindings failed, which should NOT happen
|
||||
//check graph code
|
||||
|
||||
Tile[] path = enemy.path;
|
||||
//Tile[] path = enemy.path;
|
||||
Array<Tile> path = enemy.gpath.nodes;
|
||||
|
||||
Tile target = path[enemy.node];
|
||||
Tile target = path.get(enemy.node);
|
||||
|
||||
float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy());
|
||||
|
||||
if(dst < 2){
|
||||
if(enemy.node <= path.length-2)
|
||||
if(enemy.node <= path.size-2)
|
||||
enemy.node ++;
|
||||
|
||||
target = path[enemy.node];
|
||||
target = path.get(enemy.node);
|
||||
}
|
||||
|
||||
//near the core, stop
|
||||
if(enemy.node == path.length - 1){
|
||||
if(enemy.node == path.size - 1){
|
||||
vector.set(target.worldx(), target.worldy());
|
||||
}
|
||||
|
||||
@ -51,13 +49,9 @@ public class Pathfind{
|
||||
|
||||
}
|
||||
|
||||
static public void reset(){
|
||||
paths.clear();
|
||||
pathSequences = null;
|
||||
passpathfinder = new IndexedAStarPathFinder<Tile>(passgraph);
|
||||
}
|
||||
|
||||
static public void updatePath(){
|
||||
|
||||
/*
|
||||
if(paths.size == 0 || paths.size != World.spawnpoints.size){
|
||||
paths.clear();
|
||||
pathSequences = new Tile[World.spawnpoints.size][0];
|
||||
@ -67,13 +61,6 @@ public class Pathfind{
|
||||
}
|
||||
}
|
||||
|
||||
//TODO make this work?
|
||||
/*
|
||||
PathFinderRequest<Tile> request = new PathFinderRequest<Tile>();
|
||||
request.startNode = World.spawnpoints.get(0);
|
||||
request.endNode = World.core;
|
||||
passpathfinder.search(request, 1000); */
|
||||
|
||||
for(int i = 0; i < paths.size; i ++){
|
||||
SmoothGraphPath path = paths.get(i);
|
||||
|
||||
@ -98,18 +85,47 @@ public class Pathfind{
|
||||
Effects.effect(Fx.ind, tile.worldx(), tile.worldy());
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
static void findNode(Enemy enemy){
|
||||
/*
|
||||
enemy.path = pathSequences[enemy.spawn];
|
||||
Tile[] path = enemy.path;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
if(enemy.node == -1 || (Timers.get(enemy, "pathfind", 120) && enemy.request.pathFound)){
|
||||
|
||||
enemy.gpath = new SmoothGraphPath();
|
||||
enemy.finder = new IndexedAStarPathFinder<Tile>(graph);
|
||||
enemy.gpath.clear();
|
||||
|
||||
enemy.request = new PathFinderRequest<Tile>(World.tileWorld(enemy.x, enemy.y),
|
||||
World.core,
|
||||
heuristic, enemy.gpath);
|
||||
enemy.request.statusChanged = true;
|
||||
|
||||
enemy.node = -2;
|
||||
}
|
||||
|
||||
if(enemy.gpath != null && !enemy.request.pathFound){
|
||||
enemy.request.executionFrames ++;
|
||||
if(enemy.finder.search(enemy.request, 1000000 / 5)){
|
||||
smoother.smoothPath(enemy.gpath);
|
||||
enemy.node = 1;
|
||||
//UCore.log("done in " + enemy.request.executionFrames + " frames with path of size " + enemy.gpath.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Tile closest = null;
|
||||
float ldst = 0f;
|
||||
int cindex = -1;
|
||||
|
||||
for(int i = 0; i < path.length; i ++){
|
||||
Tile tile = path[i];
|
||||
for(int i = 0; i < path.size; i ++){
|
||||
Tile tile = path.get(i);
|
||||
float dst = Vector2.dst(tile.worldx(), tile.worldy(), enemy.x, enemy.y);
|
||||
|
||||
if(closest == null || dst < ldst){
|
||||
@ -118,6 +134,6 @@ public class Pathfind{
|
||||
cindex = i;
|
||||
}
|
||||
}
|
||||
enemy.node = cindex;
|
||||
enemy.node = cindex;*/
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ public class SmoothGraphPath extends DefaultGraphPath<Tile> implements Smoothabl
|
||||
@Override
|
||||
public Vector2 getNodePosition(int index){
|
||||
Tile tile = nodes.get(index);
|
||||
return Tmp.v1.set(tile.worldx(), tile.worldy());
|
||||
return Tmp.v3.set(tile.worldx(), tile.worldy());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -24,5 +24,10 @@ public class SmoothGraphPath extends DefaultGraphPath<Tile> implements Smoothabl
|
||||
public void truncatePath(int newLength){
|
||||
nodes.truncate(newLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add (Tile node) {
|
||||
nodes.add(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Draw.reset();
|
||||
}
|
||||
},
|
||||
sniper = new BulletType(3f, 23){
|
||||
sniper = new BulletType(3f, 25){
|
||||
public void draw(Bullet b){
|
||||
Draw.color(Color.LIGHT_GRAY);
|
||||
Draw.thick(1f);
|
||||
@ -223,7 +223,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Draw.reset();
|
||||
}
|
||||
},
|
||||
flame = new BulletType(0.6f, 4){
|
||||
flame = new BulletType(0.6f, 5){
|
||||
public void draw(Bullet b){
|
||||
Draw.color(Color.YELLOW, Color.SCARLET, b.time/lifetime);
|
||||
float size = 6f-b.time/lifetime*5f;
|
||||
@ -250,7 +250,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Draw.reset();
|
||||
}
|
||||
},
|
||||
shot = new BulletType(2.4f, 2){
|
||||
shot = new BulletType(2.4f, 4){
|
||||
{lifetime = 40;}
|
||||
public void draw(Bullet b){
|
||||
Draw.color(lightGold);
|
||||
@ -258,7 +258,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
Draw.reset();
|
||||
}
|
||||
},
|
||||
multishot = new BulletType(2.5f, 2){
|
||||
multishot = new BulletType(2.5f, 3){
|
||||
{lifetime=40;}
|
||||
public void draw(Bullet b){
|
||||
Draw.color(Color.SKY);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.anuke.mindustry.entities.enemies;
|
||||
|
||||
import com.badlogic.gdx.ai.pfa.PathFinder;
|
||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
@ -7,6 +9,7 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.ai.Pathfind;
|
||||
import io.anuke.mindustry.ai.SmoothGraphPath;
|
||||
import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.BulletType;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
@ -34,9 +37,11 @@ public class Enemy extends DestructibleEntity{
|
||||
protected String shootsound = "enemyshoot";
|
||||
protected int damage;
|
||||
|
||||
public Tile[] path;
|
||||
public PathFinderRequest<Tile> request = new PathFinderRequest<>();;
|
||||
public SmoothGraphPath gpath;
|
||||
public int spawn;
|
||||
public int node = -1;
|
||||
public PathFinder<Tile> finder;
|
||||
|
||||
public Vector2 direction = new Vector2();
|
||||
public float xvelocity, yvelocity;
|
||||
@ -122,6 +127,7 @@ public class Enemy extends DestructibleEntity{
|
||||
|
||||
public void findClosestNode(){
|
||||
Pathfind.find(this);
|
||||
/*
|
||||
|
||||
int index = 0;
|
||||
int cindex = -1;
|
||||
@ -147,7 +153,7 @@ public class Enemy extends DestructibleEntity{
|
||||
Timers.run(Mathf.random(15f), ()->{
|
||||
set(x2 * Vars.tilesize, y2 * Vars.tilesize);
|
||||
});
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,6 +68,10 @@ public class World{
|
||||
return tiles[x][y];
|
||||
}
|
||||
|
||||
public static Tile tileWorld(float x, float y){
|
||||
return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize));
|
||||
}
|
||||
|
||||
public static Tile[] getNearby(int x, int y){
|
||||
temptiles[0] = tile(x+1, y);
|
||||
temptiles[1] = tile(x, y+1);
|
||||
@ -146,8 +150,6 @@ public class World{
|
||||
World.seed = seed;
|
||||
Generator.generate(mapPixmaps[map.ordinal()]);
|
||||
|
||||
Pathfind.reset();
|
||||
|
||||
//TODO multiblock core
|
||||
placeBlock(core.x, core.y, ProductionBlocks.core, 0);
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class DefenseBlocks{
|
||||
{
|
||||
fullDescription = "Repairs nearby damaged blocks in range at a slow rate. "
|
||||
+ "Uses small amounts of power.";
|
||||
formalName = "heal turret";
|
||||
formalName = "repair turret";
|
||||
range = 30;
|
||||
reload = 40f;
|
||||
health = 60;
|
||||
@ -82,7 +82,7 @@ public class DefenseBlocks{
|
||||
{
|
||||
fullDescription = "Repairs nearby damaged blocks in range at a decent rate. "
|
||||
+ "Uses power.";
|
||||
formalName = "heal turret II";
|
||||
formalName = "repair turret II";
|
||||
range = 44;
|
||||
reload = 20f;
|
||||
health = 90;
|
||||
|
@ -14,6 +14,7 @@ import io.anuke.mindustry.world.blocks.types.PowerBlock;
|
||||
import io.anuke.ucore.core.Draw;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Hue;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@ -80,9 +81,13 @@ public class Generator extends PowerBlock{
|
||||
public void drawOver(Tile tile){
|
||||
PowerEntity entity = tile.entity();
|
||||
if(entity.power > powerSpeed){
|
||||
for(int i = 0; i < laserDirections; i++){
|
||||
drawLaserTo(tile, (tile.rotation + i) - laserDirections/2);
|
||||
}
|
||||
Draw.alpha(1f);
|
||||
}else{
|
||||
Draw.alpha(0.75f);
|
||||
}
|
||||
|
||||
for(int i = 0; i < laserDirections; i++){
|
||||
drawLaserTo(tile, (tile.rotation + i) - laserDirections/2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,10 +119,9 @@ public class Generator extends PowerBlock{
|
||||
Tile target = laserTarget(tile, rotation);
|
||||
|
||||
if(target != null){
|
||||
Angles.translation(rotation * 90, 6f);
|
||||
Angles.translation(rotation * 90, width * Vars.tilesize/2 + 2f);
|
||||
|
||||
Draw.color(Color.GRAY, Color.WHITE, 0.902f + Mathf.sin(Timers.time(), 1.7f, 0.08f));
|
||||
Draw.alpha(1f);
|
||||
Draw.tint(Hue.mix(Color.GRAY, Color.WHITE, 0.902f + Mathf.sin(Timers.time(), 1.7f, 0.08f)));
|
||||
|
||||
float r = 0f;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class LiquidPowerGenerator extends Generator implements LiquidAcceptor{
|
||||
public void getStats(Array<String> list){
|
||||
super.getStats(list);
|
||||
list.add("[liquidinfo]Liquid Capacity: " + (int)liquidCapacity);
|
||||
list.add("[liquidinfo]Generation: " + Strings.toFixed(generatePower / inputLiquid, 3) + "power units/liquid unit");
|
||||
list.add("[liquidinfo]Generation: " + Strings.toFixed(generatePower / inputLiquid, 2) + " power/liquid");
|
||||
list.add("[liquidinfo]Input: " + generateLiquid);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
package io.anuke.mindustry.world.blocks.types.production;
|
||||
|
||||
public class NuclearReactor extends LiquidItemPowerGenerator{
|
||||
|
||||
//TODO make it explode when broken
|
||||
public NuclearReactor(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user