Major refactoring; implemented multi-frame pathfinding

This commit is contained in:
Anuken
2017-11-26 18:59:03 -05:00
parent 25952985dd
commit 07ac552495
60 changed files with 767 additions and 498 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 237 B

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 218 B

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

@@ -9,6 +9,7 @@ import io.anuke.mindustry.core.*;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.io.Formatter; import io.anuke.mindustry.io.Formatter;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.World;
import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.blocks.*;
import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
@@ -41,6 +42,7 @@ public class Mindustry extends ModuleCore {
@Override @Override
public void init(){ public void init(){
module(Vars.world = new World());
module(Vars.control = new Control()); module(Vars.control = new Control());
module(Vars.renderer = new Renderer()); module(Vars.renderer = new Renderer());
module(Vars.ui = new UI()); module(Vars.ui = new UI());
+2
View File
@@ -7,6 +7,7 @@ import io.anuke.mindustry.core.Control;
import io.anuke.mindustry.core.Renderer; import io.anuke.mindustry.core.Renderer;
import io.anuke.mindustry.core.UI; import io.anuke.mindustry.core.UI;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
public class Vars{ public class Vars{
@@ -59,6 +60,7 @@ public class Vars{
public static Control control; public static Control control;
public static Renderer renderer; public static Renderer renderer;
public static UI ui; public static UI ui;
public static World world;
public static Player player; public static Player player;
@@ -4,7 +4,6 @@ import com.badlogic.gdx.ai.pfa.Heuristic;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
public class MHueristic implements Heuristic<Tile>{ public class MHueristic implements Heuristic<Tile>{
//so this means that the cost of going through solids is 10x going through non solids //so this means that the cost of going through solids is 10x going through non solids
@@ -23,7 +22,7 @@ public class MHueristic implements Heuristic<Tile>{
if(other.breakable() && other.block().solid) cost += Vars.tilesize*multiplier; if(other.breakable() && other.block().solid) cost += Vars.tilesize*multiplier;
for(int dx = -1; dx <= 1; dx ++){ for(int dx = -1; dx <= 1; dx ++){
for(int dy = -1; dy <= 1; dy ++){ for(int dy = -1; dy <= 1; dy ++){
Tile tile = World.tile(node.x + dx, node.y + dy); Tile tile = Vars.world.tile(node.x + dx, node.y + dy);
if(tile != null && tile.solid()){ if(tile != null && tile.solid()){
cost += Vars.tilesize*5; cost += Vars.tilesize*5;
} }
@@ -4,8 +4,8 @@ import com.badlogic.gdx.ai.pfa.Connection;
import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph; import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
/**Tilegraph that ignores player-made tiles.*/ /**Tilegraph that ignores player-made tiles.*/
public class PassTileGraph implements IndexedGraph<Tile>{ public class PassTileGraph implements IndexedGraph<Tile>{
private Array<Connection<Tile>> tempConnections = new Array<Connection<Tile>>(); private Array<Connection<Tile>> tempConnections = new Array<Connection<Tile>>();
@@ -27,11 +27,11 @@ public class PassTileGraph implements IndexedGraph<Tile>{
@Override @Override
public int getIndex(Tile node){ public int getIndex(Tile node){
return node.x+node.y*World.worldsize; return node.id();
} }
@Override @Override
public int getNodeCount(){ public int getNodeCount(){
return World.worldsize*World.worldsize; return Vars.world.width() * Vars.world.height();
} }
} }
+51 -24
View File
@@ -1,40 +1,41 @@
package io.anuke.mindustry.ai; 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.PathSmoother;
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder; import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.world.SpawnPoint;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
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 PathSmoother<Tile, Vector2> smoother = new PathSmoother<Tile, Vector2>(new Raycaster());
static Vector2 vector = new Vector2();
static public Vector2 find(Enemy enemy){ public class Pathfind{
private static final long ms = 1000000;
MHueristic heuristic = new MHueristic();
PassTileGraph graph = new PassTileGraph();
PathSmoother<Tile, Vector2> smoother = new PathSmoother<Tile, Vector2>(new Raycaster());
Vector2 vector = new Vector2();
public Vector2 find(Enemy enemy){
if(enemy.node == -1){ if(enemy.node == -1){
findNode(enemy); findNode(enemy);
} }
if(enemy.path == null){
return vector.set(enemy.x, enemy.y);
}
//-1 is only possible here if both pathfindings failed, which should NOT happen //-1 is only possible here if both pathfindings failed, which should NOT happen
//check graph code //check graph code
Tile[] path = enemy.path; Tile[] path = enemy.path;
//REPRODUCE BUG: load in test map, then load save 1 //REPRODUCE BUG: load in test map, then load save 1?
Tile prev = path[enemy.node - 1]; Tile prev = path[enemy.node - 1];
Tile target = path[enemy.node]; Tile target = path[enemy.node];
@@ -77,19 +78,41 @@ public class Pathfind{
} }
static public void reset(){ public void update(){
paths.clear();
pathSequences = null; for(SpawnPoint point : Vars.control.getSpawnPoints()){
passpathfinder = new IndexedAStarPathFinder<Tile>(passgraph); if(!point.request.pathFound){
if(point.finder.search(point.request, ms*2)){
smoother.smoothPath(point.path);
point.pathTiles = point.path.nodes.toArray(Tile.class);
}
}
}
} }
static public void updatePath(){ public void updatePath(){
for(SpawnPoint point : Vars.control.getSpawnPoints()){
if(point.finder == null){
point.finder = new IndexedAStarPathFinder<Tile>(graph);
}
point.path.clear();
point.pathTiles = null;
point.request = new PathFinderRequest<Tile>(point.start, Vars.control.getCore(), heuristic, point.path);
point.request.statusChanged = true; //IMPORTANT!
}
/*
if(paths.size == 0 || paths.size != World.spawnpoints.size){ if(paths.size == 0 || paths.size != World.spawnpoints.size){
paths.clear(); paths.clear();
finders.clear();
pathSequences = new Tile[World.spawnpoints.size][0]; pathSequences = new Tile[World.spawnpoints.size][0];
for(int i = 0; i < World.spawnpoints.size; i ++){ for(int i = 0; i < World.spawnpoints.size; i ++){
SmoothGraphPath path = new SmoothGraphPath(); SmoothGraphPath path = new SmoothGraphPath();
paths.add(path); paths.add(path);
finders.add(new IndexedAStarPathFinder(graph));
} }
} }
@@ -97,7 +120,7 @@ public class Pathfind{
SmoothGraphPath path = paths.get(i); SmoothGraphPath path = paths.get(i);
path.clear(); path.clear();
passpathfinder.searchNodePath( finders.get(i).searchNodePath(
World.spawnpoints.get(i), World.spawnpoints.get(i),
World.core, heuristic, path); World.core, heuristic, path);
@@ -117,11 +140,15 @@ public class Pathfind{
Effects.effect(Fx.ind, tile.worldx(), tile.worldy()); Effects.effect(Fx.ind, tile.worldx(), tile.worldy());
} }
} }*/
} }
static void findNode(Enemy enemy){ void findNode(Enemy enemy){
enemy.path = pathSequences[enemy.spawn]; if(Vars.control.getSpawnPoints().get(enemy.spawn).pathTiles == null){
return;
}
enemy.path = Vars.control.getSpawnPoints().get(enemy.spawn).pathTiles;
Tile[] path = enemy.path; Tile[] path = enemy.path;
Tile closest = null; Tile closest = null;
float ldst = 0f; float ldst = 0f;
@@ -7,7 +7,6 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -72,7 +71,7 @@ public class Raycaster implements RaycastCollisionDetector<Vector2>{
} }
private boolean solid(float x, float y){ private boolean solid(float x, float y){
Tile tile = World.tile(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize)); Tile tile = Vars.world.tile(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize));
if(tile == null || tile.solid()) return true; if(tile == null || tile.solid()) return true;
+35 -23
View File
@@ -13,7 +13,6 @@ import com.badlogic.gdx.utils.reflect.Constructor;
import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.Mindustry;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.effect.Fx; import io.anuke.mindustry.entities.effect.Fx;
@@ -53,6 +52,9 @@ public class Control extends Module{
float extrawavetime; float extrawavetime;
int enemies = 0; int enemies = 0;
Tile core;
Array<SpawnPoint> spawnpoints = new Array<>();
float respawntime; float respawntime;
public Control(){ public Control(){
@@ -87,8 +89,6 @@ public class Control extends Module{
Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3"); Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3");
World.loadMaps();
KeyBinds.defaults( KeyBinds.defaults(
"up", Keys.W, "up", Keys.W,
"left", Keys.A, "left", Keys.A,
@@ -178,7 +178,7 @@ public class Control extends Module{
player.heal(); player.heal();
clearItems(); clearItems();
World.spawnpoints.clear(); spawnpoints.clear();
respawntime = -1; respawntime = -1;
hiscore = false; hiscore = false;
@@ -189,8 +189,8 @@ public class Control extends Module{
public void play(){ public void play(){
Vars.renderer.clearTiles(); Vars.renderer.clearTiles();
player.x = World.core.worldx(); player.x = core.worldx();
player.y = World.core.worldy() - Vars.tilesize*2 - ((int)(Gdx.graphics.getWidth() / (float)Core.cameraScale * 2) % 2 == 0 ? 0.5f : 0); player.y = 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); Core.camera.position.set(player.x, player.y, 0);
@@ -200,17 +200,35 @@ public class Control extends Module{
GameState.set(State.playing); GameState.set(State.playing);
} }
public Tile getCore(){
return core;
}
public Array<SpawnPoint> getSpawnPoints(){
return spawnpoints;
}
public void setCore(Tile tile){
this.core = tile;
}
public void addSpawnPoint(Tile tile){
SpawnPoint point = new SpawnPoint();
point.start = tile;
spawnpoints.add(point);
}
public void playMap(Map map){ public void playMap(Map map){
Vars.ui.showLoading(); Vars.ui.showLoading();
Timers.run(16, ()->{ Timers.run(16, ()->{
Vars.control.reset(); reset();
World.loadMap(map); world.loadMap(map);
Vars.control.play(); play();
}); });
Timers.run(18, ()->{ Timers.run(18, ()->{
Vars.ui.hideLoading(); ui.hideLoading();
}); });
} }
@@ -236,12 +254,12 @@ public class Control extends Module{
public void runWave(){ public void runWave(){
Sounds.play("spawn"); Sounds.play("spawn");
Pathfind.updatePath(); world.pathfinder().updatePath();
for(EnemySpawn spawn : spawns){ for(EnemySpawn spawn : spawns){
for(int lane = 0; lane < World.spawnpoints.size; lane ++){ for(int lane = 0; lane < spawnpoints.size; lane ++){
int fl = lane; int fl = lane;
Tile tile = World.spawnpoints.get(lane); Tile tile = spawnpoints.get(lane).start;
int spawnamount = spawn.evaluate(wave, lane); int spawnamount = spawn.evaluate(wave, lane);
for(int i = 0; i < spawnamount; i ++){ for(int i = 0; i < spawnamount; i ++){
@@ -268,10 +286,10 @@ public class Control extends Module{
wave ++; wave ++;
int last = Settings.getInt("hiscore" + World.getMap().name()); int last = Settings.getInt("hiscore" + world.getMap().name());
if(wave > last){ if(wave > last){
Settings.putInt("hiscore" + World.getMap().name(), wave); Settings.putInt("hiscore" + world.getMap().name(), wave);
Settings.save(); Settings.save();
hiscore = true; hiscore = true;
} }
@@ -301,7 +319,6 @@ public class Control extends Module{
public void coreDestroyed(){ public void coreDestroyed(){
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y); Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
Sounds.play("corexplode"); Sounds.play("corexplode");
Tile core = World.core;
for(int i = 0; i < 16; i ++){ for(int i = 0; i < 16; i ++){
Timers.run(i*2, ()->{ Timers.run(i*2, ()->{
Effects.effect(Fx.explosion, core.worldx()+Mathf.range(40), core.worldy()+Mathf.range(40)); Effects.effect(Fx.explosion, core.worldx()+Mathf.range(40), core.worldy()+Mathf.range(40));
@@ -401,7 +418,7 @@ public class Control extends Module{
Entities.initPhysics(); Entities.initPhysics();
Entities.setCollider(tilesize, (x, y)->{ Entities.setCollider(tilesize, (x, y)->{
return World.solid(x, y); return world.solid(x, y);
}); });
} }
@@ -454,7 +471,7 @@ public class Control extends Module{
respawntime -= delta(); respawntime -= delta();
if(respawntime <= 0){ if(respawntime <= 0){
player.set(World.core.worldx(), World.core.worldy()-Vars.tilesize*2); player.set(core.worldx(), core.worldy()-Vars.tilesize*2);
player.heal(); player.heal();
player.add(); player.add();
Effects.sound("respawn"); Effects.sound("respawn");
@@ -498,9 +515,4 @@ public class Control extends Module{
} }
} }
@Override
public void dispose(){
World.disposeMaps();
}
} }
+21 -20
View File
@@ -20,8 +20,8 @@ import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.Input; import io.anuke.mindustry.input.Input;
import io.anuke.mindustry.input.PlaceMode; import io.anuke.mindustry.input.PlaceMode;
import io.anuke.mindustry.world.SpawnPoint;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.ProductionBlocks; import io.anuke.mindustry.world.blocks.ProductionBlocks;
import io.anuke.ucore.UCore; import io.anuke.ucore.UCore;
@@ -80,7 +80,7 @@ public class Renderer extends RendererModule{
}else{ }else{
boolean smoothcam = Settings.getBool("smoothcam"); boolean smoothcam = Settings.getBool("smoothcam");
if(World.core.block() == ProductionBlocks.core){ if(control.core.block() == ProductionBlocks.core){
if(!smoothcam){ if(!smoothcam){
setCamera(player.x, player.y); setCamera(player.x, player.y);
@@ -88,7 +88,7 @@ public class Renderer extends RendererModule{
smoothCamera(player.x, player.y, android ? 0.3f : 0.14f); smoothCamera(player.x, player.y, android ? 0.3f : 0.14f);
} }
}else{ }else{
smoothCamera(World.core.worldx(), World.core.worldy(), 0.4f); smoothCamera(control.core.worldx(), control.core.worldy(), 0.4f);
} }
if(Settings.getBool("pixelate")) if(Settings.getBool("pixelate"))
@@ -98,7 +98,8 @@ public class Renderer extends RendererModule{
updateShake(0.75f); updateShake(0.75f);
float prevx = camera.position.x, prevy = camera.position.y; float prevx = camera.position.x, prevy = camera.position.y;
clampCamera(-tilesize / 2f, -tilesize / 2f + 1, World.pixsize - tilesize / 2f, World.pixsize - tilesize / 2f); clampCamera(-tilesize / 2f, -tilesize / 2f + 1, world.width() * tilesize - tilesize / 2f,
world.height() * tilesize - tilesize / 2f);
float deltax = camera.position.x - prex, deltay = camera.position.y - prey; float deltax = camera.position.x - prex, deltay = camera.position.y - prey;
@@ -212,7 +213,7 @@ public class Renderer extends RendererModule{
} }
void renderTiles(){ void renderTiles(){
int chunksx = World.width() / chunksize, chunksy = World.height() / chunksize; int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize;
//render the entire map //render the entire map
if(floorCache == null || floorCache.length != chunksx || floorCache[0].length != chunksy){ if(floorCache == null || floorCache.length != chunksx || floorCache[0].length != chunksy){
@@ -271,11 +272,11 @@ public class Renderer extends RendererModule{
int worldx = Mathf.scl(camera.position.x, tilesize) + x; int worldx = Mathf.scl(camera.position.x, tilesize) + x;
int worldy = Mathf.scl(camera.position.y, tilesize) + y; int worldy = Mathf.scl(camera.position.y, tilesize) + y;
if(World.tile(worldx, worldy) != null){ if(world.tile(worldx, worldy) != null){
Tile tile = World.tile(worldx, worldy); Tile tile = world.tile(worldx, worldy);
if(l == 0){ if(l == 0){
if(tile.block() != Blocks.air && World.isAccessible(worldx, worldy)){ if(tile.block() != Blocks.air && world.isAccessible(worldx, worldy)){
Draw.rect(tile.block().shadow, worldx * tilesize, worldy * tilesize); tile.block().drawShadow(tile);
} }
}else if(l == 1){ }else if(l == 1){
tile.block().draw(tile); tile.block().draw(tile);
@@ -315,7 +316,7 @@ public class Renderer extends RendererModule{
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){
Tile tile = World.tile(tilex, tiley); Tile tile = world.tile(tilex, tiley);
tile.floor().drawCache(tile); tile.floor().drawCache(tile);
} }
@@ -332,8 +333,8 @@ public class Renderer extends RendererModule{
//draw tutorial placement point //draw tutorial placement point
if(Vars.control.tutorial.showBlock()){ if(Vars.control.tutorial.showBlock()){
int x = World.core.x + Vars.control.tutorial.getPlacePoint().x; int x = control.core.x + Vars.control.tutorial.getPlacePoint().x;
int y = World.core.y + Vars.control.tutorial.getPlacePoint().y; int y = control.core.y + Vars.control.tutorial.getPlacePoint().y;
int rot = Vars.control.tutorial.getPlaceRotation(); int rot = Vars.control.tutorial.getPlaceRotation();
Draw.thick(1f); Draw.thick(1f);
@@ -368,7 +369,7 @@ public class Renderer extends RendererModule{
x = tilex * tilesize; x = tilex * tilesize;
y = tiley * tilesize; y = tiley * tilesize;
boolean valid = World.validPlace(tilex, tiley, player.recipe.result) && (android || Input.cursorNear()); boolean valid = world.validPlace(tilex, tiley, player.recipe.result) && (android || Input.cursorNear());
Vector2 offset = player.recipe.result.getPlaceOffset(); Vector2 offset = player.recipe.result.getPlaceOffset();
@@ -388,8 +389,8 @@ public class Renderer extends RendererModule{
Draw.thickness(1f); Draw.thickness(1f);
Draw.color("scarlet"); Draw.color("scarlet");
for(Tile spawn : World.spawnpoints){ for(SpawnPoint spawn : control.getSpawnPoints()){
Draw.dashcircle(spawn.worldx(), spawn.worldy(), enemyspawnspace); Draw.dashcircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
} }
if(valid) if(valid)
@@ -401,8 +402,8 @@ public class Renderer extends RendererModule{
} }
//block breaking //block breaking
if(Inputs.buttonDown(Buttons.RIGHT) && World.validBreak(Input.tilex(), Input.tiley())){ if(Inputs.buttonDown(Buttons.RIGHT) && world.validBreak(Input.tilex(), Input.tiley())){
Tile tile = World.tile(Input.tilex(), Input.tiley()); Tile tile = world.tile(Input.tilex(), Input.tiley());
if(tile.isLinked()) if(tile.isLinked())
tile = tile.getLinked(); tile = tile.getLinked();
Vector2 offset = tile.block().getPlaceOffset(); Vector2 offset = tile.block().getPlaceOffset();
@@ -413,8 +414,8 @@ public class Renderer extends RendererModule{
}else if(android && player.breaktime > 0){ //android block breaking }else if(android && player.breaktime > 0){ //android block breaking
Vector2 vec = Graphics.world(Gdx.input.getX(0), Gdx.input.getY(0)); Vector2 vec = Graphics.world(Gdx.input.getX(0), Gdx.input.getY(0));
if(World.validBreak(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize))){ if(world.validBreak(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize))){
Tile tile = World.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize)); Tile tile = world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
float fract = player.breaktime / tile.getBreakTime(); float fract = player.breaktime / tile.getBreakTime();
Draw.color(Color.YELLOW, Color.SCARLET, fract); Draw.color(Color.YELLOW, Color.SCARLET, fract);
@@ -425,7 +426,7 @@ public class Renderer extends RendererModule{
//draw selected block health //draw selected block health
if(player.recipe == null && !ui.hasMouse()){ if(player.recipe == null && !ui.hasMouse()){
Tile tile = World.tile(Input.tilex(), Input.tiley()); Tile tile = world.tile(Input.tilex(), Input.tiley());
if(tile != null && tile.block() != Blocks.air){ if(tile != null && tile.block() != Blocks.air){
Tile target = tile; Tile target = tile;
+27 -23
View File
@@ -1,12 +1,16 @@
package io.anuke.mindustry.core; package io.anuke.mindustry.core;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.*; import io.anuke.mindustry.world.blocks.*;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.builders.button; import io.anuke.ucore.scene.builders.button;
@@ -29,7 +33,7 @@ public class Tutorial{
} }
public boolean active(){ public boolean active(){
return World.getMap() == Map.tutorial && !GameState.is(State.menu); return world.getMap() == Map.tutorial && !GameState.is(State.menu);
} }
public void buildUI(table table){ public void buildUI(table table){
@@ -71,7 +75,7 @@ public class Tutorial{
//info.setText(stage.text); //info.setText(stage.text);
if(stage.showBlock){ if(stage.showBlock){
Tile tile = World.tile(World.core.x + stage.blockPlaceX, World.core.y + stage.blockPlaceY); Tile tile = world.tile(control.core.x + stage.blockPlaceX, control.core.y + stage.blockPlaceY);
if(tile.block() == stage.targetBlock && (tile.rotation == stage.blockRotation || stage.blockRotation == -1)){ if(tile.block() == stage.targetBlock && (tile.rotation == stage.blockRotation || stage.blockRotation == -1)){
move(true); move(true);
@@ -151,9 +155,9 @@ public class Tutorial{
} }
public void setDefaultBlocks(int corex, int corey){ public void setDefaultBlocks(int corex, int corey){
World.tile(corex, corey - 1).setBlock(Blocks.air); world.tile(corex, corey - 1).setBlock(Blocks.air);
World.tile(corex, corey - 2).setBlock(Blocks.air); world.tile(corex, corey - 2).setBlock(Blocks.air);
World.tile(corex, corey - 2).setFloor(Blocks.stone); world.tile(corex, corey - 2).setFloor(Blocks.stone);
} }
enum Stage{ enum Stage{
@@ -288,11 +292,11 @@ public class Tutorial{
void onSwitch(){ void onSwitch(){
for(int flip : new int[]{1, -1}){ for(int flip : new int[]{1, -1}){
World.tile(World.core.x + flip, World.core.y - 1).setBlock(DistributionBlocks.conveyor, 2 * flip); world.tile(control.core.x + flip, control.core.y - 1).setBlock(DistributionBlocks.conveyor, 2 * flip);
World.tile(World.core.x + flip*2, World.core.y - 1).setBlock(DistributionBlocks.conveyor, 2 * flip); world.tile(control.core.x + flip*2, control.core.y - 1).setBlock(DistributionBlocks.conveyor, 2 * flip);
World.tile(World.core.x + flip*2, World.core.y - 2).setBlock(DistributionBlocks.conveyor, 1); world.tile(control.core.x + flip*2, control.core.y - 2).setBlock(DistributionBlocks.conveyor, 1);
World.tile(World.core.x + flip*2, World.core.y - 3).setFloor(Blocks.stone); world.tile(control.core.x + flip*2, control.core.y - 3).setFloor(Blocks.stone);
World.tile(World.core.x + flip*2, World.core.y - 3).setBlock(ProductionBlocks.stonedrill); world.tile(control.core.x + flip*2, control.core.y - 3).setBlock(ProductionBlocks.stonedrill);
} }
} }
@@ -463,7 +467,7 @@ public class Tutorial{
void onSwitch(){ void onSwitch(){
Vars.ui.<ImageButton>find("sectionbuttondistribution").fireClick(); Vars.ui.<ImageButton>find("sectionbuttondistribution").fireClick();
World.tile(blockPlaceX + World.core.x, blockPlaceY + World.core.y).setBlock(Blocks.air); world.tile(blockPlaceX + control.core.x, blockPlaceY + control.core.y).setBlock(Blocks.air);
} }
}, },
conduitUse2{ conduitUse2{
@@ -480,7 +484,7 @@ public class Tutorial{
} }
void onSwitch(){ void onSwitch(){
World.tile(blockPlaceX + World.core.x, blockPlaceY + World.core.y).setBlock(Blocks.air); world.tile(blockPlaceX + control.core.x, blockPlaceY + control.core.y).setBlock(Blocks.air);
} }
}, },
conduitUse3{ conduitUse3{
@@ -497,7 +501,7 @@ public class Tutorial{
} }
void onSwitch(){ void onSwitch(){
World.tile(blockPlaceX + World.core.x, blockPlaceY + World.core.y).setBlock(Blocks.air); world.tile(blockPlaceX + control.core.x, blockPlaceY + control.core.y).setBlock(Blocks.air);
} }
}, },
extractor{ extractor{
@@ -513,7 +517,7 @@ public class Tutorial{
} }
void onSwitch(){ void onSwitch(){
World.tile(blockPlaceX + World.core.x, blockPlaceY + World.core.y).setBlock(Blocks.air); world.tile(blockPlaceX + control.core.x, blockPlaceY + control.core.y).setBlock(Blocks.air);
Vars.ui.<ImageButton>find("sectionbuttonproduction").fireClick(); Vars.ui.<ImageButton>find("sectionbuttonproduction").fireClick();
Vars.control.addItem(Item.steel, 60); Vars.control.addItem(Item.steel, 60);
Vars.control.addItem(Item.iron, 60); Vars.control.addItem(Item.iron, 60);
@@ -527,19 +531,19 @@ public class Tutorial{
void onSwitch(){ void onSwitch(){
for(int i = -2; i <= 2; i ++){ for(int i = -2; i <= 2; i ++){
World.tile(World.core.x + i + 4, World.core.y + 2).setBlock(ProductionBlocks.stonedrill); world.tile(control.core.x + i + 4, control.core.y + 2).setBlock(ProductionBlocks.stonedrill);
World.tile(World.core.x + i + 4, World.core.y + 2).setFloor(Blocks.stone); world.tile(control.core.x + i + 4, control.core.y + 2).setFloor(Blocks.stone);
} }
for(int i = 0; i < 3; i ++){ for(int i = 0; i < 3; i ++){
World.tile(World.core.x + 4 - 1 - i, World.core.y).setBlock(DistributionBlocks.conveyor, 2); world.tile(control.core.x + 4 - 1 - i, control.core.y).setBlock(DistributionBlocks.conveyor, 2);
} }
World.tile(World.core.x + 2, World.core.y + 1).setBlock(DistributionBlocks.conveyor, 0); world.tile(control.core.x + 2, control.core.y + 1).setBlock(DistributionBlocks.conveyor, 0);
World.tile(World.core.x + 3, World.core.y + 1).setBlock(DistributionBlocks.conveyor, 0); world.tile(control.core.x + 3, control.core.y + 1).setBlock(DistributionBlocks.conveyor, 0);
World.tile(World.core.x + 4, World.core.y + 1).setBlock(DistributionBlocks.conveyor, 3); world.tile(control.core.x + 4, control.core.y + 1).setBlock(DistributionBlocks.conveyor, 3);
World.tile(World.core.x + 5, World.core.y + 1).setBlock(DistributionBlocks.conveyor, 2); world.tile(control.core.x + 5, control.core.y + 1).setBlock(DistributionBlocks.conveyor, 2);
World.tile(World.core.x + 6, World.core.y + 1).setBlock(DistributionBlocks.conveyor, 2); world.tile(control.core.x + 6, control.core.y + 1).setBlock(DistributionBlocks.conveyor, 2);
} }
}, },
@@ -2,8 +2,8 @@ package io.anuke.mindustry.entities;
import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.tilesize;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.entities.*; import io.anuke.ucore.entities.*;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -29,7 +29,7 @@ public class Bullet extends BulletEntity{
int tilex = Mathf.scl2(x, tilesize); int tilex = Mathf.scl2(x, tilesize);
int tiley = Mathf.scl2(y, tilesize); int tiley = Mathf.scl2(y, tilesize);
Tile tile = World.tile(tilex, tiley); Tile tile = Vars.world.tile(tilex, tiley);
TileEntity targetEntity = null; TileEntity targetEntity = null;
if(tile != null){ if(tile != null){
@@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -29,7 +28,7 @@ public class DamageArea{
int trad = (int)(radius / Vars.tilesize); int trad = (int)(radius / Vars.tilesize);
for(int dx = -trad; dx <= trad; dx ++){ for(int dx = -trad; dx <= trad; dx ++){
for(int dy= -trad; dy <= trad; dy ++){ for(int dy= -trad; dy <= trad; dy ++){
Tile tile = World.tile(Mathf.scl2(x, Vars.tilesize) + dx, Mathf.scl2(y, Vars.tilesize) + dy); Tile tile = Vars.world.tile(Mathf.scl2(x, Vars.tilesize) + dx, Mathf.scl2(y, Vars.tilesize) + dy);
if(tile != null && tile.entity != null && Vector2.dst(dx, dy, 0, 0) <= trad){ if(tile != null && tile.entity != null && Vector2.dst(dx, dy, 0, 0) <= trad){
int amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage); int amount = calculateDamage(x, y, tile.worldx(), tile.worldy(), radius, damage);
tile.entity.damage(amount); tile.entity.damage(amount);
@@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.mindustry.world.blocks.types.PowerAcceptor; import io.anuke.mindustry.world.blocks.types.PowerAcceptor;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
@@ -36,7 +35,7 @@ public class EMP extends TimedEntity{
for(int dx = -radius; dx <= radius; dx ++){ for(int dx = -radius; dx <= radius; dx ++){
for(int dy = -radius; dy <= radius; dy ++){ for(int dy = -radius; dy <= radius; dy ++){
if(Vector2.dst(dx, dy, 0, 0) < radius){ if(Vector2.dst(dx, dy, 0, 0) < radius){
Tile tile = World.tile(worldx + dx, worldy + dy); Tile tile = Vars.world.tile(worldx + dx, worldy + dy);
if(tile != null && tile.block().destructible){ if(tile != null && tile.block().destructible){
array.add(tile); array.add(tile);
@@ -5,14 +5,12 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.effect.Fx; import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.entities.effect.Shaders; import io.anuke.mindustry.entities.effect.Shaders;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.*; import io.anuke.ucore.entities.*;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -57,15 +55,17 @@ public class Enemy extends DestructibleEntity{
} }
void move(){ void move(){
boolean nearCore = distanceTo(World.core.worldx(), World.core.worldy()) <= range - 18f; Tile core = Vars.control.getCore();
boolean nearCore = distanceTo(core.worldx(), core.worldy()) <= range - 18f;
Vector2 vec; Vector2 vec;
if(nearCore){ if(nearCore){
vec = Tmp.v2.setZero(); vec = Tmp.v2.setZero();
target = World.core.entity; target = core.entity;
}else{ }else{
vec = Pathfind.find(this); vec = Vars.world.pathfinder().find(this);
vec.sub(x, y).setLength(speed); vec.sub(x, y).setLength(speed);
} }
@@ -94,8 +94,13 @@ public class Enemy extends DestructibleEntity{
move(vec.x * Timers.delta(), vec.y * Timers.delta()); move(vec.x * Timers.delta(), vec.y * Timers.delta());
updateTargeting(nearCore);
}
void updateTargeting(boolean nearCore){
if(Timers.get(this, "target", 15) && !nearCore){ if(Timers.get(this, "target", 15) && !nearCore){
target = World.findTileTarget(x, y, null, range, false); target = Vars.world.findTileTarget(x, y, null, range, false);
//no tile found //no tile found
if(target == null){ if(target == null){
@@ -126,7 +131,7 @@ public class Enemy extends DestructibleEntity{
} }
public void findClosestNode(){ public void findClosestNode(){
Pathfind.find(this); Vars.world.pathfinder().find(this);
int index = 0; int index = 0;
int cindex = -1; int cindex = -1;
@@ -150,7 +155,7 @@ public class Enemy extends DestructibleEntity{
int x2 = path[node].x, y2 = path[node].y; int x2 = path[node].x, y2 = path[node].y;
//if the enemy can't move to that node right now, set its position to it //if the enemy can't move to that node right now, set its position to it
if(World.raycast(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize), x2, y2) != null){ if(Vars.world.raycast(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize), x2, y2) != null){
Timers.run(Mathf.random(15f), () -> { Timers.run(Mathf.random(15f), () -> {
set(x2 * Vars.tilesize, y2 * Vars.tilesize); set(x2 * Vars.tilesize, y2 * Vars.tilesize);
}); });
@@ -1,11 +1,11 @@
package io.anuke.mindustry.entities.enemies; package io.anuke.mindustry.entities.enemies;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.effect.Shaders;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.graphics.Hue;
@@ -28,12 +28,7 @@ public class HealerEnemy extends Enemy{
} }
@Override @Override
void move(){ void updateTargeting(boolean nearCore){
Vector2 vec = Pathfind.find(this);
vec.sub(x, y).setLength(speed);
move(vec.x*Timers.delta(), vec.y*Timers.delta());
if(Timers.get(this, "target", 15)){ if(Timers.get(this, "target", 15)){
target = Entities.getClosest(Entities.getGroup(Enemy.class), target = Entities.getClosest(Entities.getGroup(Enemy.class),
x, y, range, e -> e instanceof Enemy && e != this && ((Enemy)e).healthfrac() < 1f); x, y, range, e -> e instanceof Enemy && e != this && ((Enemy)e).healthfrac() < 1f);
@@ -62,12 +57,14 @@ public class HealerEnemy extends Enemy{
Angles.translation(this.angleTo(enemy), 5f); Angles.translation(this.angleTo(enemy), 5f);
Graphics.shader();
if(enemy != null && enemy.health < enemy.maxhealth){ if(enemy != null && enemy.health < enemy.maxhealth){
Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f)); Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f));
Draw.alpha(0.9f); Draw.alpha(0.9f);
Draw.laser("laser", "laserend", x + Angles.x(), y + Angles.y(), enemy.x - Angles.x()/1.5f, enemy.y - Angles.y()/1.5f); Draw.laser("laser", "laserend", x + Angles.x(), y + Angles.y(), enemy.x - Angles.x()/1.5f, enemy.y - Angles.y()/1.5f);
Draw.color(); Draw.color();
} }
Graphics.shader(Shaders.outline);
} }
} }
@@ -10,7 +10,6 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
@@ -51,7 +50,7 @@ public class AndroidInput extends InputAdapter{
public static Tile selected(){ public static Tile selected(){
Vector2 vec = Graphics.world(mousex, mousey); Vector2 vec = Graphics.world(mousex, mousey);
return World.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize)); return Vars.world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
} }
public static void breakBlock(){ public static void breakBlock(){
@@ -60,7 +59,7 @@ public class AndroidInput extends InputAdapter{
if(player.breaktime >= tile.block().breaktime){ if(player.breaktime >= tile.block().breaktime){
brokeBlock = true; brokeBlock = true;
World.breakBlock(tile.x, tile.y); Vars.world.breakBlock(tile.x, tile.y);
player.breaktime = 0f; player.breaktime = 0f;
} }
} }
@@ -72,9 +71,9 @@ public class AndroidInput extends InputAdapter{
int tiley = Mathf.scl2(vec.y, tilesize); int tiley = Mathf.scl2(vec.y, tilesize);
if(player.recipe != null && if(player.recipe != null &&
World.validPlace(tilex, tiley, player.recipe.result)){ Vars.world.validPlace(tilex, tiley, player.recipe.result)){
World.placeBlock(tilex, tiley, player.recipe.result, player.rotation); Vars.world.placeBlock(tilex, tiley, player.recipe.result, player.rotation);
for(ItemStack stack : player.recipe.requirements){ for(ItemStack stack : player.recipe.requirements){
Vars.control.removeItem(stack); Vars.control.removeItem(stack);
@@ -97,7 +96,7 @@ public class AndroidInput extends InputAdapter{
if(sel == null) return; if(sel == null) return;
if(warmup > warmupDelay && World.validBreak(sel.x, sel.y)){ if(warmup > warmupDelay && Vars.world.validBreak(sel.x, sel.y)){
player.breaktime += Timers.delta(); player.breaktime += Timers.delta();
if(player.breaktime > selected().block().breaktime){ if(player.breaktime > selected().block().breaktime){
+5 -6
View File
@@ -10,7 +10,6 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.mindustry.world.blocks.types.Configurable;
import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Inputs;
@@ -46,13 +45,13 @@ public class Input{
} }
} }
Tile cursor = World.tile(tilex(), tiley()); Tile cursor = Vars.world.tile(tilex(), tiley());
if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != null && if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != null &&
World.validPlace(tilex(), tiley(), player.recipe.result) && !ui.hasMouse() && cursorNear() && Vars.world.validPlace(tilex(), tiley(), player.recipe.result) && !ui.hasMouse() && cursorNear() &&
Vars.control.hasItems(player.recipe.requirements)){ Vars.control.hasItems(player.recipe.requirements)){
World.placeBlock(tilex(), tiley(), player.recipe.result, player.rotation); Vars.world.placeBlock(tilex(), tiley(), player.recipe.result, player.rotation);
for(ItemStack stack : player.recipe.requirements){ for(ItemStack stack : player.recipe.requirements){
Vars.control.removeItem(stack); Vars.control.removeItem(stack);
@@ -80,11 +79,11 @@ public class Input{
} }
//block breaking //block breaking
if(Inputs.buttonDown(Buttons.RIGHT) && cursor != null && World.validBreak(tilex(), tiley())){ if(Inputs.buttonDown(Buttons.RIGHT) && cursor != null && Vars.world.validBreak(tilex(), tiley())){
Tile tile = cursor; Tile tile = cursor;
player.breaktime += Timers.delta(); player.breaktime += Timers.delta();
if(player.breaktime >= tile.getBreakTime()){ if(player.breaktime >= tile.getBreakTime()){
World.breakBlock(cursor.x, cursor.y); Vars.world.breakBlock(cursor.x, cursor.y);
player.breaktime = 0f; player.breaktime = 0f;
} }
}else{ }else{
+18 -16
View File
@@ -19,7 +19,9 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.*; import io.anuke.mindustry.entities.enemies.*;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Core;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
@@ -203,16 +205,16 @@ public class SaveIO{
//--MAP DATA-- //--MAP DATA--
//map ID //map ID
stream.writeByte(World.getMap().ordinal()); stream.writeByte(Vars.world.getMap().ordinal());
//seed //seed
stream.writeInt(World.getSeed()); stream.writeInt(Vars.world.getSeed());
int totalblocks = 0; int totalblocks = 0;
for(int x = 0; x < World.width(); x ++){ for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < World.height(); y ++){ for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = World.tile(x, y); Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){ if(tile.breakable()){
totalblocks ++; totalblocks ++;
@@ -223,13 +225,13 @@ public class SaveIO{
//tile amount //tile amount
stream.writeInt(totalblocks); stream.writeInt(totalblocks);
for(int x = 0; x < World.width(); x ++){ for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < World.height(); y ++){ for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = World.tile(x, y); Tile tile = Vars.world.tile(x, y);
if(tile.breakable()){ if(tile.breakable()){
stream.writeInt(x + y*World.width()); //tile pos stream.writeInt(x + y*Vars.world.width()); //tile pos
stream.writeByte(tile.link); stream.writeByte(tile.link);
stream.writeBoolean(tile.entity != null); //whether it has a tile entity stream.writeBoolean(tile.entity != null); //whether it has a tile entity
stream.writeInt(tile.block().id); //block ID stream.writeInt(tile.block().id); //block ID
@@ -349,20 +351,20 @@ public class SaveIO{
int seed = stream.readInt(); int seed = stream.readInt();
int tiles = stream.readInt(); int tiles = stream.readInt();
World.loadMap(Map.values()[mapid], seed); Vars.world.loadMap(Map.values()[mapid], seed);
Vars.renderer.clearTiles(); Vars.renderer.clearTiles();
for(Enemy enemy : enemiesToUpdate){ for(Enemy enemy : enemiesToUpdate){
enemy.findClosestNode(); enemy.findClosestNode();
} }
for(int x = 0; x < World.width(); x ++){ for(int x = 0; x < Vars.world.width(); x ++){
for(int y = 0; y < World.height(); y ++){ for(int y = 0; y < Vars.world.height(); y ++){
Tile tile = World.tile(x, y); Tile tile = Vars.world.tile(x, y);
//remove breakables like rocks //remove breakables like rocks
if(tile.breakable()){ if(tile.breakable()){
World.tile(x, y).setBlock(Blocks.air); Vars.world.tile(x, y).setBlock(Blocks.air);
} }
} }
} }
@@ -373,7 +375,7 @@ public class SaveIO{
boolean hasEntity = stream.readBoolean(); boolean hasEntity = stream.readBoolean();
int blockid = stream.readInt(); int blockid = stream.readInt();
Tile tile = World.tile(pos % World.width(), pos / World.width()); Tile tile = Vars.world.tile(pos % Vars.world.width(), pos / Vars.world.width());
tile.setBlock(Block.getByID(blockid)); tile.setBlock(Block.getByID(blockid));
tile.link = link; tile.link = link;
@@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Map;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
@@ -50,7 +49,7 @@ public class LevelDialog extends FloatingDialog{
float images = 154f; float images = 154f;
ImageButton image = new ImageButton(new TextureRegion(World.getTexture(map)), "togglemap"); ImageButton image = new ImageButton(new TextureRegion(Vars.world.getTexture(map)), "togglemap");
image.row(); image.row();
image.add(inset).width(images+6).units(Unit.dp); image.add(inset).width(images+6).units(Unit.dp);
image.clicked(()->{ image.clicked(()->{
+17 -3
View File
@@ -15,6 +15,7 @@ import io.anuke.mindustry.resource.Liquid;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
public class Block{ public class Block{
private static int lastid; private static int lastid;
@@ -48,10 +49,12 @@ public class Block{
public int health = 40; public int health = 40;
/**the shadow drawn under the block*/ /**the shadow drawn under the block*/
public String shadow = "shadow"; public String shadow = "shadow";
/**whether to display a different shadow per variant*/
public boolean varyShadow = false;
/**edge fallback, used mainly for ores*/ /**edge fallback, used mainly for ores*/
public String edge = "stone"; public String edge = "stone";
/**whether this block has 3 variants*/ /**number of block variants, 0 to disable*/
public boolean vary = true; public int variants = 0;
/**stuff that drops when broken*/ /**stuff that drops when broken*/
public ItemStack drops = null; public ItemStack drops = null;
/**liquids that drop from this block, used for pumps*/ /**liquids that drop from this block, used for pumps*/
@@ -203,10 +206,12 @@ public class Block{
public void draw(Tile tile){ public void draw(Tile tile){
//note: multiblocks do not support rotation //note: multiblocks do not support rotation
if(!isMultiblock()){ if(!isMultiblock()){
Draw.rect(name(), tile.worldx(), tile.worldy(), rotate ? tile.rotation * 90 : 0); Draw.rect(variants > 0 ? (name() + Mathf.randomSeed(tile.id(), 1, variants)) : name(),
tile.worldx(), tile.worldy(), rotate ? tile.rotation * 90 : 0);
}else{ }else{
//if multiblock, make sure to draw even block sizes offset, since the core block is at the BOTTOM LEFT //if multiblock, make sure to draw even block sizes offset, since the core block is at the BOTTOM LEFT
Vector2 offset = getPlaceOffset(); Vector2 offset = getPlaceOffset();
Draw.rect(name(), tile.worldx() + offset.x, tile.worldy() + offset.y); Draw.rect(name(), tile.worldx() + offset.x, tile.worldy() + offset.y);
} }
@@ -216,6 +221,15 @@ public class Block{
} }
} }
public void drawShadow(Tile tile){
if(varyShadow && variants > 0){
Draw.rect(shadow + (Mathf.randomSeed(tile.id(), 1, variants)), tile.worldx(), tile.worldy());
}else{
Draw.rect(shadow, tile.worldx(), tile.worldy());
}
}
/**Offset for placing and drawing multiblocks.*/ /**Offset for placing and drawing multiblocks.*/
public Vector2 getPlaceOffset(){ public Vector2 getPlaceOffset(){
return Tmp.v3.set(((width + 1) % 2) * Vars.tilesize/2, ((height + 1) % 2) * Vars.tilesize/2); return Tmp.v3.set(((width + 1) % 2) * Vars.tilesize/2, ((height + 1) % 2) * Vars.tilesize/2);
@@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.enemies.TargetEnemy; import io.anuke.mindustry.entities.enemies.TargetEnemy;
import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.noise.Noise; import io.anuke.ucore.noise.Noise;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -23,14 +24,16 @@ public class Generator{
Hue.rgb(110, 80, 30), Blocks.dirt, Hue.rgb(110, 80, 30), Blocks.dirt,
Hue.rgb(160, 120, 70), Blocks.dirtblock, Hue.rgb(160, 120, 70), Blocks.dirtblock,
Hue.rgb(100, 100, 100), Blocks.stoneblock, Hue.rgb(100, 100, 100), Blocks.stoneblock,
Color.valueOf("414141"), Blocks.blackstoneblock,
Color.valueOf("252525"), Blocks.blackstone,
Color.valueOf("ed5334"), Blocks.lava, Color.valueOf("ed5334"), Blocks.lava,
Color.valueOf("292929"), Blocks.oil Color.valueOf("292929"), Blocks.oil
); );
/**Returns world size.*/ /**Returns world size.*/
public static void generate(Pixmap pixmap){ public static void generate(Pixmap pixmap, Tile[][] tiles){
Noise.setSeed(World.getSeed()); Noise.setSeed(Vars.world.getSeed());
for(int x = 0; x < pixmap.getWidth(); x ++){ for(int x = 0; x < pixmap.getWidth(); x ++){
for(int y = 0; y < pixmap.getHeight(); y ++){ for(int y = 0; y < pixmap.getHeight(); y ++){
@@ -41,23 +44,29 @@ public class Generator{
if(colors.containsKey(color)){ if(colors.containsKey(color)){
//TODO less hacky method //TODO less hacky method
if(colors.get(color).name().contains("block")){ if(!(colors.get(color) instanceof Floor)){
block = colors.get(color); block = colors.get(color);
}else{ }else{
floor = colors.get(color); floor = colors.get(color);
} }
}else if(color == start){ }else if(color == start){
World.core = World.tile(x, y); Vars.control.setCore(Vars.world.tile(x, y));
}else if(color == spawn){ }else if(color == spawn){
World.spawnpoints.add(World.tile(x, y)); Vars.control.addSpawnPoint(Vars.world.tile(x, y));
floor = Blocks.dirt; floor = Blocks.dirt;
}else{ }
if(Mathf.chance(0.02)){
block = Mathf.choose(Blocks.rock, Blocks.rock2); if(block == Blocks.air){
if(floor == Blocks.stone && Mathf.chance(0.02)){
block = Blocks.rock;
}
if(floor == Blocks.blackstone && Mathf.chance(0.03)){
block = Blocks.blackrock;
} }
} }
if(floor == Blocks.stone || floor == Blocks.grass){ if(floor == Blocks.stone || floor == Blocks.grass || floor == Blocks.blackstone){
if(Noise.nnoise(x, y, 8, 1) > 0.2){ if(Noise.nnoise(x, y, 8, 1) > 0.2){
floor = Blocks.iron; floor = Blocks.iron;
} }
@@ -77,11 +86,6 @@ public class Generator{
if(block == Blocks.grassblock){ if(block == Blocks.grassblock){
floor = Blocks.grass; floor = Blocks.grass;
block = Mathf.choose(Blocks.grassblock, Blocks.grassblock2);
}
if(block == Blocks.stoneblock){
block = Mathf.choose(Blocks.stoneblock, Blocks.stoneblock2, Blocks.stoneblock3);
} }
if(floor == Blocks.grass && Mathf.chance(0.02) && block == Blocks.air){ if(floor == Blocks.grass && Mathf.chance(0.02) && block == Blocks.air){
@@ -98,10 +102,8 @@ public class Generator{
// block = Mathf.choose(ProductionBlocks.stonedrill, DistributionBlocks.conveyor); // block = Mathf.choose(ProductionBlocks.stonedrill, DistributionBlocks.conveyor);
//} //}
World.tile(x, y).setBlock(block); tiles[x][y].setBlock(block, 0);
World.tile(x, y).setFloor(floor); tiles[x][y].setFloor(floor);
} }
} }
} }
+9 -5
View File
@@ -2,27 +2,31 @@ package io.anuke.mindustry.world;
public enum Map{ public enum Map{
delta("Starting map."), delta("Starting map."),
canyon("Badly drawn map."),
pit("Eck."), pit("Eck."),
maze("it's okay."), maze("it's okay."),
maze2("test"), volcano("desc"),
maze3("test"),
maze4("test"),
maze5("test"),
tutorial(false), tutorial(false),
test1(false), test1(false),
test2(false); test2(false);
public final boolean visible; public final boolean visible;
public final boolean sandbox;
public final String description; public final String description;
public int width, height;
private Map(boolean visible){ private Map(boolean visible){
this.visible = visible; this.visible = visible;
this.sandbox = false;
this.description = "Test map!"; this.description = "Test map!";
} }
private Map(String description){ private Map(String description){
this(description, false);
}
private Map(String description, boolean sandbox){
this.visible = true; this.visible = true;
this.sandbox = sandbox;
this.description = description; this.description = description;
} }
} }
@@ -0,0 +1,14 @@
package io.anuke.mindustry.world;
import com.badlogic.gdx.ai.pfa.PathFinder;
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
import io.anuke.mindustry.ai.SmoothGraphPath;
public class SpawnPoint{
public Tile start;
public Tile[] pathTiles;
public PathFinder<Tile> finder;
public SmoothGraphPath path = new SmoothGraphPath();
public PathFinderRequest<Tile> request;
}
+6 -5
View File
@@ -5,6 +5,7 @@ import static io.anuke.mindustry.Vars.tilesize;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.Bits;
@@ -52,7 +53,7 @@ public class Tile{
float dst = Vector2.dst(dx, dy, 0, 0); float dst = Vector2.dst(dx, dy, 0, 0);
if(dst > rad || (dx == 0 && dy == 0)) continue; if(dst > rad || (dx == 0 && dy == 0)) continue;
Tile other = World.tile(x + dx, y + dy); Tile other = Vars.world.tile(x + dx, y + dy);
if(other.entity != null){ if(other.entity != null){
other.entity.damage((int)(amount * Mathf.lerp(1f-dst/rad, 1f, falloff))); other.entity.damage((int)(amount * Mathf.lerp(1f-dst/rad, 1f, falloff)));
} }
@@ -61,7 +62,7 @@ public class Tile{
} }
public int id(){ public int id(){
return x + y * World.worldsize; return x + y * Vars.world.width();
} }
public float worldx(){ public float worldx(){
@@ -139,7 +140,7 @@ public class Tile{
int offsety = -(block.height-1)/2; int offsety = -(block.height-1)/2;
for(int dx = 0; dx < block.width; dx ++){ for(int dx = 0; dx < block.width; dx ++){
for(int dy = 0; dy < block.height; dy ++){ for(int dy = 0; dy < block.height; dy ++){
Tile other = World.tile(x + dx + offsetx, y + dy + offsety); Tile other = Vars.world.tile(x + dx + offsetx, y + dy + offsety);
tmpArray.add(other); tmpArray.add(other);
} }
} }
@@ -154,12 +155,12 @@ public class Tile{
}else{ }else{
byte dx = Bits.getLeftByte(link); byte dx = Bits.getLeftByte(link);
byte dy = Bits.getRightByte(link); byte dy = Bits.getRightByte(link);
return World.tile(x - (dx - 8), y - (dy - 8)); return Vars.world.tile(x - (dx - 8), y - (dy - 8));
} }
} }
public Tile[] getNearby(){ public Tile[] getNearby(){
return World.getNearby(x, y); return Vars.world.getNearby(x, y);
} }
public void changed(){ public void changed(){
+76 -77
View File
@@ -18,61 +18,81 @@ import io.anuke.ucore.core.Sounds;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
public class World{ public class World extends Module{
public static int worldsize = 128; private int seed;
public static int pixsize = worldsize*tilesize;
private static int seed;
private static Pixmap[] mapPixmaps; private Pixmap[] mapPixmaps;
private static Texture[] mapTextures; private Texture[] mapTextures;
private static Map currentMap; private Map currentMap;
private static Tile[][] tiles = new Tile[worldsize][worldsize]; private Tile[][] tiles;
private static Tile[] temptiles = new Tile[4]; private Tile[] temptiles = new Tile[4];
private Pathfind pathfind = new Pathfind();
public static Tile core; public World(){
//TODO move this to control? loadMaps();
public static Array<Tile> spawnpoints = new Array<Tile>(); }
public static boolean solid(int x, int y){ @Override
public void update(){
pathfind.update();
}
@Override
public void dispose(){
for(Texture texture : mapTextures){
texture.dispose();
}
for(Pixmap pix : mapPixmaps){
pix.dispose();
}
}
public Pathfind pathfinder(){
return pathfind;
}
public boolean solid(int x, int y){
Tile tile = tile(x, y); Tile tile = tile(x, y);
return tile == null || tile.block().solid || (tile.floor().solid && (tile.block() == Blocks.air)); return tile == null || tile.block().solid || (tile.floor().solid && (tile.block() == Blocks.air));
} }
public static boolean wallSolid(int x, int y){ public boolean wallSolid(int x, int y){
Tile tile = tile(x, y); Tile tile = tile(x, y);
return tile == null || tile.block().solid; return tile == null || tile.block().solid;
} }
public static boolean isAccessible(int x, int y){ public boolean isAccessible(int x, int y){
return !wallSolid(x, y-1) || !wallSolid(x, y+1) || !wallSolid(x-1, y) ||!wallSolid(x+1, y); return !wallSolid(x, y-1) || !wallSolid(x, y+1) || !wallSolid(x-1, y) ||!wallSolid(x+1, y);
} }
public static Map getMap(){ public Map getMap(){
return currentMap; return currentMap;
} }
public static int width(){ public int width(){
return mapPixmaps[currentMap.ordinal()].getWidth(); return currentMap.width;
} }
public static int height(){ public int height(){
return mapPixmaps[currentMap.ordinal()].getHeight(); return currentMap.height;
} }
public static Tile tile(int x, int y){ public Tile tile(int x, int y){
if(!Mathf.inBounds(x, y, tiles)) return null; if(!Mathf.inBounds(x, y, tiles)) return null;
return tiles[x][y]; return tiles[x][y];
} }
public static Tile tileWorld(float x, float y){ public Tile tileWorld(float x, float y){
return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize)); return tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize));
} }
public static Tile[] getNearby(int x, int y){ public Tile[] getNearby(int x, int y){
temptiles[0] = tile(x+1, y); temptiles[0] = tile(x+1, y);
temptiles[1] = tile(x, y+1); temptiles[1] = tile(x, y+1);
temptiles[2] = tile(x-1, y); temptiles[2] = tile(x-1, y);
@@ -80,11 +100,11 @@ public class World{
return temptiles; return temptiles;
} }
public static Texture getTexture(Map map){ public Texture getTexture(Map map){
return mapTextures[map.ordinal()]; return mapTextures[map.ordinal()];
} }
public static void loadMaps(){ public void loadMaps(){
Map[] maps = Map.values(); Map[] maps = Map.values();
mapPixmaps = new Pixmap[maps.length]; mapPixmaps = new Pixmap[maps.length];
@@ -94,10 +114,12 @@ public class World{
Pixmap pix = new Pixmap(Gdx.files.internal("maps/"+maps[i]+".png")); Pixmap pix = new Pixmap(Gdx.files.internal("maps/"+maps[i]+".png"));
mapPixmaps[i] = pix; mapPixmaps[i] = pix;
mapTextures[i] = new Texture(pix); mapTextures[i] = new Texture(pix);
maps[i].width = pix.getWidth();
maps[i].height = pix.getHeight();
} }
} }
private static void createTiles(){ private void createTiles(){
for(int x = 0; x < tiles.length; x ++){ for(int x = 0; x < tiles.length; x ++){
for(int y = 0; y < tiles[0].length; y ++){ for(int y = 0; y < tiles[0].length; y ++){
if(tiles[x][y] == null){ if(tiles[x][y] == null){
@@ -107,7 +129,7 @@ public class World{
} }
} }
private static void clearTileEntities(){ private void clearTileEntities(){
for(int x = 0; x < tiles.length; x ++){ for(int x = 0; x < tiles.length; x ++){
for(int y = 0; y < tiles[0].length; y ++){ for(int y = 0; y < tiles[0].length; y ++){
if(tiles[x][y] != null && tiles[x][y].entity != null){ if(tiles[x][y] != null && tiles[x][y].entity != null){
@@ -117,57 +139,48 @@ public class World{
} }
} }
public static void loadMap(Map map){ public void loadMap(Map map){
loadMap(map, MathUtils.random(0, 99999)); loadMap(map, MathUtils.random(0, 99999));
} }
public static void loadMap(Map map, int seed){ public void loadMap(Map map, int seed){
spawnpoints.clear();
int size = mapPixmaps[map.ordinal()].getWidth();
worldsize = size;
pixsize = worldsize*tilesize;
currentMap = map; currentMap = map;
if(tiles != null){ if(tiles != null){
clearTileEntities(); clearTileEntities();
if(tiles.length != worldsize || tiles[0].length != worldsize){ if(tiles.length != map.width || tiles[0].length != map.height){
tiles = new Tile[worldsize][worldsize]; tiles = new Tile[map.width][map.height];
} }
createTiles(); createTiles();
}else{ }else{
tiles = new Tile[worldsize][worldsize]; tiles = new Tile[map.width][map.height];
createTiles(); createTiles();
} }
Entities.resizeTree(0, 0, pixsize, pixsize); Entities.resizeTree(0, 0, map.width * tilesize, map.height * tilesize);
World.seed = seed; this.seed = seed;
Generator.generate(mapPixmaps[map.ordinal()]); Generator.generate(mapPixmaps[map.ordinal()], tiles);
Pathfind.reset();
//TODO multiblock core //TODO multiblock core
placeBlock(core.x, core.y, ProductionBlocks.core, 0); placeBlock(control.getCore().x, control.getCore().y, ProductionBlocks.core, 0);
if(map != Map.tutorial){ if(map != Map.tutorial){
setDefaultBlocks(); setDefaultBlocks();
}else{ }else{
Vars.control.getTutorial().setDefaultBlocks(core.x, core.y); Vars.control.getTutorial().setDefaultBlocks(control.getCore().x, control.getCore().y);
} }
Pathfind.updatePath(); pathfind.updatePath();
} }
static void setDefaultBlocks(){ void setDefaultBlocks(){
int x = core.x, y = core.y; int x = control.getCore().x, y = control.getCore().y;
//set(x, y-1, DistributionBlocks.conveyor, 1);
set(x, y-2, DistributionBlocks.conveyor, 1); set(x, y-2, DistributionBlocks.conveyor, 1);
set(x, y-3, DistributionBlocks.conveyor, 1); set(x, y-3, DistributionBlocks.conveyor, 1);
@@ -183,28 +196,26 @@ public class World{
set(x+2*d, y-3, DistributionBlocks.conveyor, 2*d); set(x+2*d, y-3, DistributionBlocks.conveyor, 2*d);
set(x+2*d, y-4, DistributionBlocks.conveyor, 1); set(x+2*d, y-4, DistributionBlocks.conveyor, 1);
set(x+2*d, y-5, DistributionBlocks.conveyor, 1); set(x+2*d, y-5, DistributionBlocks.conveyor, 1);
//set(x+2*d, y-6, DistributionBlocks.conveyor, 1);
//set(x+3*d, y-6, ProductionBlocks.stonedrill, 0);
set(x+3*d, y-5, ProductionBlocks.stonedrill, 0); set(x+3*d, y-5, ProductionBlocks.stonedrill, 0);
set(x+3*d, y-4, ProductionBlocks.stonedrill, 0); set(x+3*d, y-4, ProductionBlocks.stonedrill, 0);
set(x+3*d, y-3, ProductionBlocks.stonedrill, 0); set(x+3*d, y-3, ProductionBlocks.stonedrill, 0);
} }
} }
static void set(int x, int y, Block type, int rot){ void set(int x, int y, Block type, int rot){
if(type == ProductionBlocks.stonedrill){ if(type == ProductionBlocks.stonedrill){
tiles[x][y].setFloor(Blocks.stone); tiles[x][y].setFloor(Blocks.stone);
} }
tiles[x][y].setBlock(type, rot); tiles[x][y].setBlock(type, rot);
} }
public static int getSeed(){ public int getSeed(){
return seed; return seed;
} }
//TODO move to control or player? //TODO move to control or player?
public static void placeBlock(int x, int y, Block result, int rotation){ public void placeBlock(int x, int y, Block result, int rotation){
Tile tile = tile(x, y); Tile tile = tile(x, y);
//just in case //just in case
@@ -239,10 +250,10 @@ public class World{
} }
//TODO move this to control? //TODO move this to control?
public static boolean validPlace(int x, int y, Block type){ public boolean validPlace(int x, int y, Block type){
for(Tile spawn : spawnpoints){ for(SpawnPoint spawn : control.getSpawnPoints()){
if(Vector2.dst(x * tilesize, y * tilesize, spawn.worldx(), spawn.worldy()) < enemyspawnspace){ if(Vector2.dst(x * tilesize, y * tilesize, spawn.start.worldx(), spawn.start.worldy()) < enemyspawnspace){
return false; return false;
} }
} }
@@ -270,7 +281,8 @@ public class World{
int rotation = Vars.control.getTutorial().getPlaceRotation(); int rotation = Vars.control.getTutorial().getPlaceRotation();
Block block = Vars.control.getTutorial().getPlaceBlock(); Block block = Vars.control.getTutorial().getPlaceBlock();
if(type != block || point.x != x - core.x || point.y != y - core.y || (rotation != -1 && rotation != Vars.player.rotation)){ if(type != block || point.x != x - control.getCore().x || point.y != y - control.getCore().y
|| (rotation != -1 && rotation != Vars.player.rotation)){
return false; return false;
} }
}else if(Vars.control.getTutorial().active()){ }else if(Vars.control.getTutorial().active()){
@@ -298,7 +310,7 @@ public class World{
} }
} }
public static void breakBlock(int x, int y){ public void breakBlock(int x, int y){
Tile tile = tile(x, y); Tile tile = tile(x, y);
if(tile == null) return; if(tile == null) return;
@@ -324,7 +336,7 @@ public class World{
} }
} }
public static boolean validBreak(int x, int y){ public boolean validBreak(int x, int y){
Tile tile = tile(x, y); Tile tile = tile(x, y);
if(tile == null || tile.block() == ProductionBlocks.core) return false; if(tile == null || tile.block() == ProductionBlocks.core) return false;
@@ -340,7 +352,8 @@ public class World{
int rotation = Vars.control.getTutorial().getPlaceRotation(); int rotation = Vars.control.getTutorial().getPlaceRotation();
Block block = Vars.control.getTutorial().getPlaceBlock(); Block block = Vars.control.getTutorial().getPlaceBlock();
if(block != Blocks.air || point.x != x - core.x || point.y != y - core.y || (rotation != -1 && rotation != Vars.player.rotation)){ if(block != Blocks.air || point.x != x - control.getCore().x || point.y != y - control.getCore().y
|| (rotation != -1 && rotation != Vars.player.rotation)){
return false; return false;
} }
}else{ }else{
@@ -351,11 +364,7 @@ public class World{
return tile.breakable(); return tile.breakable();
} }
//public static Rectangle getCollider(int x, int y){ public TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){
// return Rectangle.tmp2.setSize(tilesize).setCenter(x * tilesize, y * tilesize);
//}
public static TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){
Entity closest = null; Entity closest = null;
float dst = 0; float dst = 0;
@@ -389,21 +398,11 @@ public class World{
return (TileEntity) closest; return (TileEntity) closest;
} }
public static void disposeMaps(){
for(Pixmap pixmap : mapPixmaps){
pixmap.dispose();
}
for(Texture texture : mapTextures){
texture.dispose();
}
}
/** /**
* Input is in block coordinates, not world coordinates. * Input is in block coordinates, not world coordinates.
* @return null if no collisions found, block position otherwise. * @return null if no collisions found, block position otherwise.
*/ */
public static Vector2 raycast(int x0f, int y0f, int x1f, int y1f){ public Vector2 raycast(int x0f, int y0f, int x1f, int y1f){
int x0 = (int)x0f; int x0 = (int)x0f;
int y0 = (int)y0f; int y0 = (int)y0f;
int x1 = (int)x1f; int x1 = (int)x1f;
@@ -31,20 +31,20 @@ public class Blocks{
blockpart = new BlockPart(), blockpart = new BlockPart(),
deepwater = new Floor("deepwater"){{ deepwater = new Floor("deepwater"){{
vary = false; variants = 0;
solid = true; solid = true;
liquidDrop = Liquid.water; liquidDrop = Liquid.water;
}}, }},
water = new Floor("water"){{ water = new Floor("water"){{
vary = false; variants = 0;
solid = true; solid = true;
liquidDrop = Liquid.water; liquidDrop = Liquid.water;
}}, }},
lava = new Floor("lava"){ lava = new Floor("lava"){
{ {
vary = false; variants = 0;
solid = true; solid = true;
liquidDrop = Liquid.lava; liquidDrop = Liquid.lava;
} }
@@ -63,7 +63,7 @@ public class Blocks{
oil = new Floor("oil"){ oil = new Floor("oil"){
{ {
vary = false; variants = 0;
solid = true; solid = true;
liquidDrop = Liquid.oil; liquidDrop = Liquid.oil;
} }
@@ -80,6 +80,10 @@ public class Blocks{
drops = new ItemStack(Item.stone, 1); drops = new ItemStack(Item.stone, 1);
}}, }},
blackstone = new Floor("blackstone"){{
drops = new ItemStack(Item.stone, 1);
}},
iron = new Floor("iron"){{ iron = new Floor("iron"){{
drops = new ItemStack(Item.iron, 1); drops = new ItemStack(Item.iron, 1);
}}, }},
@@ -100,24 +104,38 @@ public class Blocks{
grass = new Floor("grass"), grass = new Floor("grass"),
stoneblock = new Block("stoneblock"){{ stoneblock = new Block("stoneblock"){
{
solid = true; solid = true;
}}, variants = 3;
}
stoneblock2 = new Block("stoneblock2"){{ @Override
solid = true; public void draw(Tile tile){
}}, // Draw.colorl(0.9f + Mathf.randomSeed(tile.id()*9999, 1, 10)/10f / 10f);
super.draw(tile);
// Draw.color();
}
},
stoneblock3 = new Block("stoneblock3"){{ blackstoneblock = new Block("blackstoneblock"){
{
solid = true; solid = true;
}}, variants = 3;
}
@Override
public void draw(Tile tile){
// float f = 0.15f;
// Draw.colorl(1f - f + Mathf.randomSeed(tile.id()*9999, 1, 10)/10f / (1f / f));
super.draw(tile);
// Draw.color();
}
},
grassblock = new Block("grassblock"){{ grassblock = new Block("grassblock"){{
solid = true; solid = true;
}}, variants = 2;
grassblock2 = new Block("grassblock2"){{
solid = true;
}}, }},
mossblock = new Block("mossblock"){{ mossblock = new Block("mossblock"){{
@@ -134,13 +152,17 @@ public class Blocks{
shadow = "rockshadow"; shadow = "rockshadow";
breakable = true; breakable = true;
breaktime = 15; breaktime = 15;
variants = 2;
varyShadow = true;
drops = new ItemStack(Item.stone, 3); drops = new ItemStack(Item.stone, 3);
}}, }},
rock2 = new Block("rock2"){{ blackrock = new Block("blackrock"){{
shadow = "rock2shadow"; shadow = "blackrockshadow";
breakable = true; breakable = true;
breaktime = 15; breaktime = 15;
variants = 1;
varyShadow = true;
drops = new ItemStack(Item.stone, 3); drops = new ItemStack(Item.stone, 3);
}}, }},
@@ -0,0 +1,31 @@
package io.anuke.mindustry.world.blocks.types;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf;
public class BlendBlock extends Block{
protected String edge;
protected Predicate<Block> blend = block -> block == this;
public BlendBlock(String name) {
super(name);
edge = name + "-edge";
}
@Override
public void draw(Tile tile){
Draw.rect(variants > 0 ? (name() + Mathf.randomSeed(tile.id(), 1, variants)) : name(),
tile.worldx(), tile.worldy());
Tile[] nearby = tile.getNearby();
for(int i = 0; i < 4; i ++){
if(nearby[i] != null && !blend.test(nearby[i].block())){
Draw.rect(edge + "-" + i, tile.worldx(), tile.worldy());
}
}
}
}
@@ -3,9 +3,9 @@ package io.anuke.mindustry.world.blocks.types;
import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.graphics.Caches; import io.anuke.ucore.graphics.Caches;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -14,20 +14,21 @@ public class Floor extends Block{
public Floor(String name) { public Floor(String name) {
super(name); super(name);
variants = 3;
} }
@Override @Override
public void drawCache(Tile tile){ public void drawCache(Tile tile){
MathUtils.random.setSeed(tile.id()); MathUtils.random.setSeed(tile.id());
Caches.draw(vary ? (name() + MathUtils.random(1, 3)) : name(), tile.worldx(), tile.worldy()); Caches.draw(variants > 0 ? (name() + MathUtils.random(1, variants)) : name(), tile.worldx(), tile.worldy());
for(int dx = -1; dx <= 1; dx ++){ for(int dx = -1; dx <= 1; dx ++){
for(int dy = -1; dy <= 1; dy ++){ for(int dy = -1; dy <= 1; dy ++){
if(dx == 0 && dy == 0) continue; if(dx == 0 && dy == 0) continue;
Tile other = World.tile(tile.x+dx, tile.y+dy); Tile other = Vars.world.tile(tile.x+dx, tile.y+dy);
if(other == null) continue; if(other == null) continue;
@@ -0,0 +1,11 @@
package io.anuke.mindustry.world.blocks.types.defense;
import io.anuke.mindustry.world.blocks.types.Wall;
public class Door extends Wall{
public Door(String name) {
super(name);
}
}
@@ -4,8 +4,8 @@ import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.graphics.Hue;
@@ -39,7 +39,7 @@ public class RepairTurret extends PowerTurret{
TurretEntity entity = tile.entity(); TurretEntity entity = tile.entity();
if(Timers.get(entity, "blocktarget", targetInterval)){ if(Timers.get(entity, "blocktarget", targetInterval)){
entity.blockTarget = World.findTileTarget(tile.worldx(), tile.worldy(), tile, range, true); entity.blockTarget = Vars.world.findTileTarget(tile.worldx(), tile.worldy(), tile, range, true);
} }
if(entity.blockTarget != null){ if(entity.blockTarget != null){
@@ -8,7 +8,6 @@ import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.effect.Fx; import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.World;
import io.anuke.mindustry.world.blocks.types.PowerAcceptor; import io.anuke.mindustry.world.blocks.types.PowerAcceptor;
import io.anuke.mindustry.world.blocks.types.PowerBlock; import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
@@ -140,7 +139,7 @@ public class Generator extends PowerBlock{
int i = 0; int i = 0;
for(i = 1; i < laserRange; i++){ for(i = 1; i < laserRange; i++){
Tile other = World.tile(tile.x + i * point.x, tile.y + i * point.y); Tile other = Vars.world.tile(tile.x + i * point.x, tile.y + i * point.y);
if(other != null && other.block() instanceof PowerAcceptor){ if(other != null && other.block() instanceof PowerAcceptor){
Tile linked = other.getLinked(); Tile linked = other.getLinked();
@@ -173,7 +172,7 @@ public class Generator extends PowerBlock{
} }
if(Vector2.dst(x, y, 0, 0) < powerRange){ if(Vector2.dst(x, y, 0, 0) < powerRange){
Tile dest = World.tile(tile.x + x, tile.y + y); Tile dest = Vars.world.tile(tile.x + x, tile.y + y);
if(dest != null && dest.block() instanceof PowerAcceptor && ((PowerAcceptor) dest.block()).acceptsPower(dest)){ if(dest != null && dest.block() instanceof PowerAcceptor && ((PowerAcceptor) dest.block()).acceptsPower(dest)){
if(i == 1){ if(i == 1){
PowerAcceptor block = (PowerAcceptor) dest.block(); PowerAcceptor block = (PowerAcceptor) dest.block();