Merge remote-tracking branch 'origin/continuous-sectors' into continuous-sectors

This commit is contained in:
Anuken
2018-09-21 08:47:41 -04:00
81 changed files with 391 additions and 2974 deletions

View File

@ -27,7 +27,7 @@ allprojects {
appName = 'Mindustry'
gdxVersion = '1.9.8'
roboVMVersion = '2.3.0'
uCoreVersion = '39d511523f61b8464d7187a3bcd93ea17550712d'
uCoreVersion = '99b7a3af00a1fa7e48a494515bf6b137774e114b'
getVersionString = {
String buildVersion = getBuildVersion()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

View File

@ -10,11 +10,6 @@ Font: {
markup: false,
scale: 0.5
},
korean: {
file: korean.fnt,
markup: true,
scale: 0.5
},
trad-chinese: {
file: trad_chinese.fnt,
markup: true,

View File

@ -13,6 +13,13 @@ public class Recipes implements ContentList{
@Override
public void load(){
//DEBUG
new Recipe(distribution, DebugBlocks.itemSource).setMode(GameMode.sandbox).setHidden(true);
new Recipe(distribution, DebugBlocks.itemVoid).setMode(GameMode.sandbox).setHidden(true);
new Recipe(liquid, DebugBlocks.liquidSource).setMode(GameMode.sandbox).setHidden(true);
new Recipe(power, DebugBlocks.powerVoid).setMode(GameMode.sandbox).setHidden(true);
new Recipe(power, DebugBlocks.powerInfinite).setMode(GameMode.sandbox).setHidden(true);
//DEFENSE
//walls
@ -181,13 +188,6 @@ public class Recipes implements ContentList{
new Recipe(liquid, LiquidBlocks.mechanicalPump, new ItemStack(Items.copper, 30), new ItemStack(Items.lead, 20)).setDependencies(CraftingBlocks.smelter);
new Recipe(liquid, LiquidBlocks.rotaryPump, new ItemStack(Items.copper, 140), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 70));
new Recipe(liquid, LiquidBlocks.thermalPump, new ItemStack(Items.copper, 160), new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 60), new ItemStack(Items.titanium, 80), new ItemStack(Items.thorium, 70));
//DEBUG
new Recipe(units, DebugBlocks.itemSource).setMode(GameMode.sandbox).setHidden(true);
new Recipe(units, DebugBlocks.itemVoid).setMode(GameMode.sandbox).setHidden(true);
new Recipe(units, DebugBlocks.liquidSource).setMode(GameMode.sandbox).setHidden(true);
new Recipe(units, DebugBlocks.powerVoid).setMode(GameMode.sandbox).setHidden(true);
new Recipe(units, DebugBlocks.powerInfinite).setMode(GameMode.sandbox).setHidden(true);
}
@Override

View File

@ -10,6 +10,7 @@ import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
@ -39,6 +40,13 @@ public class DebugBlocks extends BlockList implements ContentList{
powerVoid = new PowerBlock("powervoid"){
{
powerCapacity = Float.MAX_VALUE;
shadow = "shadow-round-1";
}
@Override
public void setBars(){
super.setBars();
bars.remove(BarType.power);
}
};
@ -47,6 +55,9 @@ public class DebugBlocks extends BlockList implements ContentList{
powerCapacity = 10000f;
powerSpeed = 100f;
maxNodes = 100;
outputsPower = true;
consumesPower = false;
shadow = "shadow-round-1";
}
@Override
@ -134,7 +145,7 @@ public class DebugBlocks extends BlockList implements ContentList{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new LiquidSourceEntity();
}
};

View File

@ -63,11 +63,11 @@ public class PowerBlocks extends BlockList implements ContentList{
health = 600;
}};
battery = new PowerDistributor("battery"){{
battery = new Battery("battery"){{
powerCapacity = 320f;
}};
batteryLarge = new PowerDistributor("battery-large"){{
batteryLarge = new Battery("battery-large"){{
size = 3;
powerCapacity = 2000f;
}};

View File

@ -75,12 +75,12 @@ public class ProductionBlocks extends BlockList implements ContentList{
waterextractor = new SolidPump("water-extractor"){{
result = Liquids.water;
pumpAmount = 0.1f;
pumpAmount = 0.065f;
size = 2;
liquidCapacity = 30f;
rotateSpeed = 1.4f;
consumes.power(0.15f);
consumes.power(0.13f);
}};
oilextractor = new Fracker("oil-extractor"){{

View File

@ -62,7 +62,6 @@ public class UI extends SceneModule{
public ContentInfoDialog content;
public SectorsDialog sectors;
public MissionDialog missions;
public UnlockGraphDialog graph;
private Locale lastLocale;
@ -118,7 +117,7 @@ public class UI extends SceneModule{
font.getData().setScale(Vars.fontScale);
font.getData().down += Unit.dp.scl(4f);
font.getData().lineHeight -= Unit.dp.scl(4.3f);
}, skin.font(), skin.getFont("default-font-chat"), skin.getFont("korean"), skin.getFont("trad-chinese"), skin.getFont("simp-chinese"));
}, skin.font(), skin.getFont("default-font-chat"), skin.getFont("trad-chinese"), skin.getFont("simp-chinese"));
}
@Override
@ -173,12 +172,12 @@ public class UI extends SceneModule{
Group group = Core.scene.getRoot();
backfrag.build(group);
control.input(0).getFrag().build(Core.scene.getRoot());
hudfrag.build(group);
menufrag.build(group);
chatfrag.container().build(group);
listfrag.build(group);
loadfrag.build(group);
}
@Override

View File

@ -216,6 +216,10 @@ public class World extends Module{
Events.fire(new WorldLoadEvent());
}
public boolean isGenerating(){
return generating;
}
/**Loads up a sector map. This does not call play(), but calls reset().*/
public void loadSector(Sector sector){
currentSector = sector;
@ -228,7 +232,7 @@ public class World extends Module{
beginMapLoad();
int width = sectorSize * sector.size, height = sectorSize * sector.size;
int width = sectorSize * sector.width, height = sectorSize * sector.height;
Tile[][] tiles = createTiles(width, height);

View File

@ -90,7 +90,7 @@ public class Damage{
Tile tile = world.tile(cx, cy);
if(tile != null && tile.entity != null && tile.target().getTeamID() != team.ordinal() && tile.entity.collide(hitter)){
tile.entity.collision(hitter);
Effects.effect(effect, tile.worldx(), tile.worldy());
hitter.getBulletType().hit(hitter, tile.worldx(), tile.worldy());
}
return false;
});

View File

@ -157,6 +157,10 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
}
public void removeFromProximity(){
if(power != null){
tile.block().powerGraphRemoved(tile);
}
GridPoint2[] nearby = Edges.getEdges(tile.block().size);
for(GridPoint2 point : nearby){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
@ -179,18 +183,17 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
for(GridPoint2 point : nearby){
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other != null){
other.block().onProximityUpdate(other);
other = other.target();
}
if(other == null) continue;
other = other.target();
if(other.entity == null || other.getTeamID() != tile.getTeamID()) continue;
if(other != null && other.entity != null){
tmpTiles.add(other);
other.block().onProximityUpdate(other);
//add this tile to proximity of nearby tiles
if(!other.entity.proximity.contains(tile, true)){
other.entity.proximity.add(tile);
}
tmpTiles.add(other);
//add this tile to proximity of nearby tiles
if(!other.entity.proximity.contains(tile, true)){
other.entity.proximity.add(tile);
}
}
@ -199,6 +202,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
proximity.add(tile);
}
if(tile.block().hasPower) tile.block().updatePowerGraph(tile);
tile.block().onProximityUpdate(tile);
}

View File

@ -109,6 +109,10 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
remove();
}
public BulletType getBulletType(){
return type;
}
public void resetOwner(Entity entity, Team team){
this.owner = entity;
this.team = team;

View File

@ -181,12 +181,7 @@ public interface BuilderTrait extends Entity{
setMineTile(null);
}
TileEntity core = unit.getClosestCore();
//if there is no core to build with, stop building!
if(core == null){
return;
}
Tile tile = world.tile(current.x, current.y);
@ -205,6 +200,13 @@ public interface BuilderTrait extends Entity{
}
}
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();

View File

@ -35,7 +35,8 @@ public class UnitDrops{
if(Mathf.chance(0.03)){
int amount = Mathf.random(20, 40);
Call.transferItemTo(item, amount, unit.x + Mathf.range(2f), unit.y + Mathf.range(2f), core.tile);
amount = core.tile.block().acceptStack(item, amount, core.tile, null);
if (amount > 0) Call.transferItemTo(item, amount, unit.x + Mathf.range(2f), unit.y + Mathf.range(2f), core.tile);
}
}
}

View File

@ -48,7 +48,6 @@ public abstract class InputHandler extends InputAdapter{
public InputHandler(Player player){
this.player = player;
this.section = "player_" + (player.playerIndex + 1);
Timers.run(1f, () -> frag.build(Core.scene.getRoot()));
}
//methods to override
@ -122,6 +121,10 @@ public abstract class InputHandler extends InputAdapter{
tile.block().tapped(tile, player);
}
public OverlayFragment getFrag(){
return frag;
}
public void update(){
}

View File

@ -293,10 +293,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public void drawOutlined(){
//Draw.color(Palette.placing);
//Lines.poly(player.x, player.y, 100, Player.placeDistance);
//Draw.color();
Lines.stroke(1f);
Shaders.mix.color.set(Palette.accent);
Graphics.shader(Shaders.mix);
@ -549,14 +546,14 @@ public class MobileInput extends InputHandler implements GestureListener{
float worldx = Graphics.world(x, y).x, worldy = Graphics.world(x, y).y;
checkTargets(worldx, worldy);
//get tile on cursor
Tile cursor = tileAt(x, y);
//ignore off-screen taps
if(cursor == null || ui.hasMouse(x, y)) return false;
checkTargets(worldx, worldy);
//remove if request present
if(hasRequest(cursor)){
removeRequest(getRequest(cursor));

View File

@ -22,7 +22,7 @@ public class Sector{
/**Slot ID of this sector's save. -1 means no save has been created.*/
public int saveID = -1;
/**Sector size; if more than 1, the coordinates are the bottom left corner.*/
public int size = 1;
public int width = 1, height = 1;
/**Num of missions in this sector that have been completed so far.*/
public int completedMissions;
/**Display texture. Needs to be disposed.*/

View File

@ -85,19 +85,14 @@ public class Sectors{
Sector sector = get(x, y);
sector.complete = true;
for(GridPoint2 point : Edges.getEdges(sector.size)){
//TODO work for unique width + height?
for(GridPoint2 point : Edges.getEdges(sector.width)){
createSector(sector.x + point.x, sector.y + point.y);
}
}
/**Creates a sector at a location if it is not present, but does not unlock it.*/
public void createSector(int x, int y){
boolean isLarge = Mathf.randomSeed(3+Bits.packInt((short)round2(x), (short)round2(y))) < sectorLargeChance;
if(isLarge){
x = round2(x);
y = round2(y);
}
if(grid.containsKey(x, y)) return;
@ -105,11 +100,11 @@ public class Sectors{
sector.x = (short)x;
sector.y = (short)y;
sector.complete = false;
sector.size = isLarge ? 2 : 1;
sector.width = sector.height = 1;
initSector(sector);
for(int cx = 0; cx < sector.size; cx++){
for(int cy = 0; cy < sector.size; cy++){
for(int cx = 0; cx < sector.width; cx++){
for(int cy = 0; cy < sector.height; cy++){
grid.put(x + cx, y + cy, sector);
}
}
@ -128,8 +123,8 @@ public class Sectors{
for(Sector sector : out){
createTexture(sector);
initSector(sector);
for(int cx = 0; cx < sector.size; cx++){
for(int cy = 0; cy < sector.size; cy++){
for(int cx = 0; cx < sector.width; cx++){
for(int cy = 0; cy < sector.height; cy++){
grid.put(sector.x + cx, sector.y + cy, sector);
}
}
@ -165,8 +160,7 @@ public class Sectors{
sector.spawns = sector.missions.first().getWaves(sector);
//add all ores for now since material differences aren't well handled yet
sector.ores.addAll(Items.copper, Items.coal, Items.lead, Items.thorium, Items.titanium);
sector.ores.addAll(Items.copper);
//set starter items
if(sector.difficulty > 12){ //now with titanium
@ -184,15 +178,10 @@ public class Sectors{
}
}
private int round2(int i){
if(i < 0) i --;
return i/2*2;
}
private void createTexture(Sector sector){
if(headless) return; //obviously not created or needed on server
Pixmap pixmap = new Pixmap(sectorImageSize * sector.size, sectorImageSize * sector.size, Format.RGBA8888);
Pixmap pixmap = new Pixmap(sectorImageSize * sector.width, sectorImageSize * sector.height, Format.RGBA8888);
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){

View File

@ -70,7 +70,7 @@ public class FortressGenerator{
gen.setBlock(enemyX, enemyY, StorageBlocks.core, team);
float difficultyScl = Mathf.clamp(gen.sector.difficulty / 20f + gen.random.range(1f/2f), 0f, 0.9999f);
int coreDst = FortressGenerator.coreDst*gen.sector.size;
int coreDst = FortressGenerator.coreDst*gen.sector.width;
Array<Block> turrets = find(b -> b instanceof ItemTurret);
Array<Block> powerTurrets = find(b -> b instanceof PowerTurret);

View File

@ -1,119 +0,0 @@
package io.anuke.mindustry.ui;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.SafeArray;
public class GraphSimulation<T>{
public Array<Vertex<T>> vertices = new SafeArray<>();
public Array<Edge<T>> edges = new SafeArray<>();
public int frameWidth;
public int frameHeight;
public boolean equi = false;
public float criterion = 1000;
public float coolingRate = 0.065f;
private static final float C = 1f;
private int iteration = 0;
private float k;
private float t;
private boolean equilibriumReached = false;
private Vector2 deltaPos = new Vector2();
public int startSimulation() {
iteration = 0;
equilibriumReached = false;
int area = Math.min(frameWidth * frameWidth, frameHeight * frameHeight);
k = C * Mathf.sqrt(area / vertices.size);
t = frameWidth / 10;
if (equi) {
while (!equilibriumReached && iteration < 10000) {
simulateStep();
}
} else {
for (int i = 0; i < criterion; i++) {
simulateStep();
}
}
return iteration;
}
private void simulateStep() {
for (Vertex<T> v : vertices) {
v.disp.set(0, 0);
for (Vertex<T> u : vertices) {
if (v != u) {
deltaPos.set(v.pos).sub(u.pos);
float length = deltaPos.len();
deltaPos.setLength(forceRepulsive(length, k));
v.disp.add(deltaPos);
}
}
}
for (Edge<T> e : edges) {
deltaPos.set(e.v.pos).sub(e.u.pos);
float length = deltaPos.len();
deltaPos.setLength(forceAttractive(length, k));
e.v.disp.sub(deltaPos);
e.u.disp.add(deltaPos);
}
equilibriumReached = true;
for (Vertex<T> v : vertices) {
deltaPos.set(v.disp);
float length = deltaPos.len();
if (length > criterion) {
equilibriumReached = false;
}
deltaPos.setLength(Math.min(length, t));
v.pos.add(deltaPos);
v.pos.x = Mathf.clamp(v.pos.x, 0, frameWidth);
v.pos.y = Mathf.clamp(v.pos.y, 0, frameHeight);
}
t = Math.max(t * (1 - coolingRate), 1);
iteration++;
}
private float forceAttractive(float d, float k) {
return d * d / k;
}
private float forceRepulsive(float d, float k) {
return k * k /d;
}
public static class Vertex<T>{
public Vector2 pos = new Vector2();
public final T value;
private Vector2 disp = new Vector2();
public Vertex(T value){
this.value = value;
}
}
public static class Edge<T> {
public final Vertex<T> v;
public final Vertex<T> u;
public Edge(Vertex<T> v, Vertex<T> u) {
this.v = v;
this.u = u;
}
}
}

View File

@ -130,7 +130,7 @@ public class SectorsDialog extends FloatingDialog{
float drawY = y + height/2f + sectorY * padSectorSize - offsetY * padSectorSize - panY % padSectorSize;
Sector sector = world.sectors().get(sectorX, sectorY);
int size = (sector == null ? 1 : sector.size);
int size = (sector == null ? 1 : sector.width);
float padding = (size-1) * sectorPadding;
if(sector != null && (sector.x != sectorX || sector.y != sectorY)){

View File

@ -1,97 +0,0 @@
package io.anuke.mindustry.ui.dialogs;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.ItemType;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.GraphSimulation;
import io.anuke.mindustry.ui.GraphSimulation.Edge;
import io.anuke.mindustry.ui.GraphSimulation.Vertex;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
public class UnlockGraphDialog extends FloatingDialog{
int frameSize = 1000;
ObjectMap<UnlockableContent, Vertex<UnlockableContent>> map = new ObjectMap<>();
Array<Vertex<UnlockableContent>> vertices;
Array<Edge<UnlockableContent>> edges;
public UnlockGraphDialog(){
super("$text.unlocks");
rebuild();
}
public void rebuild(){
content().clear();
GraphSimulation<UnlockableContent> sim = new GraphSimulation<>();
sim.frameWidth = frameSize;
sim.frameHeight = frameSize;
vertices = sim.vertices;
edges = sim.edges;
for(Item item : Vars.content.items()){
if(item.type != ItemType.material) continue;
put(item);
}
for(Recipe recipe : Vars.content.recipes()){
if(recipe.requirements.length == 0) continue;
put(recipe);
for(Item item : Vars.content.items()){
for(ItemStack stack : recipe.requirements){
if(stack.item == item){
link(item, recipe);
break;
}
}
}
}
sim.startSimulation();
content().addRect((x, y, w, h) -> {
float cx = x + w/2f, cy = y + h/2f;
float ox = cx - frameSize/2f, oy = cy - frameSize/2f;
Draw.color(Color.DARK_GRAY);
Lines.stroke(4f);
for(Edge<UnlockableContent> e : edges){
if(e.v.value instanceof Item){
Draw.color(((Item) e.v.value).color);
}
Lines.line(e.u.pos.x + ox, e.u.pos.y + oy, e.v.pos.x + ox, e.v.pos.y + oy);
}
Draw.color();
for(Vertex<UnlockableContent> v : vertices){
Draw.rect(v.value.getContentIcon(), v.pos.x + ox, v.pos.y + oy, 16*2f, 16*2f);
}
}).grow();
}
private Vertex<UnlockableContent> get(UnlockableContent c){
return map.get(c);
}
private void put(UnlockableContent c){
Vertex<UnlockableContent> v = new Vertex<>(c);
v.pos.set(frameSize/2f + Mathf.range(frameSize/2f), frameSize/2f + Mathf.range(frameSize/2f));
map.put(c, v);
vertices.add(v);
}
private void link(UnlockableContent a, UnlockableContent b){
edges.add(new Edge<>(get(a), get(b)));
}
}

View File

@ -25,6 +25,8 @@ public abstract class BaseBlock extends MappableContent{
public boolean outputsLiquid = false;
public boolean singleLiquid = true;
public boolean consumesPower = true;
public boolean outputsPower;
public int itemCapacity;
public float liquidCapacity = 10f;
@ -42,7 +44,7 @@ public abstract class BaseBlock extends MappableContent{
* Returns the amount of items this block can accept.
*/
public int acceptStack(Item item, int amount, Tile tile, Unit source){
if(acceptItem(item, tile, tile) && hasItems && source.getTeam() == tile.getTeam()){
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.getTeam() == tile.getTeam())){
return Math.min(getMaximumAccepted(tile, item), amount);
}else{
return 0;

View File

@ -138,6 +138,41 @@ public class Block extends BaseBlock {
return drops != null && drops.item == item;
}
public void updatePowerGraph(Tile tile){
TileEntity entity = tile.entity();
for(Tile other : getPowerConnections(tile, tempTiles)){
if(other.entity.power != null){
other.entity.power.graph.add(entity.power.graph);
}
}
}
public void powerGraphRemoved(Tile tile){
tile.entity.power.graph.remove(tile);
for(int i = 0; i < tile.entity.power.links.size; i++){
Tile other = world.tile(tile.entity.power.links.get(i));
if(other != null && other.entity != null && other.entity.power != null){
other.entity.power.links.removeValue(tile.packedPosition());
}
}
}
public Array<Tile> getPowerConnections(Tile tile, Array<Tile> out){
out.clear();
for(Tile other : tile.entity.proximity()){
if(other.entity.power != null && !(consumesPower && other.block().consumesPower && !outputsPower && !other.block().outputsPower)){
out.add(other);
}
}
for(int i = 0; i < tile.entity.power.links.size; i++){
Tile link = world.tile(tile.entity.power.links.get(i));
if(link != null && link.entity != null && link.entity.power != null) out.add(link);
}
return out;
}
public boolean isLayer(Tile tile){
return true;
}
@ -444,7 +479,7 @@ public class Block extends BaseBlock {
return destructible || update;
}
public TileEntity getEntity(){
public TileEntity newEntity(){
return new TileEntity();
}
@ -478,7 +513,8 @@ public class Block extends BaseBlock {
"entity.x", tile.entity.x,
"entity.y", tile.entity.y,
"entity.id", tile.entity.id,
"entity.items.total", hasItems ? tile.entity.items.total() : null
"entity.items.total", hasItems ? tile.entity.items.total() : null,
"entity.graph", tile.entity.power != null && tile.entity.power.graph != null ? tile.entity.power.graph.getID() : null
);
}
}

View File

@ -416,12 +416,17 @@ public class Tile implements PosTrait, TargetTrait{
Block block = block();
if(block.hasEntity()){
entity = block.getEntity().init(this, block.update);
entity = block.newEntity().init(this, block.update);
entity.cons = new ConsumeModule();
if(block.hasItems) entity.items = new InventoryModule();
if(block.hasLiquids) entity.liquids = new LiquidModule();
if(block.hasPower) entity.power = new PowerModule();
entity.updateProximity();
if(block.hasPower){
entity.power = new PowerModule();
entity.power.graph.add(this);
}
if(!world.isGenerating()){
entity.updateProximity();
}
}else if(!(block instanceof BlockPart)){
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
for(GridPoint2 p : Geometry.d4){

View File

@ -171,7 +171,7 @@ public class BuildBlock extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new BuildEntity();
}

View File

@ -76,7 +76,7 @@ public class DeflectorWall extends Wall{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new DeflectorEntity();
}

View File

@ -81,7 +81,7 @@ public class Door extends Wall{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new DoorEntity();
}

View File

@ -169,7 +169,7 @@ public class ForceProjector extends Block {
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ForceEntity();
}

View File

@ -122,7 +122,7 @@ public class MendProjector extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new MendEntity();
}

View File

@ -52,7 +52,7 @@ public class MendingWall extends Wall{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new DeflectorEntity();
}
}

View File

@ -123,7 +123,7 @@ public class OverdriveProjector extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new OverdriveEntity();
}

View File

@ -38,7 +38,7 @@ public class ArtilleryTurret extends ItemTurret{
for(int i = 0; i < shots; i++){
Bullet.create(ammo.bullet, tile.entity, tile.getTeam(), tile.drawx() + tr.x, tile.drawy() + tr.y,
entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
}
effects(tile);

View File

@ -60,7 +60,7 @@ public class ChargeTurret extends PowerTurret{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new LaserTurretEntity();
}

View File

@ -89,7 +89,7 @@ public class LaserTurret extends PowerTurret{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new LaserTurretEntity();
}

View File

@ -339,7 +339,7 @@ public abstract class Turret extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new TurretEntity();
}

View File

@ -41,7 +41,7 @@ public class BufferedItemBridge extends ExtendingItemBridge{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new BufferedItemBridgeEntity();
}

View File

@ -127,7 +127,7 @@ public class Conduit extends LiquidBlock{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ConduitEntity();
}

View File

@ -358,7 +358,7 @@ public class Conveyor extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ConveyorEntity();
}

View File

@ -287,7 +287,7 @@ public class ItemBridge extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ItemBridgeEntity();
}

View File

@ -92,7 +92,7 @@ public class Junction extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new JunctionEntity();
}

View File

@ -234,7 +234,7 @@ public class MassDriver extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new MassDriverEntity();
}

View File

@ -86,7 +86,7 @@ public class Router extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new SplitterEntity();
}

View File

@ -114,7 +114,7 @@ public class Sorter extends Block implements SelectionTrait{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new SorterEntity();
}

View File

@ -273,7 +273,7 @@ public class WarpGate extends PowerBlock{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new TeleporterEntity();
}

View File

@ -0,0 +1,10 @@
package io.anuke.mindustry.world.blocks.power;
public class Battery extends PowerDistributor{
public Battery(String name){
super(name);
outputsPower = true;
consumesPower = true;
}
}

View File

@ -50,7 +50,7 @@ public class FusionReactor extends PowerGenerator{
entity.power.amount += powerAdded;
entity.totalProgress += entity.warmup * Timers.delta();
distributePower(tile);
tile.entity.power.graph.update();
}
@Override
@ -108,7 +108,7 @@ public class FusionReactor extends PowerGenerator{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new FusionReactorEntity();
}

View File

@ -106,14 +106,13 @@ public abstract class ItemGenerator extends PowerGenerator{
entity.generateTime = 1f;
}
distributePower(tile);
tile.entity.power.graph.update();
}
protected abstract float getItemEfficiency(Item item);
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ItemGeneratorEntity();
}

View File

@ -77,7 +77,7 @@ public abstract class ItemLiquidGenerator extends ItemGenerator{
}
}
distributePower(tile);
tile.entity.power.graph.update();
}
@Override

View File

@ -61,7 +61,7 @@ public abstract class LiquidGenerator extends PowerGenerator{
}
}
distributePower(tile);
tile.entity.power.graph.update();
}
@Override
@ -70,7 +70,7 @@ public abstract class LiquidGenerator extends PowerGenerator{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ItemGeneratorEntity();
}

View File

@ -124,7 +124,7 @@ public class NuclearReactor extends PowerGenerator{
if(entity.heat >= 0.999f){
entity.kill();
}else{
distributePower(tile);
tile.entity.power.graph.update();
}
}
@ -193,7 +193,7 @@ public class NuclearReactor extends PowerGenerator{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new NuclearReactorEntity();
}

View File

@ -1,66 +1,18 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.ucore.core.Timers;
public class PowerDistributor extends PowerBlock{
public PowerDistributor(String name){
super(name);
}
protected void distributePower(Tile tile){
TileEntity entity = tile.entity;
int sources = 0;
if(entity == null) return;
if(Float.isNaN(entity.power.amount)){
entity.power.amount = 0f;
}
for(GridPoint2 point : Edges.getEdges(size)){
Tile target = tile.getNearby(point);
if(target != null && target.block().hasPower &&
shouldDistribute(tile, target)) sources++;
}
if(sources == 0) return;
float result = entity.power.amount / sources;
for(GridPoint2 point : Edges.getEdges(size)){
Tile target = tile.getNearby(point);
if(target == null) continue;
target = target.target();
if(target.block().hasPower && shouldDistribute(tile, target)){
float diff = (tile.entity.power.amount / powerCapacity - target.entity.power.amount / target.block().powerCapacity) / 1.4f;
float transmit = Math.min(result * Timers.delta(), diff * powerCapacity);
if(target.block().acceptPower(target, tile, transmit)){
float transferred = target.block().addPower(target, transmit);
entity.power.amount -= transferred;
}
}
}
}
protected boolean shouldDistribute(Tile tile, Tile other){
other = other.target();
//only generators can distribute to other generators
return other.getTeamID() == tile.getTeamID() && (!(other.block() instanceof PowerGenerator) || tile.block() instanceof PowerGenerator)
&& other.entity != null
&& other.block().hasPower
&& other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
consumesPower = false;
outputsPower = true;
}
@Override
public void update(Tile tile){
distributePower(tile);
tile.entity.power.graph.update();
}
}

View File

@ -18,7 +18,7 @@ public class PowerGenerator extends PowerDistributor{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new GeneratorEntity();
}

View File

@ -0,0 +1,136 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import com.badlogic.gdx.utils.Queue;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.threads;
public class PowerGraph{
private final static Queue<Tile> queue = new Queue<>();
private final static Array<Tile> outArray1 = new Array<>();
private final static Array<Tile> outArray2 = new Array<>();
private final ObjectSet<Tile> producers = new ObjectSet<>();
private final ObjectSet<Tile> consumers = new ObjectSet<>();
private final ObjectSet<Tile> all = new ObjectSet<>();
private long lastFrameUpdated;
private final int graphID;
private static int lastGraphID;
{
graphID = lastGraphID++;
}
public int getID(){
return graphID;
}
public synchronized void update(){
if(threads.getFrameID() == lastFrameUpdated || consumers.size == 0 || producers.size == 0){
return;
}
lastFrameUpdated = threads.getFrameID();
float totalInput = 0f;
for(Tile producer : producers){
totalInput += producer.entity.power.amount;
}
for(Tile producer : producers){
float accumulator = producer.entity.power.amount;
if(accumulator <= 0.0001f) continue;
float toEach = accumulator / consumers.size;
float outputs = 0f;
for(Tile tile : consumers){
outputs += Math.min(tile.block().powerCapacity - tile.entity.power.amount, toEach) / toEach;
}
float finalEach = toEach / outputs;
float buffer = 0f;
if(Float.isNaN(finalEach) || Float.isInfinite(finalEach)){
continue;
}
for(Tile tile : consumers){
float used = Math.min(tile.block().powerCapacity - tile.entity.power.amount, finalEach) * accumulator / totalInput;
buffer += used;
tile.entity.power.amount += used;
}
producer.entity.power.amount -= buffer;
}
}
public synchronized void add(PowerGraph graph){
for(Tile tile : graph.all){
add(tile);
}
}
public synchronized void add(Tile tile){
tile.entity.power.graph = this;
all.add(tile);
if(tile.block().outputsPower){
producers.add(tile);
}
if(tile.block().consumesPower){
consumers.add(tile);
}
}
public synchronized void clear(){
for(Tile other : all){
other.entity.power.graph = null;
}
all.clear();
producers.clear();
consumers.clear();
}
public synchronized void reflow(Tile tile){
queue.clear();
queue.addLast(tile);
while(queue.size > 0){
Tile child = queue.removeFirst();
child.entity.power.graph = this;
add(child);
for(Tile next : child.block().getPowerConnections(child, outArray2)){
if(next.entity.power != null && next.entity.power.graph == null){
queue.addLast(next);
}
}
}
}
public synchronized void remove(Tile tile){
clear();
for(Tile other : tile.block().getPowerConnections(tile, outArray1)){
if(other.entity.power == null || other.entity.power.graph != null) continue;
PowerGraph graph = new PowerGraph();
queue.clear();
queue.addLast(other);
while(queue.size > 0){
Tile child = queue.removeFirst();
child.entity.power.graph = graph;
graph.add(child);
for(Tile next : child.block().getPowerConnections(child, outArray2)){
if(next != tile && next.entity.power != null && next.entity.power.graph == null){
queue.addLast(next);
}
}
}
}
}
}

View File

@ -1,7 +1,6 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.entities.Player;
@ -23,10 +22,6 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class PowerNode extends PowerBlock{
@ -49,40 +44,52 @@ public class PowerNode extends PowerBlock{
layer = Layer.power;
powerCapacity = 5f;
configurable = true;
consumesPower = false;
outputsPower = false;
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void linkPowerDistributors(Player player, Tile tile, Tile other){
if(!(tile.entity instanceof DistributorEntity)) return;
public static void linkPowerNodes(Player player, Tile tile, Tile other){
if(tile.entity.power == null) return;
DistributorEntity entity = tile.entity();
TileEntity entity = tile.entity();
if(!entity.links.contains(other.packedPosition())){
entity.links.add(other.packedPosition());
if(!entity.power.links.contains(other.packedPosition())){
entity.power.links.add(other.packedPosition());
}
if(other.getTeamID() == tile.getTeamID() && other.block() instanceof PowerNode){
DistributorEntity oe = other.entity();
if(other.getTeamID() == tile.getTeamID()){
if(!oe.links.contains(tile.packedPosition())){
oe.links.add(tile.packedPosition());
if(!other.entity.power.links.contains(tile.packedPosition())){
other.entity.power.links.add(tile.packedPosition());
}
}
entity.power.graph.add(other.entity.power.graph);
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void unlinkPowerDistributors(Player player, Tile tile, Tile other){
if(!(tile.entity instanceof DistributorEntity)) return;
public static void unlinkPowerNodes(Player player, Tile tile, Tile other){
if(tile.entity.power == null) return;
DistributorEntity entity = tile.entity();
TileEntity entity = tile.entity();
entity.links.removeValue(other.packedPosition());
entity.power.links.removeValue(other.packedPosition());
if(other.block() instanceof PowerNode){
DistributorEntity oe = other.entity();
oe.links.removeValue(tile.packedPosition());
other.entity.power.links.removeValue(tile.packedPosition());
}
//clear all graph data first
PowerGraph tg = entity.power.graph;
tg.clear();
//reflow from this point, covering all tiles on this side
tg.reflow(tile);
//create new graph for other end
PowerGraph og = new PowerGraph();
//reflow from other end
og.reflow(other);
}
@Override
@ -93,7 +100,7 @@ public class PowerNode extends PowerBlock{
public void playerPlaced(Tile tile){
Tile before = world.tile(lastPlaced);
if(linkValid(tile, before) && before.block() instanceof PowerNode){
Call.linkPowerDistributors(null, tile, before);
Call.linkPowerNodes(null, tile, before);
}
lastPlaced = tile.packedPosition();
@ -109,21 +116,21 @@ public class PowerNode extends PowerBlock{
@Override
public void update(Tile tile){
distributeLaserPower(tile);
tile.entity.power.graph.update();
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
DistributorEntity entity = tile.entity();
TileEntity entity = tile.entity();
other = other.target();
Tile result = other;
if(linkValid(tile, other)){
if(linked(tile, other)){
threads.run(() -> Call.unlinkPowerDistributors(null, tile, result));
}else if(entity.links.size < maxNodes){
threads.run(() -> Call.linkPowerDistributors(null, tile, result));
threads.run(() -> Call.unlinkPowerNodes(null, tile, result));
}else if(entity.power.links.size < maxNodes){
threads.run(() -> Call.linkPowerNodes(null, tile, result));
}
return false;
}
@ -144,7 +151,7 @@ public class PowerNode extends PowerBlock{
@Override
public void drawConfigure(Tile tile){
DistributorEntity entity = tile.entity();
TileEntity entity = tile.entity();
Draw.color(Palette.accent);
@ -170,7 +177,7 @@ public class PowerNode extends PowerBlock{
Lines.square(link.drawx(), link.drawy(),
link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f)));
if((entity.links.size >= maxNodes || (link.block() instanceof PowerNode && ((DistributorEntity) link.entity).links.size >= ((PowerNode) link.block()).maxNodes)) && !linked){
if((entity.power.links.size >= maxNodes || (link.block() instanceof PowerNode && link.entity.power.links.size >= ((PowerNode) link.block()).maxNodes)) && !linked){
Draw.color();
Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy());
}
@ -195,89 +202,20 @@ public class PowerNode extends PowerBlock{
public void drawLayer(Tile tile){
if(!Settings.getBool("lasers")) return;
DistributorEntity entity = tile.entity();
TileEntity entity = tile.entity();
entity.laserColor = Mathf.lerpDelta(entity.laserColor, Mathf.clamp(entity.powerRecieved / (powerSpeed)), 0.08f);
Draw.color(Palette.powerLaserFrom, Palette.powerLaserTo, 0f * (1f - flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl));
Draw.color(Palette.powerLaserFrom, Palette.powerLaserTo, entity.laserColor * (1f - flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl));
for(int i = 0; i < entity.links.size; i++){
Tile link = world.tile(entity.links.get(i));
for(int i = 0; i < entity.power.links.size; i++){
Tile link = world.tile(entity.power.links.get(i));
if(linkValid(tile, link)) drawLaser(tile, link);
}
Draw.color();
}
@Override
public float addPower(Tile tile, float amount){
DistributorEntity entity = tile.entity();
if(entity.lastRecieved != threads.getFrameID()){
entity.lastRecieved = threads.getFrameID();
entity.powerRecieved = 0f;
}
float canAccept = Math.min(powerCapacity * Timers.delta() - tile.entity.power.amount, amount);
tile.entity.power.amount += canAccept;
entity.powerRecieved += canAccept;
return canAccept;
}
protected boolean shouldDistribute(Tile tile, Tile other){
return other != null && other.entity != null && other.block().hasPower && other.getTeamID() == tile.getTeamID() && other.entity.power.amount / other.block().powerCapacity <= tile.entity.power.amount / powerCapacity &&
!(other.block() instanceof PowerGenerator); //do not distribute to power generators
}
protected boolean shouldLeechPower(Tile tile, Tile other){
return other.getTeamID() == tile.getTeamID() && !(other.block() instanceof PowerNode)
&& other.block() instanceof PowerDistributor //only suck power from batteries and power generators
&& other.entity.power.amount / other.block().powerCapacity > tile.entity.power.amount / powerCapacity;
}
protected void distributeLaserPower(Tile tile){
DistributorEntity entity = tile.entity();
if(Float.isNaN(entity.power.amount)){
entity.power.amount = 0f;
}
int targets = 0;
//validate everything first.
for(int i = 0; i < entity.links.size; i++){
Tile target = world.tile(entity.links.get(i));
if(!linkValid(tile, target)){
entity.links.removeIndex(i);
i--;
}else if(shouldDistribute(tile, target)){
targets++;
}
}
float result = Math.min(entity.power.amount / targets, powerSpeed * Timers.delta());
for(int i = 0; i < entity.links.size; i++){
Tile target = world.tile(entity.links.get(i));
if(targets > 0 && shouldDistribute(tile, target)){
float transmit = Math.min(result, entity.power.amount);
if(target.block().acceptPower(target, tile, transmit)){
entity.power.amount -= target.block().addPower(target, transmit);
}
}else if(shouldLeechPower(tile, target)){
float diff = (target.entity.power.amount / target.block().powerCapacity - tile.entity.power.amount / powerCapacity) / 1.4f;
float transmit = Math.min(Math.min(target.block().powerCapacity * diff, target.entity.power.amount), powerCapacity - tile.entity.power.amount);
entity.power.amount += transmit;
target.entity.power.amount -= transmit;
}
}
}
protected boolean linked(Tile tile, Tile other){
return tile.<DistributorEntity>entity().links.contains(other.packedPosition());
return tile.entity.power.links.contains(other.packedPosition());
}
protected boolean linkValid(Tile tile, Tile link){
@ -288,12 +226,12 @@ public class PowerNode extends PowerBlock{
if(!(tile != link && link != null && link.block().hasPower) || tile.getTeamID() != link.getTeamID()) return false;
if(link.block() instanceof PowerNode){
DistributorEntity oe = link.entity();
TileEntity oe = link.entity();
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize,
((PowerNode) link.block()).laserRange * tilesize) - tilesize / 2f
+ (link.block().size - 1) * tilesize / 2f + (tile.block().size - 1) * tilesize / 2f &&
(!checkMaxNodes || (oe.links.size < ((PowerNode) link.block()).maxNodes || oe.links.contains(tile.packedPosition())));
(!checkMaxNodes || (oe.power.links.size < ((PowerNode) link.block()).maxNodes || oe.power.links.contains(tile.packedPosition())));
}else{
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy())
<= laserRange * tilesize - tilesize / 2f + (link.block().size - 1) * tilesize;
@ -314,32 +252,4 @@ public class PowerNode extends PowerBlock{
x2 + t2.x, y2 + t2.y, thicknessScl);
}
@Override
public TileEntity getEntity(){
return new DistributorEntity();
}
public static class DistributorEntity extends TileEntity{
public float laserColor = 0f;
public float powerRecieved = 0f;
public long lastRecieved = 0;
public IntArray links = new IntArray();
@Override
public void write(DataOutputStream stream) throws IOException{
stream.writeShort(links.size);
for(int i = 0; i < links.size; i++){
stream.writeInt(links.get(i));
}
}
@Override
public void read(DataInputStream stream) throws IOException{
short amount = stream.readShort();
for(int i = 0; i < amount; i++){
links.add(stream.readInt());
}
}
}
}

View File

@ -28,7 +28,7 @@ public class SolarGenerator extends PowerGenerator{
public void update(Tile tile){
addPower(tile, generation * Timers.delta());
distributePower(tile);
tile.entity.power.graph.update();
}
}

View File

@ -95,7 +95,7 @@ public class Cultivator extends Drill{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new CultivatorEntity();
}

View File

@ -228,7 +228,7 @@ public class Drill extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new DrillEntity();
}

View File

@ -76,7 +76,7 @@ public class Fracker extends SolidPump{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new FrackerEntity();
}

View File

@ -110,7 +110,7 @@ public class GenericCrafter extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new GenericCrafterEntity();
}

View File

@ -94,7 +94,7 @@ public class Incinerator extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new IncineratorEntity();
}

View File

@ -89,7 +89,7 @@ public class LiquidMixer extends LiquidBlock{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new LiquidMixerEntity();
}

View File

@ -85,7 +85,7 @@ public class PowerCrafter extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new GenericCrafterEntity();
}
}

View File

@ -203,7 +203,7 @@ public class PowerSmelter extends PowerBlock{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new PowerSmelterEntity();
}

View File

@ -130,7 +130,7 @@ public class Separator extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new GenericCrafterEntity();
}
}

View File

@ -194,7 +194,7 @@ public class Smelter extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new SmelterEntity();
}

View File

@ -112,7 +112,7 @@ public class SolidPump extends Pump{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new SolidPumpEntity();
}

View File

@ -155,7 +155,7 @@ public class CoreBlock extends StorageBlock{
@Override
public int acceptStack(Item item, int amount, Tile tile, Unit source){
if(acceptItem(item, tile, tile) && hasItems && source.getTeam() == tile.getTeam()){
if(acceptItem(item, tile, tile) && hasItems && (source == null || source.getTeam() == tile.getTeam())){
return Math.min(itemCapacity - tile.entity.items.get(item), amount);
}else{
return 0;
@ -234,7 +234,7 @@ public class CoreBlock extends StorageBlock{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new CoreEntity();
}

View File

@ -67,7 +67,7 @@ public class SortedUnloader extends Unloader implements SelectionTrait{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new SortedUnloaderEntity();
}

View File

@ -107,7 +107,7 @@ public class CommandCenter extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new CommandCenterEntity();
}

View File

@ -204,7 +204,7 @@ public class MechPad extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new MechFactoryEntity();
}

View File

@ -299,7 +299,7 @@ public class Reconstructor extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new ReconstructorEntity();
}

View File

@ -113,7 +113,7 @@ public class RepairPoint extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new RepairPointEntity();
}

View File

@ -207,7 +207,7 @@ public class UnitFactory extends Block{
}
@Override
public TileEntity getEntity(){
public TileEntity newEntity(){
return new UnitFactoryEntity();
}

View File

@ -0,0 +1,7 @@
package io.anuke.mindustry.world.meta;
public enum PowerType{
consumer,
producer,
bridge
}

View File

@ -1,5 +1,8 @@
package io.anuke.mindustry.world.modules;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.mindustry.world.blocks.power.PowerGraph;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
@ -8,6 +11,8 @@ public class PowerModule extends BlockModule{
public float amount;
public float capacity = 10f;
public float voltage = 0.0001f;
public PowerGraph graph = new PowerGraph();
public IntArray links = new IntArray();
public boolean acceptsPower(){
return amount + 0.001f <= capacity;
@ -19,7 +24,6 @@ public class PowerModule extends BlockModule{
}
float canAccept = Math.min(capacity - amount, add);
amount += canAccept;
return canAccept;
@ -28,6 +32,11 @@ public class PowerModule extends BlockModule{
@Override
public void write(DataOutput stream) throws IOException{
stream.writeFloat(amount);
stream.writeShort(links.size);
for(int i = 0; i < links.size; i++){
stream.writeInt(links.get(i));
}
}
@Override
@ -36,5 +45,10 @@ public class PowerModule extends BlockModule{
if(Float.isNaN(amount)){
amount = 0f;
}
short amount = stream.readShort();
for(int i = 0; i < amount; i++){
links.add(stream.readInt());
}
}
}