Documentation, cleanup, incremental resource usage, core seeking

This commit is contained in:
Anuken
2018-05-20 20:41:10 -04:00
parent c1a5482ad2
commit 26e1ad51ff
127 changed files with 368 additions and 1028 deletions

View File

@@ -1,29 +0,0 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.ai.pfa.Connection;
import com.badlogic.gdx.ai.pfa.HierarchicalGraph;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.world.Tile;
public class HGraph implements HierarchicalGraph<Tile> {
@Override
public int getLevelCount() {
return 0;
}
@Override
public void setLevel(int level) {
}
@Override
public Tile convertNodeBetweenLevels(int inputLevel, Tile node, int outputLevel) {
return null;
}
@Override
public Array<Connection<Tile>> getConnections(Tile fromNode) {
return null;
}
}

View File

@@ -1,69 +0,0 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.ai.pfa.Heuristic;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.function.Predicate;
import static io.anuke.mindustry.Vars.tilesize;
public class Heuristics {
/**How many times more it costs to go through a destructible block than an empty block.*/
static final float solidMultiplier = 5f;
/**How many times more it costs to go through a tile that touches a solid block.*/
static final float occludedMultiplier = 5f;
/**Calculates the fastest path. No priorities, just avoids solid blocks.*/
public static class FastestHeuristic implements Heuristic<Tile> {
@Override
public float estimate(Tile node, Tile other){
//Get Manhattan distance cost
float cost = Math.abs(node.worldx() - other.worldx()) + Math.abs(node.worldy() - other.worldy());
//If either one of the tiles is a breakable solid block (that is, it's player-made),
//increase the cost by the tilesize times the solid block multiplier
//Also add the block health, so blocks with more health cost more to traverse
if(node.breakable() && node.block().solid) cost += tilesize* solidMultiplier + node.block().health;
if(other.breakable() && other.block().solid) cost += tilesize* solidMultiplier + other.block().health;
//if this block has solid blocks near it, increase the cost, as we don't want enemies hugging walls
//if(node.occluded) cost += tilesize*occludedMultiplier;
return cost;
}
}
/**Calculates the fastest and most destructive path based on a block predicate.*/
public static class DestrutiveHeuristic implements Heuristic<Tile> {
/**Should return whether a block if "free", e.g. whether it's an important target*/
private final Predicate<Block> frees;
public DestrutiveHeuristic(Predicate<Block> frees){
this.frees = frees;
}
@Override
public float estimate(Tile node, Tile other){
//Get Manhattan distance cost
float cost = Math.abs(node.worldx() - other.worldx()) + Math.abs(node.worldy() - other.worldy());
//If either one of the tiles is a breakable solid block (that is, it's player-made),
//increase the cost by the tilesize times the solid block multiplier
//Also add the block health, so blocks with more health cost more to traverse
if(node.breakable() && node.block().solid) cost += tilesize* solidMultiplier + node.block().health;
if(other.breakable() && other.block().solid) cost += tilesize* solidMultiplier + other.block().health;
//if this block has solid blocks near it, increase the cost, as we don't want enemies hugging walls
//if(node.occluded) cost += tilesize*occludedMultiplier;
if(other.getLinked() != null) other = other.getLinked();
if(node.getLinked() != null) node = node.getLinked();
//check if it's free
if(frees.test(other.block()) || frees.test(node.block())) cost = 0;
return cost;
}
}
}

View File

@@ -1,12 +0,0 @@
package io.anuke.mindustry.ai;
/**An interface for an indexed graph that doesn't use allocations for connections.*/
public interface OptimizedGraph<N>{
/**This is used in the same way as getConnections(), but does not use Connection objects.*/
N[] connectionsOf(N node);
/** Returns the unique index of the given node.
* @param node the node whose index will be returned
* @return the unique index of the given node. */
int getIndex (N node);
}

View File

