Upgradeable cores
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
{fields:[{name:ammo,type:int,size:4},{name:armor,type:float,size:4},{name:controller,type:mindustry.entities.units.UnitController,size:-1},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:isShooting,type:boolean,size:1},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:mounts,type:"mindustry.entities.units.WeaponMount[]",size:-1},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>,size:-1},{name:rotation,type:float,size:4},{name:shield,type:float,size:4},{name:spawnedByCore,type:boolean,size:1},{name:stack,type:mindustry.type.ItemStack,size:-1},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
|
||||||
@@ -665,7 +665,6 @@ setting.effects.name = Display Effects
|
|||||||
setting.destroyedblocks.name = Display Destroyed Blocks
|
setting.destroyedblocks.name = Display Destroyed Blocks
|
||||||
setting.blockstatus.name = Display Block Status
|
setting.blockstatus.name = Display Block Status
|
||||||
setting.conveyorpathfinding.name = Conveyor Placement Pathfinding
|
setting.conveyorpathfinding.name = Conveyor Placement Pathfinding
|
||||||
setting.coreselect.name = Allow Schematic Cores
|
|
||||||
setting.sensitivity.name = Controller Sensitivity
|
setting.sensitivity.name = Controller Sensitivity
|
||||||
setting.saveinterval.name = Save Interval
|
setting.saveinterval.name = Save Interval
|
||||||
setting.seconds = {0} seconds
|
setting.seconds = {0} seconds
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ public class BlockIndexer{
|
|||||||
for(Tile tile : world.tiles){
|
for(Tile tile : world.tiles){
|
||||||
process(tile);
|
process(tile);
|
||||||
|
|
||||||
if(tile.entity != null && tile.entity.damaged()){
|
if(tile.build != null && tile.build.damaged()){
|
||||||
notifyTileDamaged(tile.entity);
|
notifyTileDamaged(tile.build);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tile.drop() != null) allOres.add(tile.drop());
|
if(tile.drop() != null) allOres.add(tile.drop());
|
||||||
@@ -147,7 +147,7 @@ public class BlockIndexer{
|
|||||||
|
|
||||||
TileArray set = damagedTiles[team.id];
|
TileArray set = damagedTiles[team.id];
|
||||||
for(Tile tile : set){
|
for(Tile tile : set){
|
||||||
if((tile.entity == null || tile.entity.team() != team || !tile.entity.damaged()) || tile.block() instanceof BuildBlock){
|
if((tile.build == null || tile.build.team() != team || !tile.build.damaged()) || tile.block() instanceof BuildBlock){
|
||||||
returnArray.add(tile);
|
returnArray.add(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,7 +380,7 @@ public class BlockIndexer{
|
|||||||
GridBits bits = structQuadrant(team);
|
GridBits bits = structQuadrant(team);
|
||||||
|
|
||||||
//fast-set this quadrant to 'occupied' if the tile just placed is already of this team
|
//fast-set this quadrant to 'occupied' if the tile just placed is already of this team
|
||||||
if(tile.team() == team && tile.entity != null && tile.block().targetable){
|
if(tile.team() == team && tile.build != null && tile.block().targetable){
|
||||||
bits.set(quadrantX, quadrantY);
|
bits.set(quadrantX, quadrantY);
|
||||||
continue; //no need to process futher
|
continue; //no need to process futher
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class BuilderAI extends AIController{
|
|||||||
BuildPlan req = builder.buildPlan();
|
BuildPlan req = builder.buildPlan();
|
||||||
|
|
||||||
boolean valid =
|
boolean valid =
|
||||||
(req.tile().entity instanceof BuildEntity && req.tile().<BuildEntity>ent().cblock == req.block) ||
|
(req.tile().build instanceof BuildEntity && req.tile().<BuildEntity>bc().cblock == req.block) ||
|
||||||
(req.breaking ?
|
(req.breaking ?
|
||||||
Build.validBreak(unit.team(), req.x, req.y) :
|
Build.validBreak(unit.team(), req.x, req.y) :
|
||||||
Build.validPlace(req.block, unit.team(), req.x, req.y, req.rotation));
|
Build.validPlace(req.block, unit.team(), req.x, req.y, req.rotation));
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public class SuicideAI extends GroundAI{
|
|||||||
//raycast for target
|
//raycast for target
|
||||||
boolean blocked = Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> {
|
boolean blocked = Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> {
|
||||||
Tile tile = Vars.world.tile(x, y);
|
Tile tile = Vars.world.tile(x, y);
|
||||||
if(tile != null && tile.entity == target) return false;
|
if(tile != null && tile.build == target) return false;
|
||||||
if(tile != null && tile.entity != null && tile.entity.team() != unit.team()){
|
if(tile != null && tile.build != null && tile.build.team() != unit.team()){
|
||||||
blockedByBlock = true;
|
blockedByBlock = true;
|
||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -1270,7 +1270,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
coreFoundation = new CoreBlock("core-foundation"){{
|
coreFoundation = new CoreBlock("core-foundation"){{
|
||||||
requirements(Category.effect, BuildVisibility.hidden, with(Items.copper, 3000, Items.lead, 3000, Items.silicon, 2000));
|
requirements(Category.effect, with(Items.copper, 3000, Items.lead, 3000, Items.silicon, 2000));
|
||||||
|
|
||||||
health = 2000;
|
health = 2000;
|
||||||
itemCapacity = 9000;
|
itemCapacity = 9000;
|
||||||
@@ -1278,7 +1278,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
coreNucleus = new CoreBlock("core-nucleus"){{
|
coreNucleus = new CoreBlock("core-nucleus"){{
|
||||||
requirements(Category.effect, BuildVisibility.hidden, with(Items.copper, 1000, Items.lead, 1000));
|
requirements(Category.effect, with(Items.copper, 1000, Items.lead, 1000));
|
||||||
|
|
||||||
health = 4000;
|
health = 4000;
|
||||||
itemCapacity = 13000;
|
itemCapacity = 13000;
|
||||||
|
|||||||
@@ -144,6 +144,12 @@ public class Fx{
|
|||||||
Lines.circle(e.x, e.y, 4f + e.finpow() * 120f);
|
Lines.circle(e.x, e.y, 4f + e.finpow() * 120f);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
upgradeCore = new Effect(120f, e -> {
|
||||||
|
color(Color.white, Pal.accent, e.fin());
|
||||||
|
alpha(e.fout());
|
||||||
|
Fill.square(e.x, e.y, tilesize / 2f * e.rotation);
|
||||||
|
}),
|
||||||
|
|
||||||
placeBlock = new Effect(16, e -> {
|
placeBlock = new Effect(16, e -> {
|
||||||
color(Pal.accent);
|
color(Pal.accent);
|
||||||
stroke(3f - e.fin() * 2f);
|
stroke(3f - e.fin() * 2f);
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ public class Logic implements ApplicationListener{
|
|||||||
Tile tile = event.tile;
|
Tile tile = event.tile;
|
||||||
Block block = tile.block();
|
Block block = tile.block();
|
||||||
//skip null entities or un-rebuildables, for obvious reasons; also skip client since they can't modify these requests
|
//skip null entities or un-rebuildables, for obvious reasons; also skip client since they can't modify these requests
|
||||||
if(tile.entity == null || !tile.block().rebuildable || net.client()) return;
|
if(tile.build == null || !tile.block().rebuildable || net.client()) return;
|
||||||
|
|
||||||
if(block instanceof BuildBlock){
|
if(block instanceof BuildBlock){
|
||||||
|
|
||||||
BuildEntity entity = tile.ent();
|
BuildEntity entity = tile.bc();
|
||||||
|
|
||||||
//update block to reflect the fact that something was being constructed
|
//update block to reflect the fact that something was being constructed
|
||||||
if(entity.cblock != null && entity.cblock.synthetic()){
|
if(entity.cblock != null && entity.cblock.synthetic()){
|
||||||
@@ -65,7 +65,7 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.blocks.addFirst(new BlockPlan(tile.x, tile.y, tile.rotation(), block.id, tile.entity.config()));
|
data.blocks.addFirst(new BlockPlan(tile.x, tile.y, tile.rotation(), block.id, tile.build.config()));
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(BlockBuildEndEvent.class, event -> {
|
Events.on(BlockBuildEndEvent.class, event -> {
|
||||||
|
|||||||
@@ -425,11 +425,11 @@ public class NetClient implements ApplicationListener{
|
|||||||
for(int i = 0; i < amount; i++){
|
for(int i = 0; i < amount; i++){
|
||||||
int pos = input.readInt();
|
int pos = input.readInt();
|
||||||
Tile tile = world.tile(pos);
|
Tile tile = world.tile(pos);
|
||||||
if(tile == null || tile.entity == null){
|
if(tile == null || tile.build == null){
|
||||||
Log.warn("Missing entity at @. Skipping block snapshot.", tile);
|
Log.warn("Missing entity at @. Skipping block snapshot.", tile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tile.entity.readAll(Reads.get(input), tile.entity.version());
|
tile.build.readAll(Reads.get(input), tile.build.version());
|
||||||
}
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -457,8 +457,8 @@ public class NetClient implements ApplicationListener{
|
|||||||
int pos = input.readInt();
|
int pos = input.readInt();
|
||||||
Tile tile = world.tile(pos);
|
Tile tile = world.tile(pos);
|
||||||
|
|
||||||
if(tile != null && tile.entity != null){
|
if(tile != null && tile.build != null){
|
||||||
tile.entity.items.read(Reads.get(input));
|
tile.build.items.read(Reads.get(input));
|
||||||
}else{
|
}else{
|
||||||
new ItemModule().read(Reads.get(input));
|
new ItemModule().read(Reads.get(input));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class World{
|
|||||||
public Tile Building(int x, int y){
|
public Tile Building(int x, int y){
|
||||||
Tile tile = tiles.get(x, y);
|
Tile tile = tiles.get(x, y);
|
||||||
if(tile == null) return null;
|
if(tile == null) return null;
|
||||||
if(tile.entity != null) return tile.entity.tile();
|
if(tile.build != null) return tile.build.tile();
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,14 +113,14 @@ public class World{
|
|||||||
public Building ent(int x, int y){
|
public Building ent(int x, int y){
|
||||||
Tile tile = tile(x, y);
|
Tile tile = tile(x, y);
|
||||||
if(tile == null) return null;
|
if(tile == null) return null;
|
||||||
return tile.entity;
|
return tile.build;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Building ent(int pos){
|
public Building ent(int pos){
|
||||||
Tile tile = tile(pos);
|
Tile tile = tile(pos);
|
||||||
if(tile == null) return null;
|
if(tile == null) return null;
|
||||||
return tile.entity;
|
return tile.build;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -144,8 +144,8 @@ public class World{
|
|||||||
|
|
||||||
private void clearTileEntities(){
|
private void clearTileEntities(){
|
||||||
for(Tile tile : tiles){
|
for(Tile tile : tiles){
|
||||||
if(tile != null && tile.entity != null){
|
if(tile != null && tile.build != null){
|
||||||
tile.entity.remove();
|
tile.build.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,8 +187,8 @@ public class World{
|
|||||||
|
|
||||||
tile.updateOcclusion();
|
tile.updateOcclusion();
|
||||||
|
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.updateProximity();
|
tile.build.updateProximity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class EditorTile extends Tile{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity = null;
|
build = null;
|
||||||
|
|
||||||
if(block == null) block = Blocks.air;
|
if(block == null) block = Blocks.air;
|
||||||
if(floor == null) floor = (Floor)Blocks.air;
|
if(floor == null) floor = (Floor)Blocks.air;
|
||||||
@@ -123,11 +123,11 @@ public class EditorTile extends Tile{
|
|||||||
Block block = block();
|
Block block = block();
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasEntity()){
|
||||||
entity = entityprov.get().init(this, team, false);
|
build = entityprov.get().init(this, team, false);
|
||||||
entity.cons(new ConsumeModule(entity));
|
build.cons(new ConsumeModule(build));
|
||||||
if(block.hasItems) entity.items(new ItemModule());
|
if(block.hasItems) build.items(new ItemModule());
|
||||||
if(block.hasLiquids) entity.liquids(new LiquidModule());
|
if(block.hasLiquids) build.liquids(new LiquidModule());
|
||||||
if(block.hasPower) entity.power(new PowerModule());
|
if(block.hasPower) build.power(new PowerModule());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -255,8 +255,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
world.endMapLoad();
|
world.endMapLoad();
|
||||||
//add entities so they update. is this really needed?
|
//add entities so they update. is this really needed?
|
||||||
for(Tile tile : world.tiles){
|
for(Tile tile : world.tiles){
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.add();
|
tile.build.add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
|
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
|
||||||
|
|||||||
@@ -265,10 +265,10 @@ public class Damage{
|
|||||||
if(scaledDamage <= 0 || tile == null) continue;
|
if(scaledDamage <= 0 || tile == null) continue;
|
||||||
|
|
||||||
//apply damage to entity if needed
|
//apply damage to entity if needed
|
||||||
if(tile.entity != null && tile.team() != team){
|
if(tile.build != null && tile.team() != team){
|
||||||
int health = (int)tile.entity.health();
|
int health = (int)tile.build.health();
|
||||||
if(tile.entity.health() > 0){
|
if(tile.build.health() > 0){
|
||||||
tile.entity.damage(scaledDamage);
|
tile.build.damage(scaledDamage);
|
||||||
scaledDamage -= health;
|
scaledDamage -= health;
|
||||||
|
|
||||||
if(scaledDamage <= 0) continue;
|
if(scaledDamage <= 0) continue;
|
||||||
@@ -290,8 +290,8 @@ public class Damage{
|
|||||||
for(int dx = -trad; dx <= trad; dx++){
|
for(int dx = -trad; dx <= trad; dx++){
|
||||||
for(int dy = -trad; dy <= trad; dy++){
|
for(int dy = -trad; dy <= trad; dy++){
|
||||||
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
|
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
|
||||||
if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.team())) && Mathf.dst(dx, dy) <= trad){
|
if(tile != null && tile.build != null && (team == null ||team.isEnemy(tile.team())) && Mathf.dst(dx, dy) <= trad){
|
||||||
tile.entity.damage(damage);
|
tile.build.damage(damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class Units{
|
|||||||
/** Returns the neareset damaged tile. */
|
/** Returns the neareset damaged tile. */
|
||||||
public static Building findDamagedTile(Team team, float x, float y){
|
public static Building findDamagedTile(Team team, float x, float y){
|
||||||
Tile tile = Geometry.findClosest(x, y, indexer.getDamaged(team));
|
Tile tile = Geometry.findClosest(x, y, indexer.getDamaged(team));
|
||||||
return tile == null ? null : tile.entity;
|
return tile == null ? null : tile.build;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the neareset ally tile in a range. */
|
/** Returns the neareset ally tile in a range. */
|
||||||
|
|||||||
@@ -100,25 +100,25 @@ abstract class BuilderComp implements Unitc{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tile.entity instanceof BuildEntity && !current.initialized){
|
if(tile.build instanceof BuildEntity && !current.initialized){
|
||||||
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team(), (Builderc)this, current.breaking)));
|
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, team(), (Builderc)this, current.breaking)));
|
||||||
current.initialized = true;
|
current.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if there is no core to build with or no build entity, stop building!
|
//if there is no core to build with or no build entity, stop building!
|
||||||
if((core == null && !infinite) || !(tile.entity instanceof BuildEntity)){
|
if((core == null && !infinite) || !(tile.build instanceof BuildEntity)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//otherwise, update it.
|
//otherwise, update it.
|
||||||
BuildEntity entity = tile.ent();
|
BuildEntity entity = tile.bc();
|
||||||
|
|
||||||
if(current.breaking){
|
if(current.breaking){
|
||||||
entity.deconstruct(base(), core, 1f / entity.buildCost * Time.delta() * type().buildSpeed * state.rules.buildSpeedMultiplier);
|
entity.deconstruct(base(), core, 1f / entity.buildCost * Time.delta() * type().buildSpeed * state.rules.buildSpeedMultiplier);
|
||||||
}else{
|
}else{
|
||||||
if(entity.construct(base(), core, 1f / entity.buildCost * Time.delta() * type().buildSpeed * state.rules.buildSpeedMultiplier, current.hasConfig)){
|
if(entity.construct(base(), core, 1f / entity.buildCost * Time.delta() * type().buildSpeed * state.rules.buildSpeedMultiplier, current.hasConfig)){
|
||||||
if(current.hasConfig){
|
if(current.hasConfig){
|
||||||
Call.onTileConfig(null, tile.entity, current.config);
|
Call.onTileConfig(null, tile.build, current.config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,8 +190,8 @@ abstract class BuilderComp implements Unitc{
|
|||||||
plans.remove(replace);
|
plans.remove(replace);
|
||||||
}
|
}
|
||||||
Tile tile = world.tile(place.x, place.y);
|
Tile tile = world.tile(place.x, place.y);
|
||||||
if(tile != null && tile.entity instanceof BuildEntity){
|
if(tile != null && tile.build instanceof BuildEntity){
|
||||||
place.progress = tile.<BuildEntity>ent().progress;
|
place.progress = tile.<BuildEntity>bc().progress;
|
||||||
}
|
}
|
||||||
if(tail){
|
if(tail){
|
||||||
plans.addLast(place);
|
plans.addLast(place);
|
||||||
|
|||||||
@@ -400,8 +400,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
int trns = block.size/2 + 1;
|
int trns = block.size/2 + 1;
|
||||||
Tile next = tile.getNearby(Geometry.d4(rotation()).x * trns, Geometry.d4(rotation()).y * trns);
|
Tile next = tile.getNearby(Geometry.d4(rotation()).x * trns, Geometry.d4(rotation()).y * trns);
|
||||||
|
|
||||||
if(next != null && next.entity != null && next.entity.team() == team && next.entity.acceptPayload(base(), todump)){
|
if(next != null && next.build != null && next.build.team() == team && next.build.acceptPayload(base(), todump)){
|
||||||
next.entity.handlePayload(base(), todump);
|
next.build.handlePayload(base(), todump);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,8 +485,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
if(next == null) return 0;
|
if(next == null) return 0;
|
||||||
|
|
||||||
if(next.entity != null){
|
if(next.build != null){
|
||||||
return moveLiquid(next.entity, liquid);
|
return moveLiquid(next.build, liquid);
|
||||||
}else if(leakResistance != 100f && !next.block().solid && !next.block().hasLiquids){
|
}else if(leakResistance != 100f && !next.block().solid && !next.block().hasLiquids){
|
||||||
float leakAmount = liquids.get(liquid) / leakResistance;
|
float leakAmount = liquids.get(liquid) / leakResistance;
|
||||||
Puddles.deposit(next, tile, liquid, leakAmount);
|
Puddles.deposit(next, tile, liquid, leakAmount);
|
||||||
@@ -673,8 +673,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
power.graph.remove(base());
|
power.graph.remove(base());
|
||||||
for(int i = 0; i < power.links.size; i++){
|
for(int i = 0; i < power.links.size; i++){
|
||||||
Tile other = world.tile(power.links.get(i));
|
Tile other = world.tile(power.links.get(i));
|
||||||
if(other != null && other.entity != null && other.entity.power != null){
|
if(other != null && other.build != null && other.build.power != null){
|
||||||
other.entity.power.links.removeValue(pos());
|
other.build.power.links.removeValue(pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -693,7 +693,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
for(int i = 0; i < power.links.size; i++){
|
for(int i = 0; i < power.links.size; i++){
|
||||||
Tile link = world.tile(power.links.get(i));
|
Tile link = world.tile(power.links.get(i));
|
||||||
if(link != null && link.entity != null && link.entity.power != null) out.add(link.entity);
|
if(link != null && link.build != null && link.build.power != null) out.add(link.build);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -803,8 +803,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
tempTiles.sort(Structs.comparingFloat(t -> t.dst2(tile)));
|
tempTiles.sort(Structs.comparingFloat(t -> t.dst2(tile)));
|
||||||
if(!tempTiles.isEmpty()){
|
if(!tempTiles.isEmpty()){
|
||||||
Tile toLink = tempTiles.first();
|
Tile toLink = tempTiles.first();
|
||||||
if(!toLink.entity.power.links.contains(pos())){
|
if(!toLink.build.power.links.contains(pos())){
|
||||||
toLink.entity.configureAny(pos());
|
toLink.build.configureAny(pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1125,7 +1125,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
@Replace
|
@Replace
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(){
|
public boolean isValid(){
|
||||||
return tile.entity == base() && !dead();
|
return tile.build == base() && !dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Building entity = tile.entity;
|
Building entity = tile.build;
|
||||||
boolean damage = entity != null;
|
boolean damage = entity != null;
|
||||||
|
|
||||||
float flammability = baseFlammability + puddleFlammability;
|
float flammability = baseFlammability + puddleFlammability;
|
||||||
@@ -59,7 +59,7 @@ abstract class FireComp implements Timedc, Posc, Firec{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(baseFlammability < 0 || block != tile.block()){
|
if(baseFlammability < 0 || block != tile.block()){
|
||||||
baseFlammability = tile.entity == null ? 0 : tile.entity.getFlammability();
|
baseFlammability = tile.build == null ? 0 : tile.build.getFlammability();
|
||||||
block = tile.block();
|
block = tile.block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ abstract class PayloadComp implements Posc, Rotc{
|
|||||||
Tile on = tileOn();
|
Tile on = tileOn();
|
||||||
|
|
||||||
//drop off payload on an acceptor if possible
|
//drop off payload on an acceptor if possible
|
||||||
if(on != null && on.entity != null && on.entity.acceptPayload(on.entity, payload)){
|
if(on != null && on.build != null && on.build.acceptPayload(on.build, payload)){
|
||||||
Fx.unitDrop.at(on.entity);
|
Fx.unitDrop.at(on.build);
|
||||||
on.entity.handlePayload(on.entity, payload);
|
on.build.handlePayload(on.build, payload);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(liquid.temperature > 0.7f && (tile.entity != null) && Mathf.chance(0.3 * Time.delta())){
|
if(liquid.temperature > 0.7f && (tile.build != null) && Mathf.chance(0.3 * Time.delta())){
|
||||||
Fires.create(tile);
|
Fires.create(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ abstract class TrailComp implements Unitc{
|
|||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
@Import float x, y, rotation;
|
@Import float x, y, rotation;
|
||||||
|
|
||||||
transient Trail trail = new Trail(4);
|
transient Trail trail = new Trail(6);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
|
trail.length = type.trailLength;
|
||||||
|
|
||||||
float scale = elevation();
|
float scale = elevation();
|
||||||
float offset = type.engineOffset/2f + type.engineOffset/2f*scale;
|
float offset = type.engineOffset/2f + type.engineOffset/2f*scale;
|
||||||
|
|
||||||
|
|||||||
@@ -181,8 +181,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
|
|
||||||
if(tile != null && isGrounded()){
|
if(tile != null && isGrounded()){
|
||||||
//unit block update
|
//unit block update
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.unitOn(base());
|
tile.build.unitOn(base());
|
||||||
}
|
}
|
||||||
|
|
||||||
//kill when stuck in wall
|
//kill when stuck in wall
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ public class AIController implements UnitController{
|
|||||||
|
|
||||||
protected void targetClosestAllyFlag(BlockFlag flag){
|
protected void targetClosestAllyFlag(BlockFlag flag){
|
||||||
Tile target = Geometry.findClosest(unit.x, unit.y, indexer.getAllied(unit.team, flag));
|
Tile target = Geometry.findClosest(unit.x, unit.y, indexer.getAllied(unit.team, flag));
|
||||||
if(target != null) this.target = target.entity;
|
if(target != null) this.target = target.build;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void targetClosestEnemyFlag(BlockFlag flag){
|
protected void targetClosestEnemyFlag(BlockFlag flag){
|
||||||
Tile target = Geometry.findClosest(unit.x, unit.y, indexer.getEnemy(unit.team, flag));
|
Tile target = Geometry.findClosest(unit.x, unit.y, indexer.getEnemy(unit.team, flag));
|
||||||
if(target != null) this.target = target.entity;
|
if(target != null) this.target = target.build;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean retarget(){
|
protected boolean retarget(){
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import mindustry.content.*;
|
|||||||
import mindustry.mod.Mods.*;
|
import mindustry.mod.Mods.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.power.*;
|
||||||
import mindustry.world.blocks.storage.*;
|
import mindustry.world.blocks.storage.*;
|
||||||
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -29,6 +31,14 @@ public class Schematic implements Publishable, Comparable<Schematic>{
|
|||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float powerProduction(){
|
||||||
|
return tiles.sumf(s -> s.block instanceof PowerGenerator ? ((PowerGenerator)s.block).powerProduction : 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float powerConsumption(){
|
||||||
|
return tiles.sumf(s -> s.block.consumes.has(ConsumeType.power) ? s.block.consumes.getPower().usage : 0f);
|
||||||
|
}
|
||||||
|
|
||||||
public Seq<ItemStack> requirements(){
|
public Seq<ItemStack> requirements(){
|
||||||
IntIntMap amounts = new IntIntMap();
|
IntIntMap amounts = new IntIntMap();
|
||||||
|
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ public class Schematics implements Loadable{
|
|||||||
Building tile = world.ent(cx, cy);
|
Building tile = world.ent(cx, cy);
|
||||||
|
|
||||||
if(tile != null && !counted.contains(tile.pos()) && !(tile.block() instanceof BuildBlock)
|
if(tile != null && !counted.contains(tile.pos()) && !(tile.block() instanceof BuildBlock)
|
||||||
&& (tile.block().isVisible() || (tile.block() instanceof CoreBlock && Core.settings.getBool("coreselect")))){
|
&& (tile.block().isVisible() || (tile.block() instanceof CoreBlock))){
|
||||||
Object config = tile.config();
|
Object config = tile.config();
|
||||||
|
|
||||||
tiles.add(new Stile(tile.block(), tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation()));
|
tiles.add(new Stile(tile.block(), tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation()));
|
||||||
@@ -388,8 +388,8 @@ public class Schematics implements Loadable{
|
|||||||
tile.rotation(st.rotation);
|
tile.rotation(st.rotation);
|
||||||
|
|
||||||
Object config = st.config;
|
Object config = st.config;
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.configureAny(config);
|
tile.build.configureAny(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(st.block instanceof Drill){
|
if(st.block instanceof Drill){
|
||||||
@@ -408,8 +408,8 @@ public class Schematics implements Loadable{
|
|||||||
tile.rotation(st.rotation);
|
tile.rotation(st.rotation);
|
||||||
|
|
||||||
Object config = st.config;
|
Object config = st.config;
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.configureAny(config);
|
tile.build.configureAny(config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,21 +192,21 @@ public class BlockRenderer implements Disposable{
|
|||||||
Tile tile = world.rawTile(x, y);
|
Tile tile = world.rawTile(x, y);
|
||||||
Block block = tile.block();
|
Block block = tile.block();
|
||||||
//link to center
|
//link to center
|
||||||
if(tile.entity != null) tile = tile.entity.tile();
|
if(tile.build != null) tile = tile.build.tile();
|
||||||
|
|
||||||
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal && (tile.entity == null || !processedEntities.contains(tile.entity.id()))){
|
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal && (tile.build == null || !processedEntities.contains(tile.build.id()))){
|
||||||
if(block.expanded || !expanded){
|
if(block.expanded || !expanded){
|
||||||
tileview.add(tile);
|
tileview.add(tile);
|
||||||
if(tile.entity != null) processedEntities.add(tile.entity.id());
|
if(tile.build != null) processedEntities.add(tile.build.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
//lights are drawn even in the expanded range
|
//lights are drawn even in the expanded range
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
lightview.add(tile);
|
lightview.add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tile.entity != null && tile.entity.power != null && tile.entity.power.links.size > 0){
|
if(tile.build != null && tile.build.power != null && tile.build.power.links.size > 0){
|
||||||
for(Building other : tile.entity.getPowerConnections(outArray2)){
|
for(Building other : tile.build.getPowerConnections(outArray2)){
|
||||||
if(other.block() instanceof PowerNode){ //TODO need a generic way to render connections!
|
if(other.block() instanceof PowerNode){ //TODO need a generic way to render connections!
|
||||||
tileview.add(other.tile());
|
tileview.add(other.tile());
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ public class BlockRenderer implements Disposable{
|
|||||||
for(int i = 0; i < tileview.size; i++){
|
for(int i = 0; i < tileview.size; i++){
|
||||||
Tile tile = tileview.items[i];
|
Tile tile = tileview.items[i];
|
||||||
Block block = tile.block();
|
Block block = tile.block();
|
||||||
Building entity = tile.entity;
|
Building entity = tile.build;
|
||||||
|
|
||||||
Draw.z(Layer.block);
|
Draw.z(Layer.block);
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ public class BlockRenderer implements Disposable{
|
|||||||
//draw lights
|
//draw lights
|
||||||
for(int i = 0; i < lightview.size; i++){
|
for(int i = 0; i < lightview.size; i++){
|
||||||
Tile tile = lightview.items[i];
|
Tile tile = lightview.items[i];
|
||||||
Building entity = tile.entity;
|
Building entity = tile.build;
|
||||||
|
|
||||||
if(entity != null){
|
if(entity != null){
|
||||||
entity.drawLight();
|
entity.drawLight();
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import arc.struct.*;
|
|||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
|
|
||||||
public class Trail{
|
public class Trail{
|
||||||
private final int length;
|
public int length;
|
||||||
|
|
||||||
private final Seq<Vec3> points;
|
private final Seq<Vec3> points;
|
||||||
private float lastX = -1, lastY = -1;
|
private float lastX = -1, lastY = -1;
|
||||||
|
|
||||||
|
|||||||
@@ -272,8 +272,8 @@ public class DesktopInput extends InputHandler{
|
|||||||
Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY());
|
Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY());
|
||||||
|
|
||||||
if(cursor != null){
|
if(cursor != null){
|
||||||
if(cursor.entity != null){
|
if(cursor.build != null){
|
||||||
cursorType = cursor.entity.getCursor();
|
cursorType = cursor.build.getCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isPlacing() || !selectRequests.isEmpty()){
|
if(isPlacing() || !selectRequests.isEmpty()){
|
||||||
@@ -292,8 +292,8 @@ public class DesktopInput extends InputHandler{
|
|||||||
cursorType = ui.unloadCursor;
|
cursorType = ui.unloadCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cursor.entity != null && cursor.interactable(player.team()) && !isPlacing() && Math.abs(Core.input.axisTap(Binding.rotate)) > 0 && Core.input.keyDown(Binding.rotateplaced) && cursor.block().rotate){
|
if(cursor.build != null && cursor.interactable(player.team()) && !isPlacing() && Math.abs(Core.input.axisTap(Binding.rotate)) > 0 && Core.input.keyDown(Binding.rotateplaced) && cursor.block().rotate){
|
||||||
Call.rotateBlock(player, cursor.entity, Core.input.axisTap(Binding.rotate) > 0);
|
Call.rotateBlock(player, cursor.build, Core.input.axisTap(Binding.rotate) > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +445,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
deleting = true;
|
deleting = true;
|
||||||
}else if(selected != null){
|
}else if(selected != null){
|
||||||
//only begin shooting if there's no cursor event
|
//only begin shooting if there's no cursor event
|
||||||
if(!tileTapped(selected.entity) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().plans().size == 0 || !player.builder().isBuilding()) && !droppingItem &&
|
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().plans().size == 0 || !player.builder().isBuilding()) && !droppingItem &&
|
||||||
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
|
||||||
isShooting = shouldShoot;
|
isShooting = shouldShoot;
|
||||||
}
|
}
|
||||||
@@ -494,7 +494,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
removeSelection(selectX, selectY, cursorX, cursorY);
|
removeSelection(selectX, selectY, cursorX, cursorY);
|
||||||
}
|
}
|
||||||
|
|
||||||
tryDropItems(selected == null ? null : selected.entity, Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
tryDropItems(selected == null ? null : selected.build, Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||||
|
|
||||||
if(sreq != null){
|
if(sreq != null){
|
||||||
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
|
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
|
||||||
|
|||||||
@@ -85,11 +85,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
@Remote(called = Loc.server, unreliable = true)
|
@Remote(called = Loc.server, unreliable = true)
|
||||||
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
|
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
|
||||||
if(tile == null || tile.entity == null || tile.entity.items == null) return;
|
if(tile == null || tile.build == null || tile.build.items == null) return;
|
||||||
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
|
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
|
||||||
Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, tile, () -> {}));
|
Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, tile, () -> {}));
|
||||||
}
|
}
|
||||||
tile.entity.items.add(item, amount);
|
tile.build.items.add(item, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createItemTransfer(Item item, int amount, float x, float y, Position to, Runnable done){
|
public static void createItemTransfer(Item item, int amount, float x, float y, Position to, Runnable done){
|
||||||
@@ -327,7 +327,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
public boolean requestMatches(BuildPlan request){
|
public boolean requestMatches(BuildPlan request){
|
||||||
Tile tile = world.tile(request.x, request.y);
|
Tile tile = world.tile(request.x, request.y);
|
||||||
return tile != null && tile.block() instanceof BuildBlock && tile.<BuildEntity>ent().cblock == request.block;
|
return tile != null && tile.block() instanceof BuildBlock && tile.<BuildEntity>bc().cblock == request.block;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawBreaking(int x, int y){
|
public void drawBreaking(int x, int y){
|
||||||
@@ -925,7 +925,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
public void breakBlock(int x, int y){
|
public void breakBlock(int x, int y){
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
//TODO hacky
|
//TODO hacky
|
||||||
if(tile != null && tile.entity != null) tile = tile.entity.tile();
|
if(tile != null && tile.build != null) tile = tile.build.tile();
|
||||||
player.builder().addBuild(new BuildPlan(tile.x, tile.y));
|
player.builder().addBuild(new BuildPlan(tile.x, tile.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -496,9 +496,9 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}else{
|
}else{
|
||||||
Tile tile = tileAt(screenX, screenY);
|
Tile tile = tileAt(screenX, screenY);
|
||||||
|
|
||||||
if(tile == null || tile.entity == null) return false;
|
if(tile == null || tile.build == null) return false;
|
||||||
|
|
||||||
tryDropItems(tile.entity, Core.input.mouseWorld(screenX, screenY).x, Core.input.mouseWorld(screenX, screenY).y);
|
tryDropItems(tile.build, Core.input.mouseWorld(screenX, screenY).x, Core.input.mouseWorld(screenX, screenY).y);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -542,7 +542,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
//ignore off-screen taps
|
//ignore off-screen taps
|
||||||
if(cursor == null || Core.scene.hasMouse(x, y)) return false;
|
if(cursor == null || Core.scene.hasMouse(x, y)) return false;
|
||||||
Tile linked = cursor.entity == null ? cursor : cursor.entity.tile();
|
Tile linked = cursor.build == null ? cursor : cursor.build.tile();
|
||||||
|
|
||||||
checkTargets(worldx, worldy);
|
checkTargets(worldx, worldy);
|
||||||
|
|
||||||
@@ -555,7 +555,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
}else if(mode == breaking && validBreak(linked.x,linked.y) && !hasRequest(linked)){
|
}else if(mode == breaking && validBreak(linked.x,linked.y) && !hasRequest(linked)){
|
||||||
//add to selection queue if it's a valid BREAK position
|
//add to selection queue if it's a valid BREAK position
|
||||||
selectRequests.add(new BuildPlan(linked.x, linked.y));
|
selectRequests.add(new BuildPlan(linked.x, linked.y));
|
||||||
}else if(!canTapPlayer(worldx, worldy) && !tileTapped(linked.entity)){
|
}else if(!canTapPlayer(worldx, worldy) && !tileTapped(linked.build)){
|
||||||
tryBeginMine(cursor);
|
tryBeginMine(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,15 +164,15 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
stream.writeShort(tile.blockID());
|
stream.writeShort(tile.blockID());
|
||||||
|
|
||||||
//make note of whether there was an entity here
|
//make note of whether there was an entity here
|
||||||
stream.writeBoolean(tile.entity != null);
|
stream.writeBoolean(tile.build != null);
|
||||||
|
|
||||||
//only write the entity for multiblocks once - in the center
|
//only write the entity for multiblocks once - in the center
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
if(tile.isCenter()){
|
if(tile.isCenter()){
|
||||||
stream.writeBoolean(true);
|
stream.writeBoolean(true);
|
||||||
writeChunk(stream, true, out -> {
|
writeChunk(stream, true, out -> {
|
||||||
out.writeByte(tile.entity.version());
|
out.writeByte(tile.build.version());
|
||||||
tile.entity.writeAll(Writes.get(out));
|
tile.build.writeAll(Writes.get(out));
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
stream.writeBoolean(false);
|
stream.writeBoolean(false);
|
||||||
@@ -249,7 +249,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
try{
|
try{
|
||||||
readChunk(stream, true, in -> {
|
readChunk(stream, true, in -> {
|
||||||
byte revision = in.readByte();
|
byte revision = in.readByte();
|
||||||
tile.entity.readAll(Reads.get(in), revision);
|
tile.build.readAll(Reads.get(in), revision);
|
||||||
});
|
});
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
throw new IOException("Failed to read tile entity of block: " + block, e);
|
throw new IOException("Failed to read tile entity of block: " + block, e);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public abstract class LegacySaveVersion extends SaveVersion{
|
|||||||
if(block == null) block = Blocks.air;
|
if(block == null) block = Blocks.air;
|
||||||
|
|
||||||
//occupied by multiblock part
|
//occupied by multiblock part
|
||||||
boolean occupied = tile.entity != null && !tile.isCenter() && (tile.entity.block() == block || block == Blocks.air);
|
boolean occupied = tile.build != null && !tile.isCenter() && (tile.build.block() == block || block == Blocks.air);
|
||||||
|
|
||||||
//do not override occupied cells
|
//do not override occupied cells
|
||||||
if(!occupied){
|
if(!occupied){
|
||||||
@@ -66,7 +66,7 @@ public abstract class LegacySaveVersion extends SaveVersion{
|
|||||||
readChunk(stream, true, in -> {
|
readChunk(stream, true, in -> {
|
||||||
byte version = in.readByte();
|
byte version = in.readByte();
|
||||||
//legacy impl of Building#read()
|
//legacy impl of Building#read()
|
||||||
tile.entity.health(stream.readUnsignedShort());
|
tile.build.health(stream.readUnsignedShort());
|
||||||
byte packedrot = stream.readByte();
|
byte packedrot = stream.readByte();
|
||||||
byte team = Pack.leftByte(packedrot) == 8 ? stream.readByte() : Pack.leftByte(packedrot);
|
byte team = Pack.leftByte(packedrot) == 8 ? stream.readByte() : Pack.leftByte(packedrot);
|
||||||
byte rotation = Pack.rightByte(packedrot);
|
byte rotation = Pack.rightByte(packedrot);
|
||||||
@@ -74,13 +74,13 @@ public abstract class LegacySaveVersion extends SaveVersion{
|
|||||||
tile.setTeam(Team.get(team));
|
tile.setTeam(Team.get(team));
|
||||||
tile.rotation(rotation);
|
tile.rotation(rotation);
|
||||||
|
|
||||||
if(tile.entity.items != null) tile.entity.items.read(Reads.get(stream));
|
if(tile.build.items != null) tile.build.items.read(Reads.get(stream));
|
||||||
if(tile.entity.power != null) tile.entity.power.read(Reads.get(stream));
|
if(tile.build.power != null) tile.build.power.read(Reads.get(stream));
|
||||||
if(tile.entity.liquids != null) tile.entity.liquids.read(Reads.get(stream));
|
if(tile.build.liquids != null) tile.build.liquids.read(Reads.get(stream));
|
||||||
if(tile.entity.cons() != null) tile.entity.cons().read(Reads.get(stream));
|
if(tile.build.cons() != null) tile.build.cons().read(Reads.get(stream));
|
||||||
|
|
||||||
//read only from subclasses!
|
//read only from subclasses!
|
||||||
tile.entity.read(Reads.get(in), version);
|
tile.build.read(Reads.get(in), version);
|
||||||
});
|
});
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
throw new IOException("Failed to read tile entity of block: " + block, e);
|
throw new IOException("Failed to read tile entity of block: " + block, e);
|
||||||
|
|||||||
@@ -47,16 +47,16 @@ public class SectorDamage{
|
|||||||
float resultDamage = currDamage;
|
float resultDamage = currDamage;
|
||||||
|
|
||||||
//damage the tile if it's not friendly
|
//damage the tile if it's not friendly
|
||||||
if(other.entity != null && other.team() != state.rules.waveTeam){
|
if(other.build != null && other.team() != state.rules.waveTeam){
|
||||||
resultDamage -= other.entity.health();
|
resultDamage -= other.build.health();
|
||||||
|
|
||||||
if(direct){
|
if(direct){
|
||||||
other.entity.damage(currDamage);
|
other.build.damage(currDamage);
|
||||||
}else{ //indirect damage happens at game load time
|
}else{ //indirect damage happens at game load time
|
||||||
other.entity.health(other.entity.health() - currDamage);
|
other.build.health(other.build.health() - currDamage);
|
||||||
|
|
||||||
//remove the block when destroyed
|
//remove the block when destroyed
|
||||||
if(other.entity.health() < 0){
|
if(other.build.health() < 0){
|
||||||
//rubble currently disabled
|
//rubble currently disabled
|
||||||
//if(!other.floor().solid && !other.floor().isLiquid && Mathf.chance(0.4)){
|
//if(!other.floor().solid && !other.floor().isLiquid && Mathf.chance(0.4)){
|
||||||
// Effects.rubble(other.entity.x(), other.entity.y(), other.block().size);
|
// Effects.rubble(other.entity.x(), other.entity.y(), other.block().size);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class RandomItemFilter extends GenerateFilter{
|
|||||||
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock)){
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock)){
|
||||||
for(ItemStack stack : drops){
|
for(ItemStack stack : drops){
|
||||||
if(Mathf.chance(chance)){
|
if(Mathf.chance(chance)){
|
||||||
tile.entity.items.add(stack.item, Math.min(Mathf.random(stack.amount), tile.block().itemCapacity));
|
tile.build.items.add(stack.item, Math.min(Mathf.random(stack.amount), tile.block().itemCapacity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class BaseGenerator{
|
|||||||
Schematics.placeLoadout(coreschem.schematic, tile.x, tile.y, team, coreschem.required instanceof Item ? ores.get((Item)coreschem.required) : Blocks.oreCopper);
|
Schematics.placeLoadout(coreschem.schematic, tile.x, tile.y, team, coreschem.required instanceof Item ? ores.get((Item)coreschem.required) : Blocks.oreCopper);
|
||||||
|
|
||||||
//fill core with every type of item (even non-material)
|
//fill core with every type of item (even non-material)
|
||||||
Building entity = tile.entity;
|
Building entity = tile.build;
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
entity.items.add(item, entity.block().itemCapacity);
|
entity.items.add(item, entity.block().itemCapacity);
|
||||||
}
|
}
|
||||||
@@ -130,9 +130,11 @@ public class BaseGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void postGenerate(){
|
public void postGenerate(){
|
||||||
|
if(tiles == null) return;
|
||||||
|
|
||||||
for(Tile tile : tiles){
|
for(Tile tile : tiles){
|
||||||
if(tile.isCenter() && tile.block() instanceof PowerNode){
|
if(tile.isCenter() && tile.block() instanceof PowerNode){
|
||||||
tile.entity.placed();
|
tile.build.placed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class FileMapGenerator implements WorldGenerator{
|
|||||||
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && state.hasSector()){
|
if(tile.block() instanceof StorageBlock && !(tile.block() instanceof CoreBlock) && state.hasSector()){
|
||||||
for(Content content : state.getSector().data.resources){
|
for(Content content : state.getSector().data.resources){
|
||||||
if(content instanceof Item && Mathf.chance(0.3)){
|
if(content instanceof Item && Mathf.chance(0.3)){
|
||||||
tile.entity.items.add((Item)content, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
tile.build.items.add((Item)content, Math.min(Mathf.random(500), tile.block().itemCapacity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,6 +293,8 @@ public class TODOPlanetGenerator extends PlanetGenerator{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postGenerate(Tiles tiles){
|
public void postGenerate(Tiles tiles){
|
||||||
basegen.postGenerate();
|
if(sector.hasEnemyBase()){
|
||||||
|
basegen.postGenerate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
public Color lightColor = Pal.powerLight;
|
public Color lightColor = Pal.powerLight;
|
||||||
public boolean drawCell = true, drawItems = true;
|
public boolean drawCell = true, drawItems = true;
|
||||||
public int parts = 0;
|
public int parts = 0;
|
||||||
|
public int trailLength = 5;
|
||||||
|
|
||||||
public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
|
public ObjectSet<StatusEffect> immunities = new ObjectSet<>();
|
||||||
public Sound deathSound = Sounds.bang;
|
public Sound deathSound = Sounds.bang;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import arc.*;
|
|||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.Texture.*;
|
import arc.graphics.Texture.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.scene.style.*;
|
import arc.scene.style.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.ImageButton.*;
|
import arc.scene.ui.ImageButton.*;
|
||||||
@@ -348,6 +349,26 @@ public class SchematicsDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
cont.row();
|
||||||
|
float cons = schem.powerConsumption(), prod = schem.powerProduction();
|
||||||
|
if(!Mathf.zero(cons) || !Mathf.zero(prod)){
|
||||||
|
cont.table(t -> {
|
||||||
|
|
||||||
|
if(!Mathf.zero(prod)){
|
||||||
|
t.image(Icon.powerSmall).color(Pal.powerLight).padRight(3);
|
||||||
|
t.add("+" + Strings.autoFixed(prod, 2)).color(Pal.powerLight).left();
|
||||||
|
|
||||||
|
if(!Mathf.zero(cons)){
|
||||||
|
t.add().width(15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Mathf.zero(cons)){
|
||||||
|
t.image(Icon.powerSmall).color(Pal.remove).padRight(3);
|
||||||
|
t.add("-" + Strings.autoFixed(cons, 2)).color(Pal.remove).left();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
game.checkPref("savecreate", true);
|
game.checkPref("savecreate", true);
|
||||||
game.checkPref("blockreplace", true);
|
game.checkPref("blockreplace", true);
|
||||||
game.checkPref("conveyorpathfinding", true);
|
game.checkPref("conveyorpathfinding", true);
|
||||||
game.checkPref("coreselect", false);
|
|
||||||
game.checkPref("hints", true);
|
game.checkPref("hints", true);
|
||||||
if(!mobile){
|
if(!mobile){
|
||||||
game.checkPref("buildautopause", false);
|
game.checkPref("buildautopause", false);
|
||||||
|
|||||||
@@ -68,10 +68,7 @@ public class HudFragment extends Fragment{
|
|||||||
cont.top().left();
|
cont.top().left();
|
||||||
|
|
||||||
if(mobile){
|
if(mobile){
|
||||||
|
cont.table(select -> {
|
||||||
{
|
|
||||||
Table select = new Table();
|
|
||||||
|
|
||||||
select.left();
|
select.left();
|
||||||
select.defaults().size(dsize).left();
|
select.defaults().size(dsize).left();
|
||||||
|
|
||||||
@@ -118,28 +115,7 @@ public class HudFragment extends Fragment{
|
|||||||
});
|
});
|
||||||
|
|
||||||
select.image().color(Pal.gray).width(4f).fillY();
|
select.image().color(Pal.gray).width(4f).fillY();
|
||||||
|
});
|
||||||
float size = Scl.scl(dsize);
|
|
||||||
Seq<Element> children = new Seq<>(select.getChildren());
|
|
||||||
|
|
||||||
//now, you may be wondering, why is this necessary? the answer is, I don't know, but it fixes layout issues somehow
|
|
||||||
int index = 0;
|
|
||||||
for(Element elem : children){
|
|
||||||
int fi = index++;
|
|
||||||
parent.addChild(elem);
|
|
||||||
elem.visible(() -> {
|
|
||||||
if(fi < 5){
|
|
||||||
elem.setSize(size);
|
|
||||||
}else{
|
|
||||||
elem.setSize(Scl.scl(4f), size);
|
|
||||||
}
|
|
||||||
elem.setPosition(fi * size, Core.graphics.getHeight(), Align.topLeft);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cont.add().size(dsize * 5 + 3, dsize).left();
|
|
||||||
}
|
|
||||||
|
|
||||||
cont.row();
|
cont.row();
|
||||||
cont.image().height(4f).color(Pal.gray).fillX();
|
cont.image().height(4f).color(Pal.gray).fillX();
|
||||||
@@ -363,10 +339,8 @@ public class HudFragment extends Fragment{
|
|||||||
parent.fill(t -> {
|
parent.fill(t -> {
|
||||||
t.bottom().visible(() -> state.isCampaign() && player.team().core() != null);
|
t.bottom().visible(() -> state.isCampaign() && player.team().core() != null);
|
||||||
|
|
||||||
t.button("test launch", Icon.warning, () -> {
|
t.button("test launch", Icon.warning, () -> ui.planet.show(state.getSector(), player.team().core()))
|
||||||
ui.planet.show(state.getSector(), player.team().core());
|
.width(150f).disabled(b -> player.team().core() == null || !player.team().core().items.has(player.team().core().block.requirements)); //disable core when missing resources for launch
|
||||||
}).width(150f)
|
|
||||||
.disabled(b -> player.team().core() == null || !player.team().core().items.has(player.team().core().block.requirements)); //disable core when missing resources for launch
|
|
||||||
});
|
});
|
||||||
|
|
||||||
blockfrag.build(parent);
|
blockfrag.build(parent);
|
||||||
|
|||||||
@@ -450,9 +450,9 @@ public class PlacementFragment extends Fragment{
|
|||||||
Tile hoverTile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
Tile hoverTile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||||
if(hoverTile != null){
|
if(hoverTile != null){
|
||||||
//if the tile has an entity, display it
|
//if the tile has an entity, display it
|
||||||
if(hoverTile.entity != null){
|
if(hoverTile.build != null){
|
||||||
hoverTile.entity.updateFlow(true);
|
hoverTile.build.updateFlow(true);
|
||||||
return hoverTile.entity;
|
return hoverTile.build;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the tile has a drop, display the drop
|
//if the tile has a drop, display the drop
|
||||||
|
|||||||
@@ -198,8 +198,8 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
public void drawBase(Tile tile){
|
public void drawBase(Tile tile){
|
||||||
//delegates to entity unless it is null
|
//delegates to entity unless it is null
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.draw();
|
tile.build.draw();
|
||||||
}else{
|
}else{
|
||||||
Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.rotation * 90 : 0);
|
Draw.rect(region, tile.drawx(), tile.drawy(), rotate ? tile.rotation * 90 : 0);
|
||||||
}
|
}
|
||||||
@@ -255,11 +255,11 @@ public class Block extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TextureRegion getDisplayIcon(Tile tile){
|
public TextureRegion getDisplayIcon(Tile tile){
|
||||||
return tile.entity == null ? icon(Cicon.medium) : tile.entity.getDisplayIcon();
|
return tile.build == null ? icon(Cicon.medium) : tile.build.getDisplayIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayName(Tile tile){
|
public String getDisplayName(Tile tile){
|
||||||
return tile.entity == null ? localizedName : tile.entity.getDisplayName();
|
return tile.build == null ? localizedName : tile.build.getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return a custom minimap color for this or 0 to use default colors. */
|
/** @return a custom minimap color for this or 0 to use default colors. */
|
||||||
@@ -333,7 +333,7 @@ public class Block extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canReplace(Block other){
|
public boolean canReplace(Block other){
|
||||||
return (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group;
|
return (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group && size == other.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return a possible replacement for this block when placed in a line by the player. */
|
/** @return a possible replacement for this block when placed in a line by the player. */
|
||||||
@@ -479,6 +479,11 @@ public class Block extends UnlockableContent{
|
|||||||
return isVisible() && buildPlaceability.placeable() && !state.rules.bannedBlocks.contains(this);
|
return isVisible() && buildPlaceability.placeable() && !state.rules.bannedBlocks.contains(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called when building of this block begins. */
|
||||||
|
public void placeBegan(Tile tile, Block previous){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** @return a message detailing why this block can't be placed. */
|
/** @return a message detailing why this block can't be placed. */
|
||||||
public String unplaceableMessage(){
|
public String unplaceableMessage(){
|
||||||
return state.rules.bannedBlocks.contains(this) ? Core.bundle.get("banned") : buildPlaceability.message();
|
return state.rules.bannedBlocks.contains(this) ? Core.bundle.get("banned") : buildPlaceability.message();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mindustry.world;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
@@ -25,8 +26,8 @@ public class Build{
|
|||||||
//this should never happen, but it doesn't hurt to check for links
|
//this should never happen, but it doesn't hurt to check for links
|
||||||
float prevPercent = 1f;
|
float prevPercent = 1f;
|
||||||
|
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
prevPercent = tile.entity.healthf();
|
prevPercent = tile.build.healthf();
|
||||||
}
|
}
|
||||||
|
|
||||||
int rotation = tile.rotation();
|
int rotation = tile.rotation();
|
||||||
@@ -34,8 +35,8 @@ public class Build{
|
|||||||
Block sub = BuildBlock.get(previous.size);
|
Block sub = BuildBlock.get(previous.size);
|
||||||
|
|
||||||
tile.setBlock(sub, team, rotation);
|
tile.setBlock(sub, team, rotation);
|
||||||
tile.<BuildEntity>ent().setDeconstruct(previous);
|
tile.<BuildEntity>bc().setDeconstruct(previous);
|
||||||
tile.entity.health(tile.entity.maxHealth() * prevPercent);
|
tile.build.health(tile.build.maxHealth() * prevPercent);
|
||||||
|
|
||||||
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true)));
|
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, true)));
|
||||||
}
|
}
|
||||||
@@ -56,7 +57,9 @@ public class Build{
|
|||||||
Block sub = BuildBlock.get(result.size);
|
Block sub = BuildBlock.get(result.size);
|
||||||
|
|
||||||
tile.setBlock(sub, team, rotation);
|
tile.setBlock(sub, team, rotation);
|
||||||
tile.<BuildEntity>ent().setConstruct(previous, result);
|
tile.<BuildEntity>bc().setConstruct(previous, result);
|
||||||
|
|
||||||
|
result.placeBegan(tile, previous);
|
||||||
|
|
||||||
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, false)));
|
Core.app.post(() -> Events.fire(new BlockBuildBeginEvent(tile, team, false)));
|
||||||
}
|
}
|
||||||
@@ -80,14 +83,33 @@ public class Build{
|
|||||||
|
|
||||||
if(tile == null) return false;
|
if(tile == null) return false;
|
||||||
|
|
||||||
//ca check
|
//campaign darkness check
|
||||||
if(world.getDarkness(x, y) >= 3){
|
if(world.getDarkness(x, y) >= 3){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type.isMultiblock()){
|
if(type.isMultiblock()){
|
||||||
if((type.canReplace(tile.block()) || (tile.block instanceof BuildBlock && tile.<BuildEntity>ent().cblock == type)) && tile.block().size == type.size && type.canPlaceOn(tile, team) && tile.interactable(team)){
|
if((type.canReplace(tile.block()) || (tile.block instanceof BuildBlock && tile.<BuildEntity>bc().cblock == type)) &&
|
||||||
return true;
|
type.canPlaceOn(tile, team) && tile.interactable(team)){
|
||||||
|
|
||||||
|
//if the block can be replaced but the sizes differ, check all the spaces around the block to make sure it can fit
|
||||||
|
if(type.size != tile.block().size){
|
||||||
|
int offsetx = -(type.size - 1) / 2;
|
||||||
|
int offsety = -(type.size - 1) / 2;
|
||||||
|
|
||||||
|
//this does not check *all* the conditions for placeability yet
|
||||||
|
for(int dx = 0; dx < type.size; dx++){
|
||||||
|
for(int dy = 0; dy < type.size; dy++){
|
||||||
|
int wx = dx + offsetx + x, wy = dy + offsety + y;
|
||||||
|
|
||||||
|
Tile check = world.tile(wx, wy);
|
||||||
|
if(check == null || (!check.block.alwaysReplace && check.block != tile.block)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//make sure that the new block can fit the old one
|
||||||
|
return type.bounds(x, y, Tmp.r1).grow(0.01f).contains(tile.block.bounds(tile.centerX(), tile.centerY(), Tmp.r2));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO should water blocks be placeable here?
|
//TODO should water blocks be placeable here?
|
||||||
@@ -106,7 +128,7 @@ public class Build{
|
|||||||
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
|
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
|
||||||
if(
|
if(
|
||||||
other == null ||
|
other == null ||
|
||||||
(other.block() != Blocks.air && !other.block().alwaysReplace) ||
|
!other.block().alwaysReplace ||
|
||||||
!other.floor().placeableOn ||
|
!other.floor().placeableOn ||
|
||||||
(other.floor().isDeep() && !type.floating && !type.requiresWater) ||
|
(other.floor().isDeep() && !type.floating && !type.requiresWater) ||
|
||||||
(type.requiresWater && tile.floor().liquidDrop != Liquids.water)
|
(type.requiresWater && tile.floor().liquidDrop != Liquids.water)
|
||||||
@@ -122,7 +144,7 @@ public class Build{
|
|||||||
&& (!tile.floor().isDeep() || type.floating || type.requiresWater)
|
&& (!tile.floor().isDeep() || type.floating || type.requiresWater)
|
||||||
&& tile.floor().placeableOn
|
&& tile.floor().placeableOn
|
||||||
&& (!type.requiresWater || tile.floor().liquidDrop == Liquids.water)
|
&& (!type.requiresWater || tile.floor().liquidDrop == Liquids.water)
|
||||||
&& (((type.canReplace(tile.block()) || (tile.block instanceof BuildBlock && tile.<BuildEntity>ent().cblock == type))
|
&& (((type.canReplace(tile.block()) || (tile.block instanceof BuildBlock && tile.<BuildEntity>bc().cblock == type))
|
||||||
&& !(type == tile.block() && rotation == tile.rotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air)
|
&& !(type == tile.block() && rotation == tile.rotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air)
|
||||||
&& tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile, team);
|
&& tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile, team);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,19 +22,19 @@ public class CachedTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeEntity(Team team, Prov<Building> entityprov){
|
protected void changeEntity(Team team, Prov<Building> entityprov){
|
||||||
entity = null;
|
build = null;
|
||||||
|
|
||||||
Block block = block();
|
Block block = block();
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasEntity()){
|
||||||
Building n = entityprov.get();
|
Building n = entityprov.get();
|
||||||
n.cons(new ConsumeModule(entity));
|
n.cons(new ConsumeModule(build));
|
||||||
n.tile(this);
|
n.tile(this);
|
||||||
n.block(block);
|
n.block(block);
|
||||||
if(block.hasItems) n.items(new ItemModule());
|
if(block.hasItems) n.items(new ItemModule());
|
||||||
if(block.hasLiquids) n.liquids(new LiquidModule());
|
if(block.hasLiquids) n.liquids(new LiquidModule());
|
||||||
if(block.hasPower) n.power(new PowerModule());
|
if(block.hasPower) n.power(new PowerModule());
|
||||||
entity = n;
|
build = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
/** Tile traversal cost. */
|
/** Tile traversal cost. */
|
||||||
public short cost = 1;
|
public short cost = 1;
|
||||||
/** Tile entity, usually null. */
|
/** Tile entity, usually null. */
|
||||||
public @Nullable Building entity;
|
public @Nullable Building build;
|
||||||
public short x, y;
|
public short x, y;
|
||||||
protected @NonNull Block block;
|
protected @NonNull Block block;
|
||||||
protected @NonNull Floor floor;
|
protected @NonNull Floor floor;
|
||||||
@@ -105,9 +105,11 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convenience method that returns the building of this tile with a cast.
|
||||||
|
* Method name is shortened to prevent conflict. */
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Building> T ent(){
|
public <T extends Building> T bc(){
|
||||||
return (T)entity;
|
return (T)build;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float worldx(){
|
public float worldx(){
|
||||||
@@ -148,17 +150,25 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Team team(){
|
public Team team(){
|
||||||
return entity == null ? Team.derelict : entity.team();
|
return build == null ? Team.derelict : build.team();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTeam(Team team){
|
public void setTeam(Team team){
|
||||||
if(entity != null){
|
if(build != null){
|
||||||
entity.team(team);
|
build.team(team);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCenter(){
|
public boolean isCenter(){
|
||||||
return entity == null || entity.tile() == this;
|
return build == null || build.tile() == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int centerX(){
|
||||||
|
return build == null ? x : build.tile.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int centerY(){
|
||||||
|
return build == null ? y : build.tile.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getTeamID(){
|
public byte getTeamID(){
|
||||||
@@ -177,15 +187,15 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
preChanged();
|
preChanged();
|
||||||
changeEntity(team, entityprov);
|
changeEntity(team, entityprov);
|
||||||
|
|
||||||
if(entity != null){
|
if(build != null){
|
||||||
entity.team(team);
|
build.team(team);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up multiblock
|
//set up multiblock
|
||||||
if(block.isMultiblock()){
|
if(block.isMultiblock()){
|
||||||
int offsetx = -(block.size - 1) / 2;
|
int offsetx = -(block.size - 1) / 2;
|
||||||
int offsety = -(block.size - 1) / 2;
|
int offsety = -(block.size - 1) / 2;
|
||||||
Building entity = this.entity;
|
Building entity = this.build;
|
||||||
Block block = this.block;
|
Block block = this.block;
|
||||||
|
|
||||||
//two passes: first one clears, second one sets
|
//two passes: first one clears, second one sets
|
||||||
@@ -204,7 +214,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}else{
|
}else{
|
||||||
//second pass: assign changed data
|
//second pass: assign changed data
|
||||||
//assign entity and type to blocks, so they act as proxies for this one
|
//assign entity and type to blocks, so they act as proxies for this one
|
||||||
other.entity = entity;
|
other.build = entity;
|
||||||
other.block = block;
|
other.block = block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +223,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.entity = entity;
|
this.build = entity;
|
||||||
this.block = block;
|
this.block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,8 +245,8 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
this.overlay = (Floor)Blocks.air;
|
this.overlay = (Floor)Blocks.air;
|
||||||
|
|
||||||
recache();
|
recache();
|
||||||
if(entity != null){
|
if(build != null){
|
||||||
entity.onProximityUpdate();
|
build.onProximityUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +352,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean solid(){
|
public boolean solid(){
|
||||||
return block.solid || (entity != null && entity.checkSolid());
|
return block.solid || (build != null && build.checkSolid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean breakable(){
|
public boolean breakable(){
|
||||||
@@ -497,15 +507,15 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void preChanged(){
|
protected void preChanged(){
|
||||||
if(entity != null){
|
if(build != null){
|
||||||
//only call removed() for the center block - this only gets called once.
|
//only call removed() for the center block - this only gets called once.
|
||||||
entity.onRemoved();
|
build.onRemoved();
|
||||||
entity.removeFromProximity();
|
build.removeFromProximity();
|
||||||
|
|
||||||
//remove this tile's dangling entities
|
//remove this tile's dangling entities
|
||||||
if(entity.block().isMultiblock()){
|
if(build.block().isMultiblock()){
|
||||||
int cx = entity.tileX(), cy = entity.tileY();
|
int cx = build.tileX(), cy = build.tileY();
|
||||||
int size = entity.block.size;
|
int size = build.block.size;
|
||||||
int offsetx = -(size - 1) / 2;
|
int offsetx = -(size - 1) / 2;
|
||||||
int offsety = -(size - 1) / 2;
|
int offsety = -(size - 1) / 2;
|
||||||
for(int dx = 0; dx < size; dx++){
|
for(int dx = 0; dx < size; dx++){
|
||||||
@@ -514,7 +524,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
if(other != null){
|
if(other != null){
|
||||||
//reset entity and block *manually* - thus, preChanged() will not be called anywhere else, for multiblocks
|
//reset entity and block *manually* - thus, preChanged() will not be called anywhere else, for multiblocks
|
||||||
if(other != this){ //do not remove own entity so it can be processed in changed()
|
if(other != this){ //do not remove own entity so it can be processed in changed()
|
||||||
other.entity = null;
|
other.build = null;
|
||||||
other.block = Blocks.air;
|
other.block = Blocks.air;
|
||||||
|
|
||||||
//manually call changed event
|
//manually call changed event
|
||||||
@@ -535,10 +545,10 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void changeEntity(Team team, Prov<Building> entityprov){
|
protected void changeEntity(Team team, Prov<Building> entityprov){
|
||||||
if(entity != null){
|
if(build != null){
|
||||||
int size = entity.block.size;
|
int size = build.block.size;
|
||||||
entity.remove();
|
build.remove();
|
||||||
entity = null;
|
build = null;
|
||||||
|
|
||||||
//update edge entities
|
//update edge entities
|
||||||
tileSet.clear();
|
tileSet.clear();
|
||||||
@@ -557,14 +567,14 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasEntity()){
|
||||||
entity = entityprov.get().init(this, team, block.update);
|
build = entityprov.get().init(this, team, block.update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void changed(){
|
protected void changed(){
|
||||||
if(!world.isGenerating()){
|
if(!world.isGenerating()){
|
||||||
if(entity != null){
|
if(build != null){
|
||||||
entity.updateProximity();
|
build.updateProximity();
|
||||||
}else{
|
}else{
|
||||||
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
//since the entity won't update proximity for us, update proximity for all nearby tiles manually
|
||||||
for(Point2 p : Geometry.d4){
|
for(Point2 p : Geometry.d4){
|
||||||
@@ -609,7 +619,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return floor.name + ":" + block.name + ":" + overlay + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass().getSimpleName())) + ":" + team();
|
return floor.name + ":" + block.name + ":" + overlay + "[" + x + "," + y + "] " + "entity=" + (build == null ? "null" : (build.getClass().getSimpleName())) + ":" + team();
|
||||||
}
|
}
|
||||||
|
|
||||||
//remote utility methods
|
//remote utility methods
|
||||||
@@ -632,18 +642,18 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
|
|
||||||
@Remote(called = Loc.server, unreliable = true)
|
@Remote(called = Loc.server, unreliable = true)
|
||||||
public static void onTileDamage(Tile tile, float health){
|
public static void onTileDamage(Tile tile, float health){
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
tile.entity.health = health;
|
tile.build.health = health;
|
||||||
|
|
||||||
if(tile.entity.damaged()){
|
if(tile.build.damaged()){
|
||||||
indexer.notifyTileDamaged(tile.entity);
|
indexer.notifyTileDamaged(tile.build);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
public static void onTileDestroyed(Tile tile){
|
public static void onTileDestroyed(Tile tile){
|
||||||
if(tile.entity == null) return;
|
if(tile.build == null) return;
|
||||||
tile.entity.killed();
|
tile.build.killed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ public class BuildBlock extends Block{
|
|||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
public static void onConstructFinish(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
public static void onConstructFinish(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
||||||
if(tile == null) return;
|
if(tile == null) return;
|
||||||
float healthf = tile.entity.healthf();
|
float healthf = tile.build.healthf();
|
||||||
tile.setBlock(block, team, rotation);
|
tile.setBlock(block, team, rotation);
|
||||||
tile.entity.health(block.health * healthf);
|
tile.build.health(block.health * healthf);
|
||||||
//last builder was this local client player, call placed()
|
//last builder was this local client player, call placed()
|
||||||
if(!headless && builderID == player.unit().id()){
|
if(!headless && builderID == player.unit().id()){
|
||||||
if(!skipConfig){
|
if(!skipConfig){
|
||||||
tile.entity.playerPlaced();
|
tile.build.playerPlaced();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size);
|
Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size);
|
||||||
@@ -97,7 +97,7 @@ public class BuildBlock extends Block{
|
|||||||
|
|
||||||
public static void constructed(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
public static void constructed(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
||||||
Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig);
|
Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig);
|
||||||
tile.entity.placed();
|
tile.build.placed();
|
||||||
|
|
||||||
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
|
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
|
||||||
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class Wall extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Block other){
|
public boolean canReplace(Block other){
|
||||||
return super.canReplace(other) && health > other.health;
|
return super.canReplace(other) && health > other.health && size == other.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WallEntity extends Building{
|
public class WallEntity extends Building{
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public class LaserTurret extends PowerTurret{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bullet(BulletType type, float angle){
|
protected void bullet(BulletType type, float angle){
|
||||||
bullet = type.create(tile.entity, team, x + tr.x, y + tr.y, angle);
|
bullet = type.create(tile.build, team, x + tr.x, y + tr.y, angle);
|
||||||
bulletLife = shootDuration;
|
bulletLife = shootDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class LiquidTurret extends Turret{
|
|||||||
shootSound.at(tile);
|
shootSound.at(tile);
|
||||||
|
|
||||||
if(shootShake > 0){
|
if(shootShake > 0){
|
||||||
Effects.shake(shootShake, shootShake, tile.entity);
|
Effects.shake(shootShake, shootShake, tile.build);
|
||||||
}
|
}
|
||||||
|
|
||||||
recoil = recoilAmount;
|
recoil = recoilAmount;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class ItemBridge extends Block{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (other.block() == tile.block() || (!(tile.block() instanceof ItemBridge) && other.block() == this)) && (other.team() == tile.team() || tile.block() != this) && (!checkDouble || other.<ItemBridgeEntity>ent().link != tile.pos());
|
return (other.block() == tile.block() || (!(tile.block() instanceof ItemBridge) && other.block() == this)) && (other.team() == tile.team() || tile.block() != this) && (!checkDouble || other.<ItemBridgeEntity>bc().link != tile.pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile findLink(int x, int y){
|
public Tile findLink(int x, int y){
|
||||||
@@ -134,7 +134,7 @@ public class ItemBridge extends Block{
|
|||||||
public void playerPlaced(){
|
public void playerPlaced(){
|
||||||
Tile link = findLink(tile.x, tile.y);
|
Tile link = findLink(tile.x, tile.y);
|
||||||
if(linkValid(tile, link)){
|
if(linkValid(tile, link)){
|
||||||
link.entity.configure(tile.pos());
|
link.build.configure(tile.pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPlaced = tile.pos();
|
lastPlaced = tile.pos();
|
||||||
@@ -154,7 +154,7 @@ public class ItemBridge extends Block{
|
|||||||
private void drawInput(Tile other){
|
private void drawInput(Tile other){
|
||||||
if(!linkValid(tile, other, false)) return;
|
if(!linkValid(tile, other, false)) return;
|
||||||
boolean linked = other.pos() == link;
|
boolean linked = other.pos() == link;
|
||||||
if(!linked && !(other.<ItemBridgeEntity>ent().link == tile.pos())) return;
|
if(!linked && !(other.<ItemBridgeEntity>bc().link == tile.pos())) return;
|
||||||
|
|
||||||
Tmp.v2.trns(tile.angleTo(other), 2f);
|
Tmp.v2.trns(tile.angleTo(other), 2f);
|
||||||
float tx = tile.drawx(), ty = tile.drawy();
|
float tx = tile.drawx(), ty = tile.drawy();
|
||||||
@@ -227,7 +227,7 @@ public class ItemBridge extends Block{
|
|||||||
while(it.hasNext){
|
while(it.hasNext){
|
||||||
int i = it.next();
|
int i = it.next();
|
||||||
Tile other = world.tile(i);
|
Tile other = world.tile(i);
|
||||||
if(!linkValid(tile, other, false) || other.<ItemBridgeEntity>ent().link != tile.pos()){
|
if(!linkValid(tile, other, false) || other.<ItemBridgeEntity>bc().link != tile.pos()){
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,7 +245,7 @@ public class ItemBridge extends Block{
|
|||||||
dump();
|
dump();
|
||||||
uptime = 0f;
|
uptime = 0f;
|
||||||
}else{
|
}else{
|
||||||
((ItemBridgeEntity)other.entity).incoming.add(tile.pos());
|
((ItemBridgeEntity)other.build).incoming.add(tile.pos());
|
||||||
|
|
||||||
if(consValid() && Mathf.zero(1f - efficiency())){
|
if(consValid() && Mathf.zero(1f - efficiency())){
|
||||||
uptime = Mathf.lerpDelta(uptime, 1f, 0.04f);
|
uptime = Mathf.lerpDelta(uptime, 1f, 0.04f);
|
||||||
@@ -253,7 +253,7 @@ public class ItemBridge extends Block{
|
|||||||
uptime = Mathf.lerpDelta(uptime, 0f, 0.02f);
|
uptime = Mathf.lerpDelta(uptime, 0f, 0.02f);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTransport(other.entity);
|
updateTransport(other.build);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ public class MassDriver extends Block{
|
|||||||
protected boolean shooterValid(Tile other){
|
protected boolean shooterValid(Tile other){
|
||||||
if(other == null) return true;
|
if(other == null) return true;
|
||||||
if(!(other.block() instanceof MassDriver)) return false;
|
if(!(other.block() instanceof MassDriver)) return false;
|
||||||
MassDriverEntity entity = other.ent();
|
MassDriverEntity entity = other.bc();
|
||||||
return entity.link == tile.pos() && tile.dst(other) <= range;
|
return entity.link == tile.pos() && tile.dst(other) <= range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class Sorter extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int minimapColor(Tile tile){
|
public int minimapColor(Tile tile){
|
||||||
return tile.<SorterEntity>ent().sortItem == null ? 0 : tile.<SorterEntity>ent().sortItem.color.rgba();
|
return tile.<SorterEntity>bc().sortItem == null ? 0 : tile.<SorterEntity>bc().sortItem.color.rgba();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SorterEntity extends Building{
|
public class SorterEntity extends Building{
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ public class StackConveyor extends Block implements Autotiler{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
||||||
if(tile.entity instanceof StackConveyorEntity){
|
if(tile.build instanceof StackConveyorEntity){
|
||||||
int state = ((StackConveyorEntity)tile.entity).state;
|
int state = ((StackConveyorEntity)tile.build).state;
|
||||||
if(state == stateLoad){ //standard conveyor mode
|
if(state == stateLoad){ //standard conveyor mode
|
||||||
return otherblock.outputsItems() && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.outputsItems() && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}else if(state == stateUnload){ //router mode
|
}else if(state == stateUnload){ //router mode
|
||||||
|
|||||||
@@ -178,8 +178,8 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
tempTileEnts.clear();
|
tempTileEnts.clear();
|
||||||
graphs.clear();
|
graphs.clear();
|
||||||
if(tile.entity != null && tile.entity.power != null){
|
if(tile.build != null && tile.build.power != null){
|
||||||
graphs.add(tile.entity.power.graph);
|
graphs.add(tile.build.power.graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
|
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import arc.util.ArcAnnotate.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
@@ -52,7 +53,7 @@ public class CoreBlock extends StorageBlock{
|
|||||||
public static void onPlayerSpawn(Tile tile, Player player){
|
public static void onPlayerSpawn(Tile tile, Player player){
|
||||||
if(player == null || tile == null) return;
|
if(player == null || tile == null) return;
|
||||||
|
|
||||||
CoreEntity entity = tile.ent();
|
CoreEntity entity = tile.bc();
|
||||||
CoreBlock block = (CoreBlock)tile.block();
|
CoreBlock block = (CoreBlock)tile.block();
|
||||||
Fx.spawn.at(entity);
|
Fx.spawn.at(entity);
|
||||||
|
|
||||||
@@ -91,6 +92,27 @@ public class CoreBlock extends StorageBlock{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canReplace(Block other){
|
||||||
|
//coreblocks can upgrade smaller cores
|
||||||
|
return super.canReplace(other) || (other instanceof CoreBlock && size > other.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlaceOn(Tile tile, Team team){
|
||||||
|
return canReplace(tile.block());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void placeBegan(Tile tile, Block previous){
|
||||||
|
//finish placement immediately when a block is replaced.
|
||||||
|
if(previous instanceof CoreBlock){
|
||||||
|
tile.setBlock(this, tile.team());
|
||||||
|
Fx.placeBlock.at(tile, tile.block().size);
|
||||||
|
Fx.upgradeCore.at(tile, tile.block().size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class CoreEntity extends Building implements ControlBlock{
|
public class CoreEntity extends Building implements ControlBlock{
|
||||||
public int storageCapacity;
|
public int storageCapacity;
|
||||||
//note that this unit is never actually used for control; the possession handler makes the player respawn when this unit is controlled
|
//note that this unit is never actually used for control; the possession handler makes the player respawn when this unit is controlled
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class Unloader extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table, content.items(), () -> tile.<UnloaderEntity>ent().sortItem, item -> configure(item));
|
ItemSelection.buildTable(table, content.items(), () -> tile.<UnloaderEntity>bc().sortItem, item -> configure(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ public class UnitBlock extends PayloadAcceptor{
|
|||||||
|
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
public static void onUnitBlockSpawn(Tile tile){
|
public static void onUnitBlockSpawn(Tile tile){
|
||||||
if(!(tile.entity instanceof UnitBlockEntity)) return;
|
if(!(tile.build instanceof UnitBlockEntity)) return;
|
||||||
tile.<UnitBlockEntity>ent().spawned();
|
tile.<UnitBlockEntity>bc().spawned();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UnitBlockEntity extends PayloadAcceptorEntity<UnitPayload>{
|
public class UnitBlockEntity extends PayloadAcceptorEntity<UnitPayload>{
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class ConsumePower extends Consume{
|
|||||||
* @return The amount of power which is requested per tick.
|
* @return The amount of power which is requested per tick.
|
||||||
*/
|
*/
|
||||||
public float requestedPower(Building entity){
|
public float requestedPower(Building entity){
|
||||||
if(entity.tile().entity == null) return 0f;
|
if(entity.tile().build == null) return 0f;
|
||||||
if(buffered){
|
if(buffered){
|
||||||
return (1f-entity.power.status)*capacity;
|
return (1f-entity.power.status)*capacity;
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mindustry.desktop.steam;
|
package mindustry.desktop.steam;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import com.codedisaster.steamworks.*;
|
import com.codedisaster.steamworks.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
@@ -108,7 +107,7 @@ public class SStats implements SteamUserStatsCallback{
|
|||||||
if(campaign() && e.unit != null && e.unit.isLocal() && !e.breaking){
|
if(campaign() && e.unit != null && e.unit.isLocal() && !e.breaking){
|
||||||
SStat.blocksBuilt.add();
|
SStat.blocksBuilt.add();
|
||||||
|
|
||||||
if(e.tile.block() == Blocks.router && e.tile.entity.proximity().contains(t -> t.block() == Blocks.router)){
|
if(e.tile.block() == Blocks.router && e.tile.build.proximity().contains(t -> t.block() == Blocks.router)){
|
||||||
chainRouters.complete();
|
chainRouters.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class ApplicationTests{
|
|||||||
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++){
|
||||||
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);
|
assertEquals(world.tile(x, y).build, world.tile(bx, by).build);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,12 +143,12 @@ public class ApplicationTests{
|
|||||||
void blockInventories(){
|
void blockInventories(){
|
||||||
multiblock();
|
multiblock();
|
||||||
Tile tile = world.tile(4, 4);
|
Tile tile = world.tile(4, 4);
|
||||||
tile.entity.items.add(Items.coal, 5);
|
tile.build.items.add(Items.coal, 5);
|
||||||
tile.entity.items.add(Items.titanium, 50);
|
tile.build.items.add(Items.titanium, 50);
|
||||||
assertEquals(tile.entity.items.total(), 55);
|
assertEquals(tile.build.items.total(), 55);
|
||||||
tile.entity.items.remove(Items.phasefabric, 10);
|
tile.build.items.remove(Items.phasefabric, 10);
|
||||||
tile.entity.items.remove(Items.titanium, 10);
|
tile.build.items.remove(Items.titanium, 10);
|
||||||
assertEquals(tile.entity.items.total(), 45);
|
assertEquals(tile.build.items.total(), 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -216,16 +216,16 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
void updateBlocks(int times){
|
void updateBlocks(int times){
|
||||||
for(Tile tile : world.tiles){
|
for(Tile tile : world.tiles){
|
||||||
if(tile.entity != null && tile.isCenter()){
|
if(tile.build != null && tile.isCenter()){
|
||||||
tile.entity.updateProximity();
|
tile.build.updateProximity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < times; i++){
|
for(int i = 0; i < times; i++){
|
||||||
Time.update();
|
Time.update();
|
||||||
for(Tile tile : world.tiles){
|
for(Tile tile : world.tiles){
|
||||||
if(tile.entity != null && tile.isCenter()){
|
if(tile.build != null && tile.isCenter()){
|
||||||
tile.entity.update();
|
tile.build.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,14 +237,14 @@ public class ApplicationTests{
|
|||||||
state.set(State.playing);
|
state.set(State.playing);
|
||||||
|
|
||||||
world.tile(0, 0).setBlock(Blocks.liquidSource);
|
world.tile(0, 0).setBlock(Blocks.liquidSource);
|
||||||
world.tile(0, 0).entity.configureAny(Liquids.water);
|
world.tile(0, 0).build.configureAny(Liquids.water);
|
||||||
|
|
||||||
world.tile(2, 1).setBlock(Blocks.liquidTank);
|
world.tile(2, 1).setBlock(Blocks.liquidTank);
|
||||||
|
|
||||||
updateBlocks(10);
|
updateBlocks(10);
|
||||||
|
|
||||||
assertTrue(world.tile(2, 1).entity.liquids.currentAmount() >= 1);
|
assertTrue(world.tile(2, 1).build.liquids.currentAmount() >= 1);
|
||||||
assertTrue(world.tile(2, 1).entity.liquids.current() == Liquids.water);
|
assertTrue(world.tile(2, 1).build.liquids.current() == Liquids.water);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -255,7 +255,7 @@ public class ApplicationTests{
|
|||||||
Tile source = world.rawTile(0, 0), tank = world.rawTile(1, 4), junction = world.rawTile(0, 1), conduit = world.rawTile(0, 2);
|
Tile source = world.rawTile(0, 0), tank = world.rawTile(1, 4), junction = world.rawTile(0, 1), conduit = world.rawTile(0, 2);
|
||||||
|
|
||||||
source.setBlock(Blocks.liquidSource);
|
source.setBlock(Blocks.liquidSource);
|
||||||
source.entity.configureAny(Liquids.water);
|
source.build.configureAny(Liquids.water);
|
||||||
|
|
||||||
junction.setBlock(Blocks.liquidJunction);
|
junction.setBlock(Blocks.liquidJunction);
|
||||||
|
|
||||||
@@ -265,8 +265,8 @@ public class ApplicationTests{
|
|||||||
|
|
||||||
updateBlocks(10);
|
updateBlocks(10);
|
||||||
|
|
||||||
assertTrue(tank.entity.liquids.currentAmount() >= 1, "Liquid not moved through junction");
|
assertTrue(tank.build.liquids.currentAmount() >= 1, "Liquid not moved through junction");
|
||||||
assertTrue(tank.entity.liquids.current() == Liquids.water, "Tank has no water");
|
assertTrue(tank.build.liquids.current() == Liquids.water, "Tank has no water");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -290,7 +290,7 @@ 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);
|
||||||
world.tile(0, 0).entity.acceptStack(Items.copper, 1000, null);
|
world.tile(0, 0).build.acceptStack(Items.copper, 1000, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -367,14 +367,14 @@ public class ApplicationTests{
|
|||||||
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).entity.configureAny(Items.copper);
|
world.tile(0, 0).build.configureAny(Items.copper);
|
||||||
|
|
||||||
Seq<Building> entities = Seq.with(world.tile(0, 0).entity);
|
Seq<Building> entities = Seq.with(world.tile(0, 0).build);
|
||||||
|
|
||||||
for(int i = 0; i < length; i++){
|
for(int i = 0; i < length; i++){
|
||||||
world.tile(i + 1, 0).setBlock(Blocks.conveyor);
|
world.tile(i + 1, 0).setBlock(Blocks.conveyor);
|
||||||
world.tile(i + 1, 0).rotation(0);
|
world.tile(i + 1, 0).rotation(0);
|
||||||
entities.add(world.tile(i + 1, 0).entity);
|
entities.add(world.tile(i + 1, 0).build);
|
||||||
}
|
}
|
||||||
|
|
||||||
world.tile(length + 1, 0).setBlock(new Block("___"){{
|
world.tile(length + 1, 0).setBlock(new Block("___"){{
|
||||||
@@ -501,7 +501,7 @@ 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());
|
||||||
assertEquals(Blocks.copperWallLarge, world.tile(1, 1).block());
|
assertEquals(Blocks.copperWallLarge, world.tile(1, 1).block());
|
||||||
assertEquals(world.tile(1, 1).entity, world.tile(0, 0).entity);
|
assertEquals(world.tile(1, 1).build, world.tile(0, 0).build);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -565,14 +565,14 @@ public class ApplicationTests{
|
|||||||
for(int x = 0; x < tiles.width; x++){
|
for(int x = 0; x < tiles.width; x++){
|
||||||
for(int y = 0; y < tiles.height; y++){
|
for(int y = 0; y < tiles.height; y++){
|
||||||
Tile tile = world.rawTile(x, y);
|
Tile tile = world.rawTile(x, y);
|
||||||
if(tile.entity != null){
|
if(tile.build != null){
|
||||||
try{
|
try{
|
||||||
tile.entity.update();
|
tile.build.update();
|
||||||
}catch(Throwable t){
|
}catch(Throwable t){
|
||||||
fail("Failed to update block '" + tile.block() + "'.", t);
|
fail("Failed to update block '" + tile.block() + "'.", t);
|
||||||
}
|
}
|
||||||
assertEquals(tile.block(), tile.entity.block());
|
assertEquals(tile.block(), tile.build.block());
|
||||||
assertEquals(tile.block().health, tile.entity.health());
|
assertEquals(tile.block().health, tile.build.health());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -584,10 +584,10 @@ public class ApplicationTests{
|
|||||||
Tile core = world.tile(5, 5);
|
Tile core = world.tile(5, 5);
|
||||||
core.setBlock(Blocks.coreShard, Team.sharded, 0);
|
core.setBlock(Blocks.coreShard, Team.sharded, 0);
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
core.entity.items.set(item, 3000);
|
core.build.items.set(item, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(core.entity, state.teams.get(Team.sharded).core());
|
assertEquals(core.build, state.teams.get(Team.sharded).core());
|
||||||
}
|
}
|
||||||
|
|
||||||
void depositTest(Block block, Item item){
|
void depositTest(Block block, Item item){
|
||||||
@@ -595,18 +595,18 @@ public class ApplicationTests{
|
|||||||
Tile tile = new Tile(0, 0, Blocks.air, Blocks.air, block);
|
Tile tile = new Tile(0, 0, Blocks.air, Blocks.air, block);
|
||||||
int capacity = tile.block().itemCapacity;
|
int capacity = tile.block().itemCapacity;
|
||||||
|
|
||||||
assertNotNull(tile.entity, "Tile should have an entity, but does not: " + tile);
|
assertNotNull(tile.build, "Tile should have an entity, but does not: " + tile);
|
||||||
|
|
||||||
int deposited = tile.entity.acceptStack(item, capacity - 1, unit);
|
int deposited = tile.build.acceptStack(item, capacity - 1, unit);
|
||||||
assertEquals(capacity - 1, deposited);
|
assertEquals(capacity - 1, deposited);
|
||||||
|
|
||||||
tile.entity.handleStack(item, capacity - 1, unit);
|
tile.build.handleStack(item, capacity - 1, unit);
|
||||||
assertEquals(tile.entity.items.get(item), capacity - 1);
|
assertEquals(tile.build.items.get(item), capacity - 1);
|
||||||
|
|
||||||
int overflow = tile.entity.acceptStack(item, 10, unit);
|
int overflow = tile.build.acceptStack(item, 10, unit);
|
||||||
assertEquals(1, overflow);
|
assertEquals(1, overflow);
|
||||||
|
|
||||||
tile.entity.handleStack(item, 1, unit);
|
tile.build.handleStack(item, 1, unit);
|
||||||
assertEquals(capacity, tile.entity.items.get(item));
|
assertEquals(capacity, tile.build.items.get(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{
|
|||||||
};
|
};
|
||||||
|
|
||||||
tile = createFakeTile(0, 0, generator);
|
tile = createFakeTile(0, 0, generator);
|
||||||
entity = tile.ent();
|
entity = tile.bc();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tests the consumption and efficiency when being supplied with liquids. */
|
/** Tests the consumption and efficiency when being supplied with liquids. */
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import mindustry.game.*;
|
|||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.power.*;
|
import mindustry.world.blocks.power.*;
|
||||||
import mindustry.world.modules.*;
|
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -87,21 +86,21 @@ public class PowerTestFixture{
|
|||||||
Reflect.set(Tile.class, tile, "floor", Blocks.sand);
|
Reflect.set(Tile.class, tile, "floor", 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, Team.sharded, false);
|
tile.build = block.newEntity().init(tile, Team.sharded, false);
|
||||||
if(block.hasPower){
|
if(block.hasPower){
|
||||||
tile.entity.power.graph = new PowerGraph(){
|
tile.build.power.graph = new PowerGraph(){
|
||||||
//assume there's always something consuming power
|
//assume there's always something consuming power
|
||||||
@Override
|
@Override
|
||||||
public float getUsageFraction(){
|
public float getUsageFraction(){
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tile.entity.power.graph.add(tile.entity);
|
tile.build.power.graph.add(tile.build);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
block.health = 100000;
|
block.health = 100000;
|
||||||
tile.entity.health(100000.0f);
|
tile.build.health(100000.0f);
|
||||||
|
|
||||||
return tile;
|
return tile;
|
||||||
}catch(Exception ex){
|
}catch(Exception ex){
|
||||||
|
|||||||
@@ -54,19 +54,19 @@ public class PowerTests extends PowerTestFixture{
|
|||||||
|
|
||||||
void simulateDirectConsumption(float producedPower, float requiredPower, float expectedSatisfaction, String parameterDescription){
|
void simulateDirectConsumption(float producedPower, float requiredPower, float expectedSatisfaction, String parameterDescription){
|
||||||
Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(producedPower));
|
Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(producedPower));
|
||||||
producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1f;
|
producerTile.<PowerGenerator.GeneratorEntity>bc().productionEfficiency = 1f;
|
||||||
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.entity);
|
powerGraph.add(producerTile.build);
|
||||||
powerGraph.add(directConsumerTile.entity);
|
powerGraph.add(directConsumerTile.build);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
// Update and check for the expected power status of the consumer
|
// Update and check for the expected power status of the consumer
|
||||||
powerGraph.update();
|
powerGraph.update();
|
||||||
assertEquals(expectedSatisfaction, directConsumerTile.entity.power.status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match");
|
assertEquals(expectedSatisfaction, directConsumerTile.build.power.status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,24 +94,24 @@ 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>bc().productionEfficiency = 1f;
|
||||||
powerGraph.add(producerTile.entity);
|
powerGraph.add(producerTile.build);
|
||||||
}
|
}
|
||||||
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.entity);
|
powerGraph.add(directConsumerTile.build);
|
||||||
}
|
}
|
||||||
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.build.power.status = initialBatteryCapacity / maxCapacity;
|
||||||
|
|
||||||
powerGraph.add(batteryTile.entity);
|
powerGraph.add(batteryTile.build);
|
||||||
|
|
||||||
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.build.power.status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Expected battery status did not match");
|
||||||
if(directConsumerTile != null){
|
if(directConsumerTile != null){
|
||||||
assertEquals(expectedSatisfaction, directConsumerTile.entity.power.status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match");
|
assertEquals(expectedSatisfaction, directConsumerTile.build.power.status, Mathf.FLOAT_ROUNDING_ERROR, parameterDescription + ": Satisfaction of direct consumer did not match");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,24 +119,24 @@ public class PowerTests extends PowerTestFixture{
|
|||||||
@Test
|
@Test
|
||||||
void directConsumptionStopsWithNoPower(){
|
void directConsumptionStopsWithNoPower(){
|
||||||
Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(10.0f));
|
Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(10.0f));
|
||||||
producerTile.<PowerGenerator.GeneratorEntity>ent().productionEfficiency = 1.0f;
|
producerTile.<PowerGenerator.GeneratorEntity>bc().productionEfficiency = 1.0f;
|
||||||
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.entity);
|
powerGraph.add(producerTile.build);
|
||||||
powerGraph.add(consumerTile.entity);
|
powerGraph.add(consumerTile.build);
|
||||||
powerGraph.update();
|
powerGraph.update();
|
||||||
|
|
||||||
assertEquals(1.0f, consumerTile.entity.power.status, Mathf.FLOAT_ROUNDING_ERROR);
|
assertEquals(1.0f, consumerTile.build.power.status, Mathf.FLOAT_ROUNDING_ERROR);
|
||||||
|
|
||||||
powerGraph.remove(producerTile.entity);
|
powerGraph.remove(producerTile.build);
|
||||||
powerGraph.add(consumerTile.entity);
|
powerGraph.add(consumerTile.build);
|
||||||
powerGraph.update();
|
powerGraph.update();
|
||||||
|
|
||||||
assertEquals(0.0f, consumerTile.entity.power.status, Mathf.FLOAT_ROUNDING_ERROR);
|
assertEquals(0.0f, consumerTile.build.power.status, Mathf.FLOAT_ROUNDING_ERROR);
|
||||||
if(consumerTile.block().consumes.hasPower()){
|
if(consumerTile.block().consumes.hasPower()){
|
||||||
ConsumePower consumePower = consumerTile.block().consumes.getPower();
|
ConsumePower consumePower = consumerTile.block().consumes.getPower();
|
||||||
assertFalse(consumePower.valid(consumerTile.ent()));
|
assertFalse(consumePower.valid(consumerTile.bc()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user