This commit is contained in:
Anuken
2020-03-14 12:29:12 -04:00
21 changed files with 120 additions and 90 deletions

View File

@@ -39,6 +39,8 @@ be.check = Check for updates
schematic = Schematic schematic = Schematic
schematic.add = Save Schematic... schematic.add = Save Schematic...
schematics = Schematics schematics = Schematics
schematic.replace = A schematic by that name already exists. Replace it?
schematic.exists = A schematic by that name already exists.
schematic.import = Import Schematic... schematic.import = Import Schematic...
schematic.exportfile = Export File schematic.exportfile = Export File
schematic.importfile = Import File schematic.importfile = Import File

View File

@@ -115,13 +115,13 @@ public class BlockIndexer{
if(structQuadrants == null) return; if(structQuadrants == null) return;
//go through every tile... ouch //go through every tile... ouch
world.tiles.each(tile -> { for(Tile tile : world.tiles){
if(tile.team() == team){ if(tile.team() == team){
int quadrantX = tile.x / quadrantSize; int quadrantX = tile.x / quadrantSize;
int quadrantY = tile.y / quadrantSize; int quadrantY = tile.y / quadrantSize;
structQuadrant(team).set(quadrantX, quadrantY); structQuadrant(team).set(quadrantX, quadrantY);
} }
}); }
} }
/** @return whether this item is present on this map.*/ /** @return whether this item is present on this map.*/

View File