@@ -1,378 +0,0 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.ai.pfa.GraphPath;
import com.badlogic.gdx.ai.pfa.PathFinderQueue;
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
import com.badlogic.gdx.utils.BinaryHeap;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
/**An IndexedAStarPathfinder that uses an OptimizedGraph, and therefore has less allocations.*/
public class OptimizedPathFinder {
IntMap<NodeRecord> records = new IntMap<>();
BinaryHeap<NodeRecord> openList;
NodeRecord current;
private int searchId;
private Tile end;
private static final byte UNVISITED = 0;
private static final byte OPEN = 1;
private static final byte CLOSED = 2;
private static final boolean debug = false;
public OptimizedPathFinder() {
this.openList = new BinaryHeap<>();
}
public boolean searchNodePath(Tile startNode, Tile endNode, GraphPath<Tile> outPath) {
this.end = endNode;
// Perform AStar
boolean found = search(startNode, endNode);
if (found) {
// Create a path made of nodes
generateNodePath(startNode, outPath);
}
return found;
}
protected boolean search(Tile startNode, Tile endNode) {
initSearch(startNode, endNode);
// Iterate through processing each node
do {
// Retrieve the node with smallest estimated total cost from the open list
current = openList.pop();
current.category = CLOSED;
// Terminate if we reached the goal node
if (current.node == endNode) return true;
visitChildren(endNode);
} while (openList.size > 0);
// We've run out of nodes without finding the goal, so there's no solution
return false;
}
public boolean search(PathFinderRequest<Tile> request, long timeToRun) {
long lastTime = TimeUtils.nanoTime();
// We have to initialize the search if the status has just changed
if (request.statusChanged) {
initSearch(request.startNode, request.endNode);
request.statusChanged = false;
}
// Iterate through processing each node
do {
// Check the available time
long currentTime = TimeUtils.nanoTime();
timeToRun -= currentTime - lastTime;
if (timeToRun <= PathFinderQueue.TIME_TOLERANCE) return false;
// Retrieve the node with smallest estimated total cost from the open list
current = openList.pop();
current.category = CLOSED;
// Terminate if we reached the goal node; we've found a path.
if (current.node == request.endNode) {
request.pathFound = true;
generateNodePath(request.startNode, request.resultPath);
return true;
}
// Visit current node's children
visitChildren(request.endNode);
// Store the current time
lastTime = currentTime;
} while (openList.size > 0);
// The open list is empty and we've not found a path.
request.pathFound = false;
return true;
}
protected void initSearch(Tile startNode, Tile endNode) {
// Increment the search id
if (++searchId < 0) searchId = 1;
// Initialize the open list
openList.clear();
// Initialize the record for the start node and add it to the open list
NodeRecord startRecord = getNodeRecord(startNode);
startRecord.node = startNode;
//startRecord.connection = null;
startRecord.costSoFar = 0;
addToOpenList(startRecord, estimate(startNode, endNode));
current = null;
}
protected void visitChildren(Tile endNode) {
if(debug) Effects.effect(Fx.node3, current.node.worldx(), current.node.worldy());
nodes(current.node, node -> {
float addCost = estimate(current.node, node);
float nodeCost = current.costSoFar + addCost;
float nodeHeuristic;
NodeRecord nodeRecord = getNodeRecord(node);
if (nodeRecord.category == CLOSED) { // The node is closed
// If we didn't find a shorter route, skip
if (nodeRecord.costSoFar <= nodeCost){
return;
}
// We can use the node's old cost values to calculate its heuristic
// without calling the possibly expensive heuristic function
nodeHeuristic = nodeRecord.getEstimatedTotalCost() - nodeRecord.costSoFar;
} else if (nodeRecord.category == OPEN) { // The node is open
//If our route is no better, then skip
if (nodeRecord.costSoFar <= nodeCost){
return;
}
// Remove it from the open list (it will be re-added with the new cost)
openList.remove(nodeRecord);
// We can use the node's old cost values to calculate its heuristic
// without calling the possibly expensive heuristic function
nodeHeuristic = nodeRecord.getEstimatedTotalCost() - nodeRecord.costSoFar;
} else { // the node is unvisited
// We'll need to calculate the heuristic value using the function,
// since we don't have a node record with a previously calculated value
nodeHeuristic = estimate(node, endNode);
}
// Update node record's cost and connection
nodeRecord.costSoFar = nodeCost;
nodeRecord.from = current.node;
// Add it to the open list with the estimated total cost
addToOpenList(nodeRecord, nodeCost + nodeHeuristic);
});
}
protected void nodes(Tile current, Consumer<Tile> cons){
if(obstacle(current)) return;
for(int i = 0; i < 4; i ++){
Tile n = current.getNearby(i);
if(!obstacle(n)) cons.accept(n);
}
}
protected void jps(Tile current, int direction, Tile end, Consumer<Tile> cons){
if(obstacle(current)) return; //skip solid or off-the-screen stuff
//if there's no start point, scan everything.
if(direction == -1){
for(int i = 0; i < 8; i ++){
jps(current.getNearby(Geometry.d8[i]), i, end, cons);
}
return;
}
if(direction % 2 == 0){
//forced neighbor in the straight pattern
if(obstacle(rel(current, direction + 2)) && !obstacle(rel(current, direction + 1))){
cons.accept(rel(current, direction + 1));
}
if(obstacle(rel(current, direction - 2)) && !obstacle(rel(current, direction - 1))){
cons.accept(rel(current, direction - 1));
}
}else{ //moving diagonal
//forced neighbor in the diagonal pattern
if(obstacle(rel(current, direction + 3)) && !obstacle(rel(current, direction + 2)) && !obstacle(rel(current, direction -2))) {
cons.accept(rel(current, direction + 2));
}
if(obstacle(rel(current, direction - 3)) && !obstacle(rel(current, direction - 2))&& !obstacle(rel(current, direction + 2))){
cons.accept(rel(current, direction - 2));
}
}
while(!obstacle(current) && !trap(current, direction)){
if(debug) Effects.effect(Fx.node1, current.worldx(), current.worldy());
//moving straight
if(direction % 2 == 0){
Tile sf = scanDir(rel(current, direction), end, direction); //check if there's anything of interest going straight
if(sf != null){ //if there is, jump to that location immediately and stop. else, nothing must be there, end.
cons.accept(sf);
}
return;
}else{ //moving diagonal
Tile sl = scanDir(rel(current, Mathf.mod(direction - 1, 8)), end, Mathf.mod(direction - 1, 8));
if(sl != null){
cons.accept(sl);
}
Tile sr = scanDir(rel(current, Mathf.mod(direction + 1, 8)), end, Mathf.mod(direction + 1, 8));
if(sr != null){
cons.accept(sr);
}
Tile sf = scanDir(rel(current, direction), end, direction);
if(sf != null){
cons.accept(sf);
return;
}
}
if(current == end){
cons.accept(end);
return;
}
current = rel(current, direction);
}
}
protected boolean trap(Tile tile, int direction){
return direction % 2 == 1 && obstacle(rel(tile, direction - 1)) && obstacle(rel(tile, direction + 1));
}
protected Tile scanDir(Tile tile, Tile end, int direction){
while(!obstacle(tile)){
if(debug) Effects.effect(Fx.node2, tile.worldx(), tile.worldy());
if(tile == end) return tile;
if(direction % 2 == 0){
//forced neighbor in the straight pattern
if((obstacle(rel(tile, direction + 2)) && !obstacle(rel(tile, direction + 1))) ||
(obstacle(rel(tile, direction - 2)) && !obstacle(rel(tile, direction - 1)))){
//Log.info("Found forced linear neighbor {0} {1} // {2}", tile.x, tile.y, direction);
if(debug) Effects.effect(Fx.node4, tile.worldx(), tile.worldy());
return tile;
}
}else{ //moving diagonal
//forced neighbor in the diagonal pattern, end here
if((obstacle(rel(tile, direction + 3)) && !obstacle(rel(tile, direction + 2)) && !obstacle(rel(tile, direction - 2))) ||
(obstacle(rel(tile, direction - 3)) && !obstacle(rel(tile, direction - 2)) && !obstacle(rel(tile, direction + 2)))) {
if(debug) Effects.effect(Fx.node4, tile.worldx(), tile.worldy());
//Log.info("Found forced diagonal neighbor {0} {1} // {2}", tile.x, tile.y, direction);
return tile;
}else{
return null;
}
}
Tile next = rel(tile, direction);
if(obstacle(next)) break;
tile = next;
}
return null;
}
protected Tile rel(Tile tile, int i){
return tile.getNearby(Geometry.d8[Mathf.mod(i, 8)]);
}
protected boolean obstacle(Tile tile){
return tile == null || (tile.solid() && end.target() != tile && tile.target() != end);
}
protected float estimate(Tile tile, Tile other){
return Math.abs(tile.worldx() - other.worldx()) + Math.abs(tile.worldy() - other.worldy()) +0;
// (tile.occluded ? tilesize : 0) + (other.occluded ? tilesize : 0);
}
protected int relDirection(Tile from, Tile current){
if(from.y == current.y && from.x > current.x) return 0;
if(from.y == current.y && from.x < current.x) return 4;
if(from.x == current.x && from.y > current.y) return 2;
if(from.x == current.x && from.y < current.y) return 6;
if(from.y > current.y && from.x > current.x) return 1;
if(from.y < current.y && from.x < current.x) return 5;
if(from.x > current.x && from.y < current.y) return 7;
if(from.x < current.x && from.y > current.y) return 3;
return -1;
}
protected void generateNodePath(Tile startNode, GraphPath<Tile> outPath) {
// Work back along the path, accumulating nodes
// outPath.clear();
while (current.from != null) {
outPath.add(current.node);
current = records.get(indexOf(current.from));
}
outPath.add(startNode);
// Reverse the path
outPath.reverse();
}
protected void addToOpenList(NodeRecord nodeRecord, float estimatedTotalCost) {
openList.add(nodeRecord, estimatedTotalCost);
nodeRecord.category = OPEN;
}
protected NodeRecord getNodeRecord(Tile node) {
if(!records.containsKey(indexOf(node))){
NodeRecord record = new NodeRecord();
record.node = node;
record.searchId = searchId;
records.put(indexOf(node), record);
return record;
}else{
NodeRecord record = records.get(indexOf(node));
if(record.searchId != searchId){
record.category = UNVISITED;
record.searchId = searchId;
}
return record;
}
}
private int indexOf(Tile node){
return node.packedPosition();
}
static class NodeRecord extends BinaryHeap.Node {
Tile node;
Tile from;
float costSoFar;
byte category;
int searchId;
public NodeRecord() {
super(0);
}
public float getEstimatedTotalCost() {
return getValue();
}
}
}

View File

@@ -1,87 +0,0 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.ai.utils.Collision;
import com.badlogic.gdx.ai.utils.Ray;
import com.badlogic.gdx.ai.utils.RaycastCollisionDetector;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class Raycaster implements RaycastCollisionDetector<Vector2>{
private boolean found = false;
@Override
public boolean collides(Ray<Vector2> ray){
found = false;
Geometry.iterateLine(0f, ray.start.x, ray.start.y, ray.end.x, ray.end.y, tilesize, (x, y)->{
if(solid(x, y)){
found = true;
return;
}
});
return found;
}
@Override
public boolean findCollision(Collision<Vector2> collision, Ray<Vector2> ray){
Vector2 v = vectorCast(ray.start.x, ray.start.y, ray.end.x, ray.end.y);
if(v == null) return false;
collision.point = v;
collision.normal = v.nor();
return true;
}
Vector2 vectorCast(float x0f, float y0f, float x1f, float y1f){
int x0 = (int)x0f;
int y0 = (int)y0f;
int x1 = (int)x1f;
int y1 = (int)y1f;
int dx = Math.abs(x1 - x0);
int dy = Math.abs(y1 - y0);
int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;
int err = dx - dy;
int e2;
while(true){
if(solid(x0, y0)){
return new Vector2(x0, y0);
}
if(x0 == x1 && y0 == y1) break;
e2 = 2 * err;
if(e2 > -dy){
err = err - dy;
x0 = x0 + sx;
}
if(e2 < dx){
err = err + dx;
y0 = y0 + sy;
}
}
return null;
}
private boolean solid(float x, float y){
Tile tile = world.tile(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize));
if(tile == null || tile.solid()) return true;
for(int i = 0; i < 4; i ++){
Tile near = tile.getNearby(i);
if(near == null || near.solid()) return true;
}
return false;
}
}

View File

@@ -1,32 +0,0 @@
package io.anuke.mindustry.ai;
import com.badlogic.gdx.ai.pfa.DefaultGraphPath;
import com.badlogic.gdx.ai.pfa.SmoothableGraphPath;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.world.Tile;
public class SmoothGraphPath extends DefaultGraphPath<Tile> implements SmoothableGraphPath<Tile, Vector2>{
private Vector2 vector = new Vector2();
@Override
public Vector2 getNodePosition(int index){
Tile tile = nodes.get(index);
return vector.set(tile.worldx(), tile.worldy());
}
@Override
public void swapNodes(int index1, int index2){
nodes.swap(index1, index2);
}
@Override
public void truncatePath(int newLength){
nodes.truncate(newLength);
}
@Override
public void add (Tile node) {
nodes.add(node);
}
}

View File