@@ -120,9 +120,9 @@ public class EditorTile extends Tile{
} }
@Override @Override
protected void changed(){ protected void changed(Team team){
if(state.is(State.playing)){ if(state.is(State.playing)){
super.changed(); super.changed(team);
return; return;
} }
@@ -139,7 +139,7 @@ public class EditorTile extends Tile{
Block block = block(); Block block = block();
if(block.hasEntity()){ if(block.hasEntity()){
entity = block.newEntity().init(this, false); entity = block.newEntity().init(this, team, false);
entity.cons(new ConsumeModule(entity)); entity.cons(new ConsumeModule(entity));
if(block.hasItems) entity.items(new ItemModule()); if(block.hasItems) entity.items(new ItemModule());
if(block.hasLiquids) entity.liquids(new LiquidModule()); if(block.hasLiquids) entity.liquids(new LiquidModule());

View File

@@ -52,7 +52,7 @@ public class MapGenerateDialog extends FloatingDialog{
private CachedTile ctile = new CachedTile(){ private CachedTile ctile = new CachedTile(){
//nothing. //nothing.
@Override @Override
protected void changed(){ protected void changed(Team team){
} }
}; };

View File

@@ -94,10 +94,6 @@ abstract class BuilderComp implements Unitc, DrawLayerFlyingc{
//otherwise, update it. //otherwise, update it.
BuildEntity entity = tile.ent(); BuildEntity entity = tile.ent();
if(entity == null){
return;
}
if(dst(tile) <= finalPlaceDst){ if(dst(tile) <= finalPlaceDst){
rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f); rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f);
} }

View File

@@ -11,7 +11,7 @@ import static mindustry.Vars.state;
abstract class TeamComp implements Posc{ abstract class TeamComp implements Posc{
@Import float x, y; @Import float x, y;
Team team = Team.sharded; Team team = Team.derelict;
public @Nullable public @Nullable
Tilec closestCore(){ Tilec closestCore(){

View File

@@ -61,9 +61,10 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
private transient float sleepTime; private transient float sleepTime;
/** Sets this tile entity data to this and adds it if necessary. */ /** Sets this tile entity data to this and adds it if necessary. */
public Tilec init(Tile tile, boolean shouldAdd){ public Tilec init(Tile tile, Team team, boolean shouldAdd){
this.tile = tile; this.tile = tile;
this.block = tile.block(); this.block = tile.block();
this.team = team;
set(tile.drawx(), tile.drawy()); set(tile.drawx(), tile.drawy());
if(block.activeSound != Sounds.none){ if(block.activeSound != Sounds.none){

View File

@@ -61,14 +61,12 @@ public class IndexedRenderer implements Disposable{
updateMatrix(); updateMatrix();
program.bind(); program.bind();
texture.bind(); texture.bind();
program.setUniformMatrix4("u_projTrans", BatchShader.copyTransform(combined)); program.setUniformMatrix4("u_projTrans", BatchShader.copyTransform(combined));
program.setUniformi("u_texture", 0); program.setUniformi("u_texture", 0);
mesh.render(program, Gl.triangles, 0, vertices.length / vsize); mesh.render(program, Gl.triangles, 0, vertices.length / vsize);
} }
public void setColor(Color color){ public void setColor(Color color){

View File

@@ -257,10 +257,19 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(lastSchematic == null) return; if(lastSchematic == null) return;
ui.showTextInput("$schematic.add", "$name", "", text -> { ui.showTextInput("$schematic.add", "$name", "", text -> {
lastSchematic.tags.put("name", text); Schematic replacement = schematics.all().find(s -> s.name().equals(text));
schematics.add(lastSchematic); if(replacement != null){
ui.showInfoFade("$schematic.saved"); ui.showConfirm("$confirm", "$schematic.replace", () -> {
ui.schematics.showInfo(lastSchematic); schematics.overwrite(replacement, lastSchematic);
ui.showInfoFade("$schematic.saved");
ui.schematics.showInfo(replacement);
});
}else{
lastSchematic.tags.put("name", text);
schematics.add(lastSchematic);
ui.showInfoFade("$schematic.saved");
ui.schematics.showInfo(lastSchematic);
}
}); });
} }

View File

@@ -127,6 +127,8 @@ public class Scripts implements Disposable{
if(!dir.exists()) return null; // Mod and folder not found if(!dir.exists()) return null; // Mod and folder not found
return loadSource(script, dir, validator); return loadSource(script, dir, validator);
} }
currentMod = required;
return loadSource(script, required.root.child("scripts"), validator); return loadSource(script, required.root.child("scripts"), validator);
} }

View File

@@ -11,7 +11,6 @@ import arc.scene.ui.TextButton.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.core.GameState.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
@@ -89,6 +88,13 @@ public class SchematicsDialog extends FloatingDialog{
buttons.addImageButton(Icon.pencil, style, () -> { buttons.addImageButton(Icon.pencil, style, () -> {
ui.showTextInput("$schematic.rename", "$name", s.name(), res -> { ui.showTextInput("$schematic.rename", "$name", s.name(), res -> {
Schematic replacement = schematics.all().find(other -> other.name().equals(res) && other != s);
if(replacement != null){
//renaming to an existing schematic is not allowed, as it is not clear how the tags would be merged, and which one should be removed
ui.showErrorMessage("$schematic.exists");
return;
}
s.tags.put("name", res); s.tags.put("name", res);
s.save(); s.save();
rebuildPane[0].run(); rebuildPane[0].run();

View File

@@ -1,5 +1,6 @@
package mindustry.world; package mindustry.world;
import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
@@ -19,7 +20,7 @@ public class CachedTile extends Tile{
} }
@Override @Override
protected void changed(){ protected void changed(Team team){
entity = null; entity = null;
Block block = block(); Block block = block();

View File

@@ -41,7 +41,7 @@ public class Tile implements Position{
this.block = wall; this.block = wall;
//update entity and create it if needed //update entity and create it if needed
changed(); changed(Team.derelict);
} }
public Tile(int x, int y, int floor, int overlay, int wall){ public Tile(int x, int y, int floor, int overlay, int wall){
@@ -163,7 +163,7 @@ public class Tile implements Position{
preChanged(); preChanged();
this.block = type; this.block = type;
this.rotation = rotation == 0 ? 0 : (byte)Mathf.mod(rotation, 4); this.rotation = rotation == 0 ? 0 : (byte)Mathf.mod(rotation, 4);
changed(); changed(team);
if(entity != null){ if(entity != null){
entity.team(team); entity.team(team);
@@ -510,7 +510,7 @@ public class Tile implements Position{
} }
} }
protected void changed(){ protected void changed(Team team){
if(entity != null){ if(entity != null){
entity.remove(); entity.remove();
entity = null; entity = null;
@@ -519,7 +519,7 @@ public class Tile implements Position{
Block block = block(); Block block = block();
if(block.hasEntity()){ if(block.hasEntity()){
entity = block.newEntity().init(this, block.update); entity = block.newEntity().init(this, team, block.update);
entity.cons(new ConsumeModule(entity)); entity.cons(new ConsumeModule(entity));
if(block.hasItems) entity.items(new ItemModule()); if(block.hasItems) entity.items(new ItemModule());
if(block.hasLiquids) entity.liquids(new LiquidModule()); if(block.hasLiquids) entity.liquids(new LiquidModule());

View File

@@ -11,7 +11,6 @@ public class Tiles implements Iterable<Tile>{
public final int width, height; public final int width, height;
private final Tile[] array; private final Tile[] array;
private final TileIterator iterator = new TileIterator();
public Tiles(int width, int height){ public Tiles(int width, int height){
this.array = new Tile[width * height]; this.array = new Tile[width * height];
@@ -73,12 +72,8 @@ public class Tiles implements Iterable<Tile>{
@Override @Override
public Iterator<Tile> iterator(){ public Iterator<Tile> iterator(){
if(iterator.index != 0 && iterator.index != array.length){ //iterating through the entire map is expensive anyway, so a new allocation doesn't make much of a difference
iterator.index = 0; return new TileIterator();
throw new IllegalArgumentException("Double iteration. " + iterator.index + " != " + array.length);
}
iterator.index = 0;
return iterator;
} }
private class TileIterator implements Iterator<Tile>{ private class TileIterator implements Iterator<Tile>{

View File

@@ -42,7 +42,7 @@ public class LiquidSource extends Block{
drawRequestConfigCenter(req, (Content)req.config, "center"); drawRequestConfigCenter(req, (Content)req.config, "center");
} }
class LiquidSourceEntity extends TileEntity{ public class LiquidSourceEntity extends TileEntity{
public @Nullable Liquid source = null; public @Nullable Liquid source = null;
@Override @Override

View File

@@ -179,9 +179,10 @@ public class DesktopLauncher extends ClientLauncher{
static void handleCrash(Throwable e){ static void handleCrash(Throwable e){
Cons<Runnable> dialog = Runnable::run; Cons<Runnable> dialog = Runnable::run;
boolean badGPU = false; boolean badGPU = false;
String total = Strings.getCauses(e).toString();
if(e.getMessage() != null && (e.getMessage().contains("Couldn't create window") || if(total.contains("Couldn't create window") ||
e.getMessage().contains("OpenGL 2.0 or higher") || e.getMessage().toLowerCase().contains("pixel format") || e.getMessage().contains("GLEW"))){ total.contains("OpenGL 2.0 or higher") || total.toLowerCase().contains("pixel format") || total.contains("GLEW")){
dialog.get(() -> message( dialog.get(() -> message(
e.getMessage().contains("Couldn't create window") ? "A graphics initialization error has occured! Try to update your graphics drivers:\n" + e.getMessage() : e.getMessage().contains("Couldn't create window") ? "A graphics initialization error has occured! Try to update your graphics drivers:\n" + e.getMessage() :

View File

@@ -43,6 +43,13 @@ public class ApplicationTests{
net = new Net(null); net = new Net(null);
tree = new FileTree(); tree = new FileTree();
Vars.init(); Vars.init();
world = new World(){
@Override
public float getDarkness(int x, int y){
//for world borders
return 0;
}
};
content.createBaseContent(); content.createBaseContent();
add(logic = new Logic()); add(logic = new Logic());
@@ -124,11 +131,8 @@ public class ApplicationTests{
assertEquals(world.tile(bx, by).team(), Team.sharded); assertEquals(world.tile(bx, by).team(), Team.sharded);
for(int x = bx - 1; x <= bx + 1; x++){ for(int x = bx - 1; x <= bx + 1; x++){
for(int y = by - 1; y <= by + 1; y++){ for(int y = by - 1; y <= by + 1; y++){
if(x == bx && by == y){ assertEquals(world.tile(x, y).block(), Blocks.coreShard);
assertEquals(world.tile(x, y).block(), Blocks.coreShard); assertEquals(world.tile(x, y).entity, world.tile(bx, by).entity);
}else{
assertTrue(world.tile(x, y).block() instanceof BlockPart && world.tile(x, y).link() == world.tile(bx, by));
}
} }
} }
} }
@@ -215,18 +219,18 @@ public class ApplicationTests{
world.tile(0, 0).setBlock(Blocks.conveyor); world.tile(0, 0).setBlock(Blocks.conveyor);
world.tile(0, 0).rotation(0); world.tile(0, 0).rotation(0);
Blocks.conveyor.acceptStack(world.tile(0, 0), Items.copper, 1000, null); world.tile(0, 0).entity.acceptStack(Items.copper, 1000, null);
} }
@Test @Test
void conveyorBench(){ void conveyorBench(){
int[] items = {0}; int[] itemsa = {0};
world.loadMap(testMap); world.loadMap(testMap);
state.set(State.playing); state.set(State.playing);
int length = 128; int length = 128;
world.tile(0, 0).setBlock(Blocks.itemSource); world.tile(0, 0).setBlock(Blocks.itemSource);
world.tile(0, 0).configureAny(Items.copper.id); world.tile(0, 0).configureAny(Items.copper);
Array<Tilec> entities = Array.with(world.tile(0, 0).entity); Array<Tilec> entities = Array.with(world.tile(0, 0).entity);
@@ -236,17 +240,22 @@ public class ApplicationTests{
entities.add(world.tile(i + 1, 0).entity); entities.add(world.tile(i + 1, 0).entity);
} }
world.tile(length + 1, 0).setBlock(new Block("___"){ world.tile(length + 1, 0).setBlock(new Block("___"){{
@Override hasItems = true;
public void handleItem(Tile tile, Tile source, Item item){ entityType = () -> new TileEntity(){
items[0] ++; @Override
} public void handleItem(Tilec source, Item item){
itemsa[0] ++;
}
@Override @Override
public boolean acceptItem(Tile tile, Tile source, Item item){ public boolean acceptItem(Tilec source, Item item){
return true; return true;
} }
}); };
}});
entities.each(Tilec::updateProximity);
//warmup //warmup
for(int i = 0; i < 100000; i++){ for(int i = 0; i < 100000; i++){
@@ -257,8 +266,8 @@ public class ApplicationTests{
for(int i = 0; i < 200000; i++){ for(int i = 0; i < 200000; i++){
entities.each(Tilec::update); entities.each(Tilec::update);
} }
Log.info(Time.elapsed() + "ms to process " + items[0] + " items"); Log.info(Time.elapsed() + "ms to process " + itemsa[0] + " items");
assertTrue(items[0] > 0); assertNotEquals(0, itemsa[0]);
} }
@Test @Test
@@ -337,8 +346,11 @@ public class ApplicationTests{
Builderc d1 = (Builderc)UnitTypes.phantom.create(Team.sharded); Builderc d1 = (Builderc)UnitTypes.phantom.create(Team.sharded);
Builderc d2 = (Builderc)UnitTypes.phantom.create(Team.sharded); Builderc d2 = (Builderc)UnitTypes.phantom.create(Team.sharded);
d1.set(10f, 20f); //infinite build range
d2.set(10f, 20f); state.rules.editor = true;
d1.set(0f, 0f);
d2.set(20f, 20f);
d1.addBuild(new BuildRequest(0, 0, 0, Blocks.copperWallLarge)); d1.addBuild(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
d2.addBuild(new BuildRequest(1, 1, 0, Blocks.copperWallLarge)); d2.addBuild(new BuildRequest(1, 1, 0, Blocks.copperWallLarge));
@@ -349,7 +361,8 @@ public class ApplicationTests{
assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block()); assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block());
assertEquals(Blocks.air, world.tile(2, 2).block()); assertEquals(Blocks.air, world.tile(2, 2).block());
assertTrue(world.tile(1, 1).block() instanceof BlockPart); assertEquals(Blocks.copperWallLarge, world.tile(1, 1).block());
assertEquals(world.tile(1, 1).entity, world.tile(0, 0).entity);
} }
@Test @Test
@@ -375,6 +388,12 @@ public class ApplicationTests{
Time.setDeltaProvider(() -> 9999f); Time.setDeltaProvider(() -> 9999f);
d1.update(); d1.update();
assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block());
assertEquals(Blocks.copperWallLarge, world.tile(1, 1).block());
d2.clearBuilding();
d2.addBuild(new BuildRequest(1, 1));
d2.update(); d2.update();
assertEquals(Blocks.air, world.tile(0, 0).block()); assertEquals(Blocks.air, world.tile(0, 0).block());
@@ -439,16 +458,16 @@ public class ApplicationTests{
assertNotNull(tile.entity, "Tile should have an entity, but does not: " + tile); assertNotNull(tile.entity, "Tile should have an entity, but does not: " + tile);
int deposited = tile.acceptStack(item, capacity - 1, unit); int deposited = tile.entity.acceptStack(item, capacity - 1, unit);
assertEquals(capacity - 1, deposited); assertEquals(capacity - 1, deposited);
tile.handleStack(item, capacity - 1, unit); tile.entity.handleStack(item, capacity - 1, unit);
assertEquals(tile.entity.items().get(item), capacity - 1); assertEquals(tile.entity.items().get(item), capacity - 1);
int overflow = tile.acceptStack(item, 10, unit); int overflow = tile.entity.acceptStack(item, 10, unit);
assertEquals(1, overflow); assertEquals(1, overflow);
tile.handleStack(item, 1, unit); tile.entity.handleStack(item, 1, unit);
assertEquals(capacity, tile.entity.items().get(item)); assertEquals(capacity, tile.entity.items().get(item));
} }
} }

View File

@@ -32,6 +32,7 @@ public class DirectConsumerTests extends PowerTestFixture{
void testUnitFactory(int siliconAmount, int leadAmount, float producedPower, float requestedPower, float expectedSatisfaction){ void testUnitFactory(int siliconAmount, int leadAmount, float producedPower, float requestedPower, float expectedSatisfaction){
Tile consumerTile = createFakeTile(0, 0, new UnitFactory("fakefactory"){{ Tile consumerTile = createFakeTile(0, 0, new UnitFactory("fakefactory"){{
entityType = UnitFactoryEntity::new;
unitType = UnitTypes.spirit; unitType = UnitTypes.spirit;
produceTime = 60; produceTime = 60;
consumes.power(requestedPower); consumes.power(requestedPower);
@@ -44,8 +45,8 @@ public class DirectConsumerTests extends PowerTestFixture{
producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f; producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f;
PowerGraph graph = new PowerGraph(); PowerGraph graph = new PowerGraph();
graph.add(producerTile); graph.add(producerTile.entity);
graph.add(consumerTile); graph.add(consumerTile.entity);
consumerTile.entity.update(); consumerTile.entity.update();
graph.update(); graph.update();

View File

@@ -38,6 +38,7 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
powerProduction = 0.1f; powerProduction = 0.1f;
itemDuration = fakeItemDuration; itemDuration = fakeItemDuration;
maxLiquidGenerate = maximumLiquidUsage; maxLiquidGenerate = maximumLiquidUsage;
entityType = ItemLiquidGeneratorEntity::new;
} }
@Override @Override
@@ -85,13 +86,13 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
final float expectedRemainingLiquidAmount = Math.max(0.0f, availableLiquidAmount - expectedConsumptionPerTick * Time.delta()); final float expectedRemainingLiquidAmount = Math.max(0.0f, availableLiquidAmount - expectedConsumptionPerTick * Time.delta());
createGenerator(inputType); createGenerator(inputType);
assertTrue(generator.acceptLiquid(tile, null, liquid, availableLiquidAmount), inputType + " | " + parameterDescription + ": Liquids which will be declined by the generator don't need to be tested - The code won't be called for those cases."); assertTrue(entity.acceptLiquid(null, liquid, availableLiquidAmount), inputType + " | " + parameterDescription + ": Liquids which will be declined by the generator don't need to be tested - The code won't be called for those cases.");
entity.liquids().add(liquid, availableLiquidAmount); entity.liquids().add(liquid, availableLiquidAmount);
entity.cons().update(); entity.cons().update();
// Perform an update on the generator once - This should use up any resource up to the maximum liquid usage // Perform an update on the generator once - This should use up any resource up to the maximum liquid usage
generator.update(tile); entity.updateTile();
assertEquals(expectedRemainingLiquidAmount, entity.liquids().get(liquid), inputType + " | " + parameterDescription + ": Remaining liquid amount mismatch."); assertEquals(expectedRemainingLiquidAmount, entity.liquids().get(liquid), inputType + " | " + parameterDescription + ": Remaining liquid amount mismatch.");
assertEquals(expectedEfficiency, entity.productionEfficiency, inputType + " | " + parameterDescription + ": Efficiency mismatch."); assertEquals(expectedEfficiency, entity.productionEfficiency, inputType + " | " + parameterDescription + ": Efficiency mismatch.");
@@ -127,7 +128,7 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
final float expectedRemainingItemAmount = Math.max(0, amount - 1); final float expectedRemainingItemAmount = Math.max(0, amount - 1);
createGenerator(inputType); createGenerator(inputType);
assertTrue(generator.acceptItem(tile, null, item), inputType + " | " + parameterDescription + ": Items which will be declined by the generator don't need to be tested - The code won't be called for those cases."); assertTrue(entity.acceptItem(null, item), inputType + " | " + parameterDescription + ": Items which will be declined by the generator don't need to be tested - The code won't be called for those cases.");
if(amount > 0){ if(amount > 0){
entity.items().add(item, amount); entity.items().add(item, amount);
@@ -136,7 +137,7 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
// Perform an update on the generator once - This should use up one or zero items - dependent on if the item is accepted and available or not. // Perform an update on the generator once - This should use up one or zero items - dependent on if the item is accepted and available or not.
try{ try{
generator.update(tile); entity.updateTile();
assertEquals(expectedRemainingItemAmount, entity.items().get(item), inputType + " | " + parameterDescription + ": Remaining item amount mismatch."); assertEquals(expectedRemainingItemAmount, entity.items().get(item), inputType + " | " + parameterDescription + ": Remaining item amount mismatch.");
assertEquals(expectedEfficiency, entity.productionEfficiency, inputType + " | " + parameterDescription + ": Efficiency mismatch."); assertEquals(expectedEfficiency, entity.productionEfficiency, inputType + " | " + parameterDescription + ": Efficiency mismatch.");
@@ -164,16 +165,16 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
// Burn a single coal and test for the duration // Burn a single coal and test for the duration
entity.items().add(Items.coal, 1); entity.items().add(Items.coal, 1);
entity.cons().update(); entity.cons().update();
generator.update(tile); entity.updateTile();
float expectedEfficiency = entity.productionEfficiency; float expectedEfficiency = entity.productionEfficiency;
float currentDuration = 0.0f; float currentDuration = 0.0f;
while((currentDuration += Time.delta()) <= fakeItemDuration){ while((currentDuration += Time.delta()) <= fakeItemDuration){
generator.update(tile); entity.updateTile();
assertEquals(expectedEfficiency, entity.productionEfficiency, "Duration: " + currentDuration); assertEquals(expectedEfficiency, entity.productionEfficiency, "Duration: " + currentDuration);
} }
generator.update(tile); entity.updateTile();
assertEquals(0.0f, entity.productionEfficiency, "Duration: " + currentDuration); assertEquals(0.0f, entity.productionEfficiency, "Duration: " + currentDuration);
} }

View File

@@ -7,13 +7,13 @@ import mindustry.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.power.*; import mindustry.world.blocks.power.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import java.lang.reflect.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
/** /**
@@ -44,18 +44,21 @@ public class PowerTestFixture{
protected static PowerGenerator createFakeProducerBlock(float producedPower){ protected static PowerGenerator createFakeProducerBlock(float producedPower){
return new PowerGenerator("fakegen"){{ return new PowerGenerator("fakegen"){{
entityType = () -> new GeneratorEntity();
powerProduction = producedPower; powerProduction = producedPower;
}}; }};
} }
protected static Battery createFakeBattery(float capacity){ protected static Battery createFakeBattery(float capacity){
return new Battery("fakebattery"){{ return new Battery("fakebattery"){{
entityType = () -> new BatteryEntity();
consumes.powerBuffered(capacity); consumes.powerBuffered(capacity);
}}; }};
} }
protected static Block createFakeDirectConsumer(float powerPerTick){ protected static Block createFakeDirectConsumer(float powerPerTick){
return new PowerBlock("fakedirectconsumer"){{ return new PowerBlock("fakedirectconsumer"){{
entityType = TileEntity::create;
consumes.power(powerPerTick); consumes.power(powerPerTick);
}}; }};
} }
@@ -80,16 +83,11 @@ public class PowerTestFixture{
// Since this part shall not be part of the test and would require more work anyway, we manually set the block and floor // Since this part shall not be part of the test and would require more work anyway, we manually set the block and floor
// through reflections and then simulate part of what the changed() method does. // through reflections and then simulate part of what the changed() method does.
Field field = Tile.class.getDeclaredField("block"); Reflect.set(Tile.class, tile, "block", block);
field.setAccessible(true); Reflect.set(Tile.class, tile, "floor", Blocks.sand);
field.set(tile, block);
field = Tile.class.getDeclaredField("floor");
field.setAccessible(true);
field.set(tile, Blocks.sand);
// Simulate the "changed" method. Calling it through reflections would require half the game to be initialized. // Simulate the "changed" method. Calling it through reflections would require half the game to be initialized.
tile.entity = block.newEntity().init(tile, false); tile.entity = block.newEntity().init(tile, Team.sharded, false);
tile.entity.cons(new ConsumeModule(tile.entity)); tile.entity.cons(new ConsumeModule(tile.entity));
if(block.hasItems) tile.entity.items(new ItemModule()); if(block.hasItems) tile.entity.items(new ItemModule());
if(block.hasLiquids) tile.entity.liquids(new LiquidModule()); if(block.hasLiquids) tile.entity.liquids(new LiquidModule());
@@ -102,7 +100,7 @@ public class PowerTestFixture{
return 1f; return 1f;
} }
}; };
tile.entity.power().graph.add(tile); tile.entity.power().graph.add(tile.entity);
} }
// Assign incredibly high health so the block does not get destroyed on e.g. burning Blast Compound // Assign incredibly high health so the block does not get destroyed on e.g. burning Blast Compound

View File

@@ -58,8 +58,8 @@ public class PowerTests extends PowerTestFixture{
Tile directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requiredPower)); Tile directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requiredPower));
PowerGraph powerGraph = new PowerGraph(); PowerGraph powerGraph = new PowerGraph();
powerGraph.add(producerTile); powerGraph.add(producerTile.entity);
powerGraph.add(directConsumerTile); powerGraph.add(directConsumerTile.entity);
assertEquals(producedPower * Time.delta(), powerGraph.getPowerProduced(), Mathf.FLOAT_ROUNDING_ERROR); assertEquals(producedPower * Time.delta(), powerGraph.getPowerProduced(), Mathf.FLOAT_ROUNDING_ERROR);
assertEquals(requiredPower * Time.delta(), powerGraph.getPowerNeeded(), Mathf.FLOAT_ROUNDING_ERROR); assertEquals(requiredPower * Time.delta(), powerGraph.getPowerNeeded(), Mathf.FLOAT_ROUNDING_ERROR);
@@ -95,18 +95,18 @@ public class PowerTests extends PowerTestFixture{
if(producedPower > 0.0f){ if(producedPower > 0.0f){
Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(producedPower)); Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(producedPower));
producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f; producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f;
powerGraph.add(producerTile); powerGraph.add(producerTile.entity);
} }
Tile directConsumerTile = null; Tile directConsumerTile = null;
if(requestedPower > 0.0f){ if(requestedPower > 0.0f){
directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requestedPower)); directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requestedPower));
powerGraph.add(directConsumerTile); powerGraph.add(directConsumerTile.entity);
} }
float maxCapacity = 100f; float maxCapacity = 100f;
Tile batteryTile = createFakeTile(0, 2, createFakeBattery(maxCapacity)); Tile batteryTile = createFakeTile(0, 2, createFakeBattery(maxCapacity));
batteryTile.entity.power().status = initialBatteryCapacity / maxCapacity; batteryTile.entity.power().status = initialBatteryCapacity / maxCapacity;
powerGraph.add(batteryTile); powerGraph.add(batteryTile.entity);
powerGraph.update(); powerGraph.update();
assertEquals(expectedBatteryCapacity / maxCapacity, batteryTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Expected battery status did not match"); assertEquals(expectedBatteryCapacity / maxCapacity, batteryTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Expected battery status did not match");
@@ -123,14 +123,14 @@ public class PowerTests extends PowerTestFixture{
Tile consumerTile = createFakeTile(0, 1, createFakeDirectConsumer(5.0f)); Tile consumerTile = createFakeTile(0, 1, createFakeDirectConsumer(5.0f));
PowerGraph powerGraph = new PowerGraph(); PowerGraph powerGraph = new PowerGraph();
powerGraph.add(producerTile); powerGraph.add(producerTile.entity);
powerGraph.add(consumerTile); powerGraph.add(consumerTile.entity);
powerGraph.update(); powerGraph.update();
assertEquals(1.0f, consumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR); assertEquals(1.0f, consumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR);
powerGraph.remove(producerTile); powerGraph.remove(producerTile.entity);
powerGraph.add(consumerTile); powerGraph.add(consumerTile.entity);
powerGraph.update(); powerGraph.update();
assertEquals(0.0f, consumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR); assertEquals(0.0f, consumerTile.entity.power().status, Mathf.FLOAT_ROUNDING_ERROR);