@@ -1,25 +0,0 @@
package io.anuke.mindustry.ai;
import io.anuke.mindustry.world.Tile;
/**Tilegraph that ignores player-made tiles.*/
public class TileGraph implements OptimizedGraph<Tile> {
private Tile[] tiles = new Tile[4];
/**Used for the OptimizedPathFinder implementation.*/
@Override
public Tile[] connectionsOf(Tile node){
Tile[] nodes = node.getNearby(tiles);
for(int i = 0; i < 4; i ++){
if(nodes[i] != null && !nodes[i].passable()){
nodes[i] = null;
}
}
return nodes;
}
@Override
public int getIndex(Tile node){
return node.packedPosition();
}
}

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.content;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
public class AmmoTypes {
public static final AmmoType

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.content;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
public class Items {
public static final Item

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.content;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
public class Liquids {

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.resource.Mech;
import io.anuke.mindustry.type.Mech;
public class Mechs {
public static final Mech

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.content.blocks.*;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Recipe;
import static io.anuke.mindustry.resource.Section.*;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import static io.anuke.mindustry.type.Section.*;
public class Recipes {
static {

View File

@@ -2,9 +2,9 @@ package io.anuke.mindustry.content;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectMap.Entries;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.ucore.util.Mathf;
public class UpgradeRecipes {

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.type.Weapon;
public class Weapons {
public static final Weapon

View File

@@ -5,7 +5,7 @@ import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.graphics.CacheLayer;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.*;

View File

@@ -4,8 +4,8 @@ import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.production.*;

View File

@@ -3,8 +3,8 @@ package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.units.RepairPoint;
import io.anuke.mindustry.world.blocks.types.units.ResupplyPoint;

View File

@@ -3,7 +3,7 @@ package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.mindustry.world.blocks.types.defense.turrets.*;

View File

@@ -14,7 +14,7 @@ import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.effect.Lightning;
import io.anuke.mindustry.entities.effect.Puddle;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;

View File

@@ -4,7 +4,7 @@ import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.blocks.*;
import io.anuke.mindustry.entities.StatusEffect;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.util.Log;
@@ -59,8 +59,8 @@ public class ContentLoader {
Log.info("--- CONTENT INFO ---");
Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nStatus effects loaded: {6}\nRecipes loaded: {7}\nTotal content classes: {8}",
Block.getAllBlocks().size, Item.getAllItems().size, Liquid.getAllLiquids().size,
Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, Recipe.getAllRecipes().size, content.length);
Block.getAllBlocks().size, io.anuke.mindustry.type.Item.getAllItems().size, Liquid.getAllLiquids().size,
io.anuke.mindustry.type.Mech.getAllUpgrades().size, UnitType.getAllTypes().size, io.anuke.mindustry.type.AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, io.anuke.mindustry.type.Recipe.getAllRecipes().size, content.length);
Log.info("-------------------");
}

View File

@@ -18,7 +18,7 @@ import io.anuke.mindustry.io.Map;
import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.io.Saves;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.input.InputProxy;

View File

@@ -11,6 +11,8 @@ import io.anuke.mindustry.game.TeamInfo;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
@@ -42,6 +44,14 @@ public class Logic extends Module {
public void play(){
state.wavetime = wavespace * state.difficulty.timeScaling * 2;
for(Tile tile : state.teams.get(players[0].team).cores){
for(Item item : Item.getAllItems()){
if(item.material){
tile.entity.items.addItem(item, 1000);
}
}
}
Events.fire(PlayEvent.class);
}

View File

@@ -13,9 +13,9 @@ import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.NetworkIO;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Build;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;

View File

@@ -7,7 +7,7 @@ import io.anuke.mindustry.net.Packets.BlockConfigPacket;
import io.anuke.mindustry.net.Packets.BlockTapPacket;
import io.anuke.mindustry.net.Packets.ChatPacket;
import io.anuke.mindustry.net.Packets.WeaponSwitchPacket;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.modules.Module;

View File

@@ -16,9 +16,9 @@ import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Administration.PlayerInfo;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Build;
import io.anuke.mindustry.world.Tile;

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.Queue;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.Build;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.BuildBlock;
@@ -76,10 +76,17 @@ public interface BlockBuilder {
getPlaceQueue().removeFirst();
}
}else{
TileEntity core = unit.getClosestCore();
//if there is no core to build with, stop building!
if(core == null){
return;
}
//otherwise, update it.
BuildEntity entity = tile.entity();
entity.progress += 1f / entity.recipe.cost;
entity.addProgress(core.items, 1f / entity.recipe.cost);
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
}
}

View File

@@ -1,62 +0,0 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.Item;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.TimedEntity;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
/**This class should not be used anymore, as the animation does not fit the style well.*/
@Deprecated
public class ItemAnimationEffect extends TimedEntity {
private static final float size = 5f;
private final Vector2 vec = new Vector2();
private final Vector2 from = new Vector2();
private final Vector2 to = new Vector2();
private final Item item;
private final Callable removed;
public Interpolation interp = Interpolation.fade;
public float endSize = 0.9f;
public ItemAnimationEffect(Item item, float x, float y, float tox, float toy, Callable removed) {
this.x = x;
this.y = y;
this.item = item;
this.removed = removed;
from.set(x, y);
to.set(tox, toy);
lifetime = 40f;
}
@Override
public void removed() {
super.removed();
removed.run();
}
@Override
public void update() {
super.update();
vec.set(from).interpolate(to, fin(), interp);
x = vec.x;
y = vec.y;
}
@Override
public void draw() {
float s = size * (1f-Mathf.curve(fin(), endSize));
Draw.rect(item.region, x, y, s, s);
}
@Override
public <T extends Entity> T add() {
return super.add(Vars.effectGroup);
}
}

View File

@@ -0,0 +1,37 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.TimedEntity;
import io.anuke.ucore.function.Callable;
public class ItemTransfer extends TimedEntity {
public static void create(Item item, float fromx, float fromy, float tox, float toy, Callable done){
}
private ItemTransfer(){}
@Override
public void removed() {
super.removed();
}
@Override
public void update() {
super.update();
}
@Override
public void draw() {
}
@Override
public <T extends Entity> T add() {
return super.add(Vars.effectGroup);
}
}

View File

@@ -14,7 +14,10 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.*;
@@ -375,12 +378,12 @@ public class Player extends Unit implements BlockBuilder {
}
@Override
public boolean acceptsAmmo(Item item) {
public boolean acceptsAmmo(io.anuke.mindustry.type.Item item) {
return weapon.getAmmoType(item) != null && inventory.canAcceptAmmo(weapon.getAmmoType(item));
}
@Override
public void addAmmo(Item item) {
public void addAmmo(io.anuke.mindustry.type.Item item) {
inventory.addAmmo(weapon.getAmmoType(item));
}

View File

@@ -8,10 +8,13 @@ public class StatusEffect{
private static final Array<StatusEffect> array = new Array<>();
private static int lastid;
/**Duration of this status effect in ticks at maximum power.*/
public final float baseDuration;
public final int id;
/**Set of 'opposite' effects, which will decrease the duration of this effect when applied.*/
protected ObjectSet<StatusEffect> opposites = new ObjectSet<>();
/**The strength of time decrease when met with an opposite effect, as a fraction of the other's duration.*/
protected float oppositeScale = 0.5f;
public StatusEffect(float baseDuration){

View File

@@ -115,7 +115,6 @@ public abstract class SyncEntity extends DestructibleEntity{
}
public void update(){
//TODO prevent rubberbanding from getting too bad, clamp values?
time += 1f / spacing * Math.min(Timers.delta(), 1f);

View File

@@ -3,12 +3,14 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import java.io.DataInputStream;
@@ -76,6 +78,21 @@ public abstract class Unit extends SyncEntity implements SerializableEntity {
this.status.set(StatusEffect.getByID(effect), etime);
}
public TileEntity getClosestCore(){
if(state.teams.has(team)){
TeamData data = state.teams.get(team);
Tile tile = Geometry.findClosest(x, y, data.cores);
if(tile == null){
return null;
}else{
return tile.entity;
}
}else{
return null;
}
}
public Floor getFloorOn(){
Tile tile = world.tileWorld(x, y);
return (Floor)(tile == null || (tile.floor() == null) ? Blocks.defaultFloor : tile.floor());

View File

@@ -1,10 +1,10 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.resource.AmmoEntry;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.type.AmmoEntry;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import java.io.DataInputStream;
import java.io.DataOutputStream;

View File

@@ -19,14 +19,17 @@ import static io.anuke.mindustry.Vars.*;
public class Units {
private static Rectangle rect = new Rectangle();
/**Returns the neareset ally tile in a range.*/
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return findTile(x, y, range, tile -> !state.teams.areEnemies(team, tile.getTeam()) && pred.test(tile));
}
/**Returns the neareset enemy tile in a range.*/
public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return findTile(x, y, range, tile -> state.teams.areEnemies(team, tile.getTeam()) && pred.test(tile));
}
/**Returns the neareset tile entity in a range.*/
public static TileEntity findTile(float x, float y, float range, Predicate<Tile> pred){
Entity closest = null;
float dst = 0;

View File

@@ -1,4 +1,5 @@
package io.anuke.mindustry.entities.effect;
/**A flag interface for marking an effect as appearing below liquids.*/
public interface BelowLiquidEffect {
}

View File

@@ -23,10 +23,12 @@ import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.*;
/**Utility class for damaging in an area.*/
public class DamageArea{
private static Rectangle rect = new Rectangle();
private static Translator tr = new Translator();
/**Creates a dynamic explosion based on specified parameters.*/
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i ++){
int branches = 5 + Mathf.clamp((int)(power/30), 1, 20);

View File

@@ -9,6 +9,7 @@ import io.anuke.ucore.entities.EffectEntity;
import io.anuke.ucore.function.EffectRenderer;
import io.anuke.ucore.util.Mathf;
/**A ground effect contains an effect that is rendered on the ground layer as opposed to the top layer.*/
public class GroundEffectEntity extends EffectEntity {
private boolean once;
@@ -52,8 +53,12 @@ public class GroundEffectEntity extends EffectEntity {
once = false;
}
/**An effect that is rendered on the ground layer as opposed to the top layer.*/
public static class GroundEffect extends Effect{
/**How long this effect stays on the ground when static.*/
public final float staticLife;
/**If true, this effect will stop and lie on the ground for a specific duration,
* after its initial lifetime is over.*/
public final boolean isStatic;
public GroundEffect(float life, float staticLife, EffectRenderer draw) {

View File

@@ -31,6 +31,7 @@ public class Lightning extends TimedEntity implements Poolable{
public Color color = Palette.lancerLaser;
/**Create a lighting branch at a location. Use Team.none to damage everyone.*/
public static void create(Team team, Effect effect, Color color, float damage, float x, float y, float targetAngle, int length){
Lightning l = Pools.obtain(Lightning.class);

View File

@@ -15,7 +15,7 @@ import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.SerializableEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;

View File

@@ -7,10 +7,12 @@ import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.groundEffectGroup;
/**Class for creating block rubble on the ground.*/
public class Rubble extends TimedEntity implements BelowLiquidEffect{
private static final Color color = Color.valueOf("52504e");
private int size;
/**Creates a rubble effect at a position. Provide a block size to use.*/
public static void create(float x, float y, int size){
Rubble rubble = new Rubble();
rubble.size = size;

View File

@@ -14,6 +14,7 @@ import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.bulletGroup;
import static io.anuke.mindustry.Vars.shieldGroup;
//todo re-implement
public class Shield extends Entity{
public boolean active;
public boolean hitPlayers = false;

View File

@@ -5,7 +5,7 @@ import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;

View File

@@ -3,7 +3,7 @@ package io.anuke.mindustry.entities.units;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;

View File

@@ -1,13 +1,10 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor;

View File

@@ -8,8 +8,8 @@ import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Angles;

View File

@@ -1,96 +0,0 @@
package io.anuke.mindustry.game;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.Tile;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.debug;
import static io.anuke.mindustry.Vars.state;
public class Inventory {
private final int[] empty = new int[Item.getAllItems().size];
public void clearItems(){
Arrays.fill(items(), 0);
if(debug){
for(Item item : Item.getAllItems()){
if(item.material) items()[item.id] = 99999;
}
}else{
addItem(Items.iron, 40);
}
}
public void fill(){
Arrays.fill(items(), 999999999);
}
public int getAmount(Item item){
return items()[item.id];
}
public void addItem(Item item, int amount){
items()[item.id] += amount;
}
public boolean hasItems(ItemStack[] items){
for(ItemStack stack : items)
if(!hasItem(stack))
return false;
return true;
}
public boolean hasItems(ItemStack[] items, int scaling){
for(ItemStack stack : items)
if(!hasItem(stack.item, stack.amount * scaling))
return false;
return true;
}
public boolean hasItem(ItemStack req){
return items()[req.item.id] >= req.amount;
}
public boolean hasItem(Item item, int amount){
return items()[item.id] >= amount;
}
public void removeItem(ItemStack req){
items()[req.item.id] -= req.amount;
if(items()[req.item.id] < 0) items()[req.item.id] = 0; //prevents negative item glitches in multiplayer
}
public void removeItems(ItemStack... reqs){
for(ItemStack req : reqs)
removeItem(req);
}
public int[] writeItems(){
return items();
}
public int[] readItems(){
return items();
}
/*
public int[] getItems(){
updated = true;
return items();
}*/
private int[] items(){
ObjectSet<TeamData> set = state.teams.getTeams(true);
if(set.size == 0) return empty;
Array<Tile> tiles = set.first().cores;
if(tiles.size == 0) return empty;
return tiles.first().entity.items.items;
}
}

View File

@@ -18,10 +18,12 @@ public class TeamInfo {
private ObjectSet<TeamData> allTeamData = new ObjectSet<>();
private ObjectSet<Team> allTeams = new ObjectSet<>();
/**Returns all teams on a side.*/
public ObjectSet<TeamData> getTeams(boolean ally) {
return ally ? allyData : enemyData;
}
/**Returns all team data.*/
public ObjectSet<TeamData> getTeams() {
return allTeamData;
}

View File

@@ -1,26 +0,0 @@
package io.anuke.mindustry.game;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.resource.Weapon;
public class UpgradeInventory {
private final Array<Weapon> weapons = new Array<>();
public boolean hasWeapon(Weapon weapon){
return weapons.contains(weapon, true);
}
public void addWeapon(Weapon weapon){
weapons.add(weapon);
}
public Array<Weapon> getWeapons(){
return weapons;
}
public void reset(){
weapons.clear();
weapons.add(Weapons.blaster);
}
}

View File

@@ -7,7 +7,7 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.*;
import io.anuke.ucore.core.Inputs.DeviceType;
@@ -129,7 +129,7 @@ public class DesktopInput extends InputHandler{
droppingItem = false;
}
if(recipe == null && target != null && !ui.hasMouse() && Inputs.keyDown(section,"block_info") && target.block().isAccessible()){
if(recipe == null && target != null && !ui.hasMouse() && target.block().isAccessible()){
showCursor = true;
if(Inputs.keyTap(section,"select")){
canBeginShoot = false;

View File

@@ -2,13 +2,12 @@ package io.anuke.mindustry.input;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.entities.BlockBuilder.BuildRequest;
import io.anuke.mindustry.entities.ItemAnimationEffect;
import io.anuke.mindustry.entities.ItemTransfer;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.fragments.OverlayFragment;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Build;
@@ -107,7 +106,7 @@ public abstract class InputHandler extends InputAdapter{
Timers.run(i * 3, () -> {
tile.block().getStackOffset(stack.item, tile, stackTrns);
new ItemAnimationEffect(stack.item,
ItemTransfer.create(stack.item,
player.x + Angles.trnsx(rotation + 180f, backTrns), player.y + Angles.trnsy(rotation + 180f, backTrns),
tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y, () -> {
@@ -117,7 +116,7 @@ public abstract class InputHandler extends InputAdapter{
if(end && remaining[1] > 0) {
tile.block().handleStack(stack.item, remaining[1], tile, player);
}
}).add();
});
stack.amount -= removed;
remaining[0] -= removed;
@@ -130,6 +129,8 @@ public abstract class InputHandler extends InputAdapter{
});
}
}else{
//TODO create drop on the ground
/*
Vector2 vec = Graphics.screen(player.x, player.y);
if(vec.dst(Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY()) > playerSelectRange) {
@@ -140,15 +141,12 @@ public abstract class InputHandler extends InputAdapter{
float x = player.x + Angles.trnsx(rotation + 180f, backTrns),
y = player.y + Angles.trnsy(rotation + 180f, backTrns);
ItemAnimationEffect e = new ItemAnimationEffect(stack.item,
x, y, x + Mathf.range(20f), y + Mathf.range(20f), () -> {}).add();
e.interp = Interpolation.pow3Out;
e.endSize = 0.5f;
e.lifetime = 20;
ItemTransfer.create(stack.item,
x, y, x + Mathf.range(20f), y + Mathf.range(20f), () -> {});
});
}
player.inventory.clear();
}
}*/
}
}

View File

@@ -10,8 +10,8 @@ import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.*;

View File

@@ -7,7 +7,7 @@ import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.BlockPart;
import io.anuke.ucore.core.Timers;

View File

@@ -1,11 +0,0 @@
package io.anuke.mindustry.resource;
public class AmmoEntry{
public AmmoType type;
public int amount;
public AmmoEntry(AmmoType type, int amount) {
this.type = type;
this.amount = amount;
}
}

View File

@@ -0,0 +1,11 @@
package io.anuke.mindustry.type;
public class AmmoEntry{
public io.anuke.mindustry.type.AmmoType type;
public int amount;
public AmmoEntry(io.anuke.mindustry.type.AmmoType type, int amount) {
this.type = type;
this.amount = amount;
}
}

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.fx.Fx;
@@ -13,7 +13,7 @@ public class AmmoType {
/**The item used. Always null if liquid isn't.*/
public final Item item;
/**The liquid used. Always null if item isn't.*/
public final Liquid liquid;
public final io.anuke.mindustry.type.Liquid liquid;
/**The resulting bullet.*/
public final BulletType bullet;
/**For item ammo, this is amount given per ammo item.
@@ -48,7 +48,7 @@ public class AmmoType {
this.quantityMultiplier = multiplier;
}
public AmmoType(Liquid liquid, BulletType result, float multiplier){
public AmmoType(io.anuke.mindustry.type.Liquid liquid, BulletType result, float multiplier){
this.item = null;
this.liquid = liquid;
this.bullet = result;

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

View File

@@ -1,10 +1,10 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
public class ItemStack{
public Item item;
public io.anuke.mindustry.type.Item item;
public int amount;
public ItemStack(Item item, int amount){
public ItemStack(io.anuke.mindustry.type.Item item, int amount){
this.item = item;
this.amount = amount;
}

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
public class Mech extends Upgrade{
public class Mech extends io.anuke.mindustry.type.Upgrade {
public boolean flying;
public float mass = 1f;

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
@@ -11,20 +11,20 @@ public class Recipe {
public final int id;
public final Block result;
public final ItemStack[] requirements;
public final Section section;
public final io.anuke.mindustry.type.ItemStack[] requirements;
public final io.anuke.mindustry.type.Section section;
public final float cost;
public boolean desktopOnly = false, debugOnly = false;
public Recipe(Section section, Block result, ItemStack... requirements){
public Recipe(io.anuke.mindustry.type.Section section, Block result, io.anuke.mindustry.type.ItemStack... requirements){
this.id = lastid ++;
this.result = result;
this.requirements = requirements;
this.section = section;
float timeToPlace = 0f;
for(ItemStack stack : requirements){
for(io.anuke.mindustry.type.ItemStack stack : requirements){
timeToPlace += stack.amount * stack.item.cost;
}
@@ -44,7 +44,7 @@ public class Recipe {
return this;
}
public static Array<Recipe> getBySection(Section section, Array<Recipe> r){
public static Array<Recipe> getBySection(io.anuke.mindustry.type.Section section, Array<Recipe> r){
for(Recipe recipe : allRecipes){
if(recipe.section == section ) {
r.add(recipe);

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
public enum Section{
weapon, production, distribution, liquid, power, defense, crafting, units

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
import io.anuke.ucore.util.Bundles;

View File

@@ -1,4 +1,4 @@
package io.anuke.mindustry.resource;
package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.Vars;
@@ -16,11 +16,11 @@ import io.anuke.ucore.util.Bits;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
public class Weapon extends Upgrade{
public class Weapon extends io.anuke.mindustry.type.Upgrade {
/**minimum cursor distance from player, fixes 'cross-eyed' shooting.*/
protected static float minPlayerDist = 20f;
/**ammo type map. set with setAmmo()*/
protected ObjectMap<Item, AmmoType> ammoMap = new ObjectMap<>();
protected ObjectMap<io.anuke.mindustry.type.Item, io.anuke.mindustry.type.AmmoType> ammoMap = new ObjectMap<>();
/**shell ejection effect*/
protected Effect ejectEffect = Fx.none;
/**weapon reload in frames*/
@@ -83,12 +83,12 @@ public class Weapon extends Upgrade{
p.inventory.useAmmo();
}
public AmmoType getAmmoType(Item item){
public io.anuke.mindustry.type.AmmoType getAmmoType(io.anuke.mindustry.type.Item item){
return ammoMap.get(item);
}
protected void setAmmo(AmmoType... types){
for(AmmoType type : types){
protected void setAmmo(io.anuke.mindustry.type.AmmoType... types){
for(io.anuke.mindustry.type.AmmoType type : types){
ammoMap.put(type.item, type);
}
}
@@ -96,7 +96,7 @@ public class Weapon extends Upgrade{
void shootInternal(Player p, float x, float y, float rotation, boolean left){
Angles.shotgun(shots, spacing, rotation, f -> bullet(p, x, y, f + Mathf.range(inaccuracy)));
AmmoType type = p.inventory.getAmmo();
io.anuke.mindustry.type.AmmoType type = p.inventory.getAmmo();
tr.trns(rotation + 180f, type.recoil);

View File

@@ -0,0 +1,19 @@
package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
public class WeatherEvent {
private static final Array<WeatherEvent> all = new Array<>();
private static int lastid;
public final int id;
public final String name;
public WeatherEvent(String name){
this.id = lastid ++;
this.name = name;
all.add(this);
}
}

View File

@@ -9,7 +9,7 @@ import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.ui.ItemImage;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Core;

View File

@@ -9,10 +9,10 @@ import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.resource.Section;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.type.Section;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockStats;
@@ -62,7 +62,7 @@ public class BlocksFragment implements Fragment{
blocks = new table(){{
itemtable = new Table("button");
itemtable.setVisible(() -> input.recipe == null && !state.mode.infiniteResources);
itemtable.setVisible(() -> false);
itemtable.update(() -> {
int[] items = tmpItems;
for(int i = 0; i < items.length; i ++){

View File

@@ -4,8 +4,8 @@ import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.content.fx.EnvironmentFx;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.effect.Puddle;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;

View File

@@ -17,9 +17,9 @@ import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Liquid;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;

View File

@@ -7,7 +7,7 @@ import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.Entities;
@@ -26,7 +26,6 @@ public class Build {
if(tile == null) return null;
Block block = tile.isLinked() ? tile.getLinked().block() : tile.block();
Recipe result = Recipe.getByResult(block);
//todo add break results to core inventory
@@ -59,9 +58,7 @@ public class Build {
Block sub = Block.getByName("build" + result.size);
tile.setBlock(sub, rotation);
tile.<BuildEntity>entity().result = result;
tile.<BuildEntity>entity().recipe = recipe;
tile.<BuildEntity>entity().stacks = recipe.requirements;
tile.<BuildEntity>entity().set(recipe);
tile.setTeam(team);
if(result.isMultiblock()){

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world;
import com.badlogic.gdx.utils.NumberUtils;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Bits;

View File

@@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.mindustry.world.blocks.types.modules.InventoryModule;
import io.anuke.mindustry.world.blocks.types.modules.LiquidModule;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;

View File

@@ -9,12 +9,12 @@ import io.anuke.mindustry.entities.effect.Rubble;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.modules.InventoryModule;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.graphics.Draw;
@@ -33,7 +33,7 @@ public class BuildBlock extends Block {
@Override
public void setBars(){
bars.replace(new BlockBar(BarType.health, true, tile -> tile.<BuildEntity>entity().progress));
bars.replace(new BlockBar(BarType.health, true, tile -> (float)tile.<BuildEntity>entity().progress));
}
@Override
@@ -58,7 +58,7 @@ public class BuildBlock extends Block {
for(TextureRegion region : entity.result.getBlockIcon()){
Shaders.blockbuild.region = region;
Shaders.blockbuild.progress = entity.progress;
Shaders.blockbuild.progress = (float)entity.progress;
Shaders.blockbuild.apply();
Draw.rect(region, tile.drawx(), tile.drawy(), entity.result.rotate ? tile.getRotation() * 90 : 0);
@@ -77,8 +77,8 @@ public class BuildBlock extends Block {
@Override
public void update(Tile tile) {
BuildEntity entity = tile.entity();
entity.progress -= 1f/entity.result.health/decaySpeedScl;
if(entity.progress > 1f){
if(entity.progress >= 1f){
Team team = tile.getTeam();
tile.setBlock(entity.result);
tile.setTeam(team);
@@ -86,6 +86,12 @@ public class BuildBlock extends Block {
}else if(entity.progress < 0f){
entity.damage(entity.health + 1);
}
if(!entity.updated){
entity.progress -= 1f/entity.result.health/decaySpeedScl;
}
entity.updated = false;
}
@Override
@@ -94,9 +100,45 @@ public class BuildBlock extends Block {
}
public class BuildEntity extends TileEntity{
public Block result;
public Recipe recipe;
public float progress = 0.05f;
public ItemStack[] stacks;
private double progress = 0;
private double[] accumulator;
private Block result;
private boolean updated;
public void addProgress(InventoryModule inventory, double amount){
double maxProgress = amount;
for(int i = 0; i < recipe.requirements.length; i ++){
accumulator[i] += recipe.requirements[i].amount*amount; //add amount progressed to the accumulator
int required = (int)(accumulator[i]); //calculate items that are required now
if(required > 0){ //if this amount is positive...
//calculate how many items it can actually use
int maxUse = Math.min(required, inventory.getItem(recipe.requirements[i].item));
//get this as a fraction
double fraction = maxUse / (double)required;
//move max progress down if this fraction is less than 1
maxProgress = Math.min(maxProgress, maxProgress*fraction);
//remove stuff that is actually used
accumulator[i] -= maxUse;
inventory.removeItem(recipe.requirements[i].item, maxUse);
}
//else, no items are required yet, so just keep going
}
progress += maxProgress;
updated = true;
}
public void set(Recipe recipe){
updated = true;
this.result = recipe.result;
this.recipe = recipe;
this.accumulator = new double[recipe.requirements.length];
}
}
}

View File

@@ -7,8 +7,8 @@ import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.resource.AmmoEntry;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoEntry;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.world.Tile;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.util.Mathf;

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.resource.AmmoEntry;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.AmmoEntry;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.defense.turrets;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.ucore.util.Strings;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.ItemBuffer;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.util.Mathf;

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.LiquidBlock;
import io.anuke.mindustry.world.blocks.types.modules.LiquidModule;

View File

@@ -5,7 +5,7 @@ import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.world.Tile;

View File

@@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;

View File

@@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.NumberUtils;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.world.Tile;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.LiquidBlock;
import io.anuke.ucore.graphics.Draw;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.util.Mathf;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.world.Tile;

View File

@@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.world.Tile;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.world.Tile;

View File

@@ -6,8 +6,8 @@ import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Effects;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.LiquidBlock;

View File

@@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.NumberUtils;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.*;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Bits;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types.modules;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.blocks.types.BlockModule;
import java.io.DataInputStream;

View File

@@ -1,7 +1,7 @@
package io.anuke.mindustry.world.blocks.types.modules;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.blocks.types.BlockModule;
import java.io.DataInputStream;

View File

@@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks.types.power;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world.blocks.types.power;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.type.Item;
public class DecayGenerator extends BurnerGenerator {

Some files were not shown because too many files have changed in this diff Show More