Bugfixes / Mender block / Extra stats / Balancing
@@ -7,13 +7,13 @@ import java.lang.annotation.Target;
|
|||||||
|
|
||||||
public class Annotations{
|
public class Annotations{
|
||||||
|
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface Nullable{
|
public @interface Nullable{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface NonNull{
|
public @interface NonNull{
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class StructAnnotationProcessor extends AbstractProcessor{
|
|||||||
//floats: need conversion
|
//floats: need conversion
|
||||||
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||||
}else{
|
}else{
|
||||||
cons.append(" | (").append("(").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)");
|
cons.append(" | (((").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)").append(" & ").append(bitString(offset, size, structTotalSize)).append(")");
|
||||||
|
|
||||||
//bytes, shorts, chars, ints
|
//bytes, shorts, chars, ints
|
||||||
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||||
|
|||||||
BIN
core/assets-raw/sprites/blocks/defense/mender-top.png
Normal file
|
After Width: | Height: | Size: 1018 B |
BIN
core/assets-raw/sprites/blocks/defense/mender.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
@@ -366,6 +366,8 @@ blocks.itemcapacity = Item Capacity
|
|||||||
blocks.basepowergeneration = Base Power Generation
|
blocks.basepowergeneration = Base Power Generation
|
||||||
blocks.powertransferspeed = Power Transfer
|
blocks.powertransferspeed = Power Transfer
|
||||||
blocks.craftspeed = Production Speed
|
blocks.craftspeed = Production Speed
|
||||||
|
blocks.repairtime = Block Full Repair Time
|
||||||
|
blocks.range = Range
|
||||||
blocks.inputliquid = Input Liquid
|
blocks.inputliquid = Input Liquid
|
||||||
blocks.inputliquidaux = Aux Liquid
|
blocks.inputliquidaux = Aux Liquid
|
||||||
blocks.inputitem = Input Item
|
blocks.inputitem = Input Item
|
||||||
@@ -399,7 +401,7 @@ blocks.inputcapacity = Input capacity
|
|||||||
blocks.outputcapacity = Output capacity
|
blocks.outputcapacity = Output capacity
|
||||||
blocks.ammo = Ammo
|
blocks.ammo = Ammo
|
||||||
|
|
||||||
bullet.damage = [stat]{0}[lightgray] dmg
|
bullet.damage = [stat]{0}[lightgray] damage
|
||||||
bullet.splashdamage = [stat]{0}[lightgray] area dmg ~[stat] {1}[lightgray] tiles
|
bullet.splashdamage = [stat]{0}[lightgray] area dmg ~[stat] {1}[lightgray] tiles
|
||||||
bullet.incendiary = [stat]incendiary
|
bullet.incendiary = [stat]incendiary
|
||||||
bullet.homing = [stat]homing
|
bullet.homing = [stat]homing
|
||||||
@@ -510,7 +512,7 @@ mode.custom = Custom Rules
|
|||||||
rules.infiniteresources = Infinite Resources
|
rules.infiniteresources = Infinite Resources
|
||||||
rules.wavetimer = Wave Timer
|
rules.wavetimer = Wave Timer
|
||||||
rules.waves = Waves
|
rules.waves = Waves
|
||||||
rules.enemyCheat = Infinite AI Resources
|
rules.enemyCheat = Infinite AI (Red Team) Resources
|
||||||
rules.pvp = PvP
|
rules.pvp = PvP
|
||||||
rules.unitdrops = Unit Drops
|
rules.unitdrops = Unit Drops
|
||||||
rules.enemycorebuildradius = Enemy Core No-Build Radius:[LIGHT_GRAY] (tiles)
|
rules.enemycorebuildradius = Enemy Core No-Build Radius:[LIGHT_GRAY] (tiles)
|
||||||
@@ -759,6 +761,7 @@ block.blast-drill.name = Airblast Drill
|
|||||||
block.thermal-pump.name = Thermal Pump
|
block.thermal-pump.name = Thermal Pump
|
||||||
block.thermal-generator.name = Thermal Generator
|
block.thermal-generator.name = Thermal Generator
|
||||||
block.alloy-smelter.name = Alloy Smelter
|
block.alloy-smelter.name = Alloy Smelter
|
||||||
|
block.mender.name = Mender
|
||||||
block.mend-projector.name = Mend Projector
|
block.mend-projector.name = Mend Projector
|
||||||
block.surge-wall.name = Surge Wall
|
block.surge-wall.name = Surge Wall
|
||||||
block.surge-wall-large.name = Large Surge Wall
|
block.surge-wall-large.name = Large Surge Wall
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 506 B After Width: | Height: | Size: 505 B |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 513 KiB After Width: | Height: | Size: 516 KiB |
@@ -14,6 +14,7 @@ import io.anuke.mindustry.entities.Effects;
|
|||||||
import io.anuke.mindustry.entities.type.BaseUnit;
|
import io.anuke.mindustry.entities.type.BaseUnit;
|
||||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
||||||
import io.anuke.mindustry.game.SpawnGroup;
|
import io.anuke.mindustry.game.SpawnGroup;
|
||||||
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.world.Pos;
|
import io.anuke.mindustry.world.Pos;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
@@ -105,7 +106,7 @@ public class WaveSpawner{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSpawning(){
|
public boolean isSpawning(){
|
||||||
return spawning;
|
return spawning && !Net.client();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reset(){
|
private void reset(){
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class Blocks implements ContentList{
|
|||||||
//defense
|
//defense
|
||||||
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
|
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
|
||||||
copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge,
|
copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge,
|
||||||
phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mendProjector, overdriveProjector, forceProjector, shockMine,
|
phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mender, mendProjector, overdriveProjector, forceProjector, shockMine,
|
||||||
|
|
||||||
//transport
|
//transport
|
||||||
conveyor, titaniumConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, router, overflowGate, massDriver,
|
conveyor, titaniumConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, router, overflowGate, massDriver,
|
||||||
@@ -529,7 +529,7 @@ public class Blocks implements ContentList{
|
|||||||
cultivator = new Cultivator("cultivator"){{
|
cultivator = new Cultivator("cultivator"){{
|
||||||
requirements(Category.crafting, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20));
|
requirements(Category.crafting, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20));
|
||||||
output = Items.sporePod;
|
output = Items.sporePod;
|
||||||
craftTime = 200;
|
craftTime = 160;
|
||||||
size = 2;
|
size = 2;
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
@@ -544,7 +544,7 @@ public class Blocks implements ContentList{
|
|||||||
liquidCapacity = 60f;
|
liquidCapacity = 60f;
|
||||||
craftTime = 20f;
|
craftTime = 20f;
|
||||||
outputLiquid = Liquids.oil;
|
outputLiquid = Liquids.oil;
|
||||||
outputLiquidAmount = 2.5f;
|
outputLiquidAmount = 4f;
|
||||||
size = 2;
|
size = 2;
|
||||||
health = 320;
|
health = 320;
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
@@ -695,10 +695,23 @@ public class Blocks implements ContentList{
|
|||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
mender = new MendProjector("mender"){{
|
||||||
|
requirements(Category.effect, ItemStack.with(Items.lead, 60, Items.copper, 50));
|
||||||
|
consumes.power(0.7f);
|
||||||
|
size = 1;
|
||||||
|
reload = 200f;
|
||||||
|
range = 40f;
|
||||||
|
healPercent = 5f;
|
||||||
|
consumes.item(Items.phasefabric).optional(true);
|
||||||
|
}};
|
||||||
|
|
||||||
mendProjector = new MendProjector("mend-projector"){{
|
mendProjector = new MendProjector("mend-projector"){{
|
||||||
requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 50, Items.silicon, 180));
|
requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 40, Items.silicon, 80));
|
||||||
consumes.power(2f);
|
consumes.power(1.8f);
|
||||||
size = 2;
|
size = 2;
|
||||||
|
reload = 250f;
|
||||||
|
range = 70f;
|
||||||
|
healPercent = 13f;
|
||||||
consumes.item(Items.phasefabric).optional(true);
|
consumes.item(Items.phasefabric).optional(true);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1118,7 +1131,7 @@ public class Blocks implements ContentList{
|
|||||||
Items.scrap, Bullets.flakScrap,
|
Items.scrap, Bullets.flakScrap,
|
||||||
Items.lead, Bullets.flakLead
|
Items.lead, Bullets.flakLead
|
||||||
);
|
);
|
||||||
reload = 33f;
|
reload = 25f;
|
||||||
range = 180f;
|
range = 180f;
|
||||||
size = 2;
|
size = 2;
|
||||||
burstSpacing = 5f;
|
burstSpacing = 5f;
|
||||||
@@ -1126,7 +1139,7 @@ public class Blocks implements ContentList{
|
|||||||
targetGround = false;
|
targetGround = false;
|
||||||
|
|
||||||
recoil = 2f;
|
recoil = 2f;
|
||||||
rotatespeed = 10f;
|
rotatespeed = 15f;
|
||||||
inaccuracy = 17f;
|
inaccuracy = 17f;
|
||||||
shootCone = 35f;
|
shootCone = 35f;
|
||||||
|
|
||||||
|
|||||||
@@ -141,25 +141,25 @@ public class Bullets implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
flakLead = new FlakBulletType(4.2f, 3){{
|
flakLead = new FlakBulletType(4.2f, 3){{
|
||||||
lifetime = 50f;
|
lifetime = 60f;
|
||||||
ammoMultiplier = 3f;
|
ammoMultiplier = 3f;
|
||||||
shootEffect = Fx.shootSmall;
|
shootEffect = Fx.shootSmall;
|
||||||
bulletWidth = 6f;
|
bulletWidth = 6f;
|
||||||
bulletHeight = 8f;
|
bulletHeight = 8f;
|
||||||
hitEffect = Fx.flakExplosion;
|
hitEffect = Fx.flakExplosion;
|
||||||
splashDamage = 30f;
|
splashDamage = 35f;
|
||||||
splashDamageRadius = 15f;
|
splashDamageRadius = 15f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
flakScrap = new FlakBulletType(4f, 3){{
|
flakScrap = new FlakBulletType(4f, 3){{
|
||||||
lifetime = 50f;
|
lifetime = 60f;
|
||||||
ammoMultiplier = 3f;
|
ammoMultiplier = 3f;
|
||||||
shootEffect = Fx.shootSmall;
|
shootEffect = Fx.shootSmall;
|
||||||
reloadMultiplier = 0.5f;
|
reloadMultiplier = 0.5f;
|
||||||
bulletWidth = 6f;
|
bulletWidth = 6f;
|
||||||
bulletHeight = 8f;
|
bulletHeight = 8f;
|
||||||
hitEffect = Fx.flakExplosion;
|
hitEffect = Fx.flakExplosion;
|
||||||
splashDamage = 24f;
|
splashDamage = 26f;
|
||||||
splashDamageRadius = 24f;
|
splashDamageRadius = 24f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,9 @@ public class TechTree implements ContentList{
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
node(mender, () -> {
|
||||||
node(mendProjector, () -> {
|
node(mendProjector, () -> {
|
||||||
node(forceProjector, () -> {
|
node(forceProjector, () -> {
|
||||||
node(overdriveProjector, () -> {
|
node(overdriveProjector, () -> {
|
||||||
@@ -263,7 +265,7 @@ public class TechTree implements ContentList{
|
|||||||
private TechNode node(Block block, Runnable children){
|
private TechNode node(Block block, Runnable children){
|
||||||
ItemStack[] requirements = new ItemStack[block.buildRequirements.length];
|
ItemStack[] requirements = new ItemStack[block.buildRequirements.length];
|
||||||
for(int i = 0; i < requirements.length; i++){
|
for(int i = 0; i < requirements.length; i++){
|
||||||
requirements[i] = new ItemStack(block.buildRequirements[i].item, block.buildRequirements[i].amount * 6);
|
requirements[i] = new ItemStack(block.buildRequirements[i].item, block.buildRequirements[i].amount * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TechNode(block, requirements, children);
|
return new TechNode(block, requirements, children);
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
byte[] stateBytes = syncStream.toByteArray();
|
byte[] stateBytes = syncStream.toByteArray();
|
||||||
|
|
||||||
//write basic state data.
|
//write basic state data.
|
||||||
Call.onStateSnapshot(player.con.id, state.wavetime, state.wave, state.enemies, (short)stateBytes.length, Net.compressSnapshot(stateBytes));
|
Call.onStateSnapshot(player.con.id, state.wavetime, state.wave, state.enemies(), (short)stateBytes.length, Net.compressSnapshot(stateBytes));
|
||||||
|
|
||||||
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
|
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
public Renderer(){
|
public Renderer(){
|
||||||
batch = new SpriteBatch(4096);
|
batch = new SpriteBatch(4096);
|
||||||
camera = new Camera();
|
camera = new Camera();
|
||||||
Lines.setCircleVertices(14);
|
Lines.setCircleVertices(20);
|
||||||
Shaders.init();
|
Shaders.init();
|
||||||
|
|
||||||
Effects.setScreenShakeProvider((intensity, duration) -> {
|
Effects.setScreenShakeProvider((intensity, duration) -> {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import io.anuke.annotations.Annotations.Struct;
|
|||||||
import io.anuke.arc.collection.LongArray;
|
import io.anuke.arc.collection.LongArray;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.gen.TileOp;
|
import io.anuke.mindustry.gen.TileOp;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
@@ -39,7 +40,11 @@ public class DrawOperation{
|
|||||||
if(type == OpType.floor.ordinal()){
|
if(type == OpType.floor.ordinal()){
|
||||||
tile.setFloor((Floor)content.block(to));
|
tile.setFloor((Floor)content.block(to));
|
||||||
}else if(type == OpType.block.ordinal()){
|
}else if(type == OpType.block.ordinal()){
|
||||||
tile.setBlock(content.block(to));
|
Block block = content.block(to);
|
||||||
|
tile.setBlock(block);
|
||||||
|
if(block.isMultiblock()){
|
||||||
|
editor.updateLinks(block, tile.x, tile.y);
|
||||||
|
}
|
||||||
}else if(type == OpType.rotation.ordinal()){
|
}else if(type == OpType.rotation.ordinal()){
|
||||||
tile.setRotation(to);
|
tile.setRotation(to);
|
||||||
}else if(type == OpType.team.ordinal()){
|
}else if(type == OpType.team.ordinal()){
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(Block type){
|
public void setBlock(Block type){
|
||||||
if(type == null) return;
|
Block previous =wall;
|
||||||
Block previous = wall == null ? Blocks.air : wall;
|
|
||||||
if(previous == type) return;
|
if(previous == type) return;
|
||||||
super.setBlock(type);
|
super.setBlock(type);
|
||||||
op(TileOp.get(x, y, (byte)OpType.block.ordinal(), previous.id, type.id));
|
op(TileOp.get(x, y, (byte)OpType.block.ordinal(), previous.id, type.id));
|
||||||
|
|||||||
@@ -146,6 +146,27 @@ public class MapEditor{
|
|||||||
return tiles[0].length;
|
return tiles[0].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateLinks(Block block, int x, int y){
|
||||||
|
int offsetx = -(block.size - 1) / 2;
|
||||||
|
int offsety = -(block.size - 1) / 2;
|
||||||
|
|
||||||
|
for(int dx = 0; dx < block.size; dx++){
|
||||||
|
for(int dy = 0; dy < block.size; dy++){
|
||||||
|
int worldx = dx + offsetx + x;
|
||||||
|
int worldy = dy + offsety + y;
|
||||||
|
|
||||||
|
if(Structs.inBounds(worldx, worldy, width(), height())){
|
||||||
|
Tile tile = tiles[worldx][worldy];
|
||||||
|
|
||||||
|
if(!(worldx == x && worldy == y)){
|
||||||
|
tile.setBlock(Blocks.part);
|
||||||
|
tile.setLinkByte(Pack.byteByte((byte)(dx + offsetx + 8), (byte)(dy + offsety + 8)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void draw(int x, int y, boolean paint){
|
public void draw(int x, int y, boolean paint){
|
||||||
draw(x, y, paint, drawBlock);
|
draw(x, y, paint, drawBlock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ public class CustomRulesDialog extends FloatingDialog{
|
|||||||
main.row();
|
main.row();
|
||||||
main.addCheck("$rules.wavetimer", b -> rules.waveTimer = b).checked(b -> rules.waveTimer);
|
main.addCheck("$rules.wavetimer", b -> rules.waveTimer = b).checked(b -> rules.waveTimer);
|
||||||
main.row();
|
main.row();
|
||||||
main.addCheck("$rules.waves", b -> rules.waves = b).checked(b -> rules.waves).disabled(b -> rules.pvp);
|
main.addCheck("$rules.waves", b -> rules.waves = b).checked(b -> rules.waves);
|
||||||
main.row();
|
main.row();
|
||||||
main.addCheck("$rules.pvp", b -> rules.pvp = b).checked(b -> rules.pvp).disabled(b -> rules.waves);
|
main.addCheck("$rules.pvp", b -> rules.pvp = b).checked(b -> rules.pvp);
|
||||||
main.row();
|
main.row();
|
||||||
main.addCheck("$rules.unitdrops", b -> rules.unitDrops = b).checked(b -> rules.unitDrops);
|
main.addCheck("$rules.unitdrops", b -> rules.unitDrops = b).checked(b -> rules.unitDrops);
|
||||||
main.row();
|
main.row();
|
||||||
|
|||||||
@@ -449,15 +449,17 @@ public class HudFragment extends Fragment{
|
|||||||
builder.append(wavef.get(state.wave));
|
builder.append(wavef.get(state.wave));
|
||||||
builder.append("\n");
|
builder.append("\n");
|
||||||
|
|
||||||
if(state.enemies() > 0 && !state.rules.waveTimer){
|
if(state.enemies() > 0){
|
||||||
if(state.enemies() == 1){
|
if(state.enemies() == 1){
|
||||||
builder.append(enemyf.get(state.enemies()));
|
builder.append(enemyf.get(state.enemies()));
|
||||||
}else{
|
}else{
|
||||||
builder.append(enemiesf.get(state.enemies()));
|
builder.append(enemiesf.get(state.enemies()));
|
||||||
}
|
}
|
||||||
}else if(state.rules.waveTimer){
|
}
|
||||||
|
|
||||||
|
if(state.rules.waveTimer){
|
||||||
builder.append(waitingf.get((int)(state.wavetime/60)));
|
builder.append(waitingf.get((int)(state.wavetime/60)));
|
||||||
}else{
|
}else if(state.enemies() == 0){
|
||||||
builder.append(Core.bundle.get("waiting"));
|
builder.append(Core.bundle.get("waiting"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,14 +136,14 @@ public class Block extends BlockStorage{
|
|||||||
TileEntity entity = tile.entity();
|
TileEntity entity = tile.entity();
|
||||||
|
|
||||||
for(Tile other : getPowerConnections(tile, tempTiles)){
|
for(Tile other : getPowerConnections(tile, tempTiles)){
|
||||||
if(other.entity.power != null && other.entity.power.graph != null){
|
if(other.entity.power != null){
|
||||||
other.entity.power.graph.add(entity.power.graph);
|
other.entity.power.graph.add(entity.power.graph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void powerGraphRemoved(Tile tile){
|
protected void powerGraphRemoved(Tile tile){
|
||||||
if(tile.entity == null || tile.entity.power == null || tile.entity.power.graph == null){
|
if(tile.entity == null || tile.entity.power == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import io.anuke.mindustry.content.Fx;
|
|||||||
import io.anuke.mindustry.entities.type.TileEntity;
|
import io.anuke.mindustry.entities.type.TileEntity;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.meta.BlockStat;
|
||||||
|
import io.anuke.mindustry.world.meta.StatUnit;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
@@ -32,8 +34,8 @@ public class MendProjector extends Block{
|
|||||||
|
|
||||||
protected TextureRegion topRegion;
|
protected TextureRegion topRegion;
|
||||||
protected float reload = 250f;
|
protected float reload = 250f;
|
||||||
protected float range = 50f;
|
protected float range = 60f;
|
||||||
protected float healPercent = 6f;
|
protected float healPercent = 12f;
|
||||||
protected float phaseBoost = 12f;
|
protected float phaseBoost = 12f;
|
||||||
protected float phaseRangeBoost = 50f;
|
protected float phaseRangeBoost = 50f;
|
||||||
protected float useTime = 400f;
|
protected float useTime = 400f;
|
||||||
@@ -52,6 +54,14 @@ public class MendProjector extends Block{
|
|||||||
topRegion = Core.atlas.find(name + "-top");
|
topRegion = Core.atlas.find(name + "-top");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStats(){
|
||||||
|
super.setStats();
|
||||||
|
|
||||||
|
stats.add(BlockStat.repairTime, (int)(100f / healPercent * reload / 60f), StatUnit.seconds);
|
||||||
|
stats.add(BlockStat.range, range / tilesize, StatUnit.blocks);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
MendEntity entity = tile.entity();
|
MendEntity entity = tile.entity();
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ public class PowerDistributor extends PowerBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
if(tile.entity.power.graph != null){
|
tile.entity.power.graph.update();
|
||||||
tile.entity.power.graph.update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ public class PowerGraph{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void add(Tile tile){
|
public void add(Tile tile){
|
||||||
|
if(tile.block().consumes.has(ConsumePower.class) && !tile.block().consumes.get(ConsumePower.class).isBuffered){
|
||||||
|
//reset satisfaction to zero in case of direct consumer. There is no reason to clear power from buffered consumers.
|
||||||
|
tile.entity.power.satisfaction = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
tile.entity.power.graph = this;
|
tile.entity.power.graph = this;
|
||||||
all.add(tile);
|
all.add(tile);
|
||||||
|
|
||||||
@@ -191,32 +196,15 @@ public class PowerGraph{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(){
|
|
||||||
for(Tile other : all){
|
|
||||||
if(other.entity != null && other.entity.power != null){
|
|
||||||
if(other.block().consumes.has(ConsumePower.class) && !other.block().consumes.get(ConsumePower.class).isBuffered){
|
|
||||||
// Reset satisfaction to zero in case of direct consumer. There is no reason to clear power from buffered consumers.
|
|
||||||
other.entity.power.satisfaction = 0.0f;
|
|
||||||
}
|
|
||||||
other.entity.power.graph = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
all.clear();
|
|
||||||
producers.clear();
|
|
||||||
consumers.clear();
|
|
||||||
batteries.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reflow(Tile tile){
|
public void reflow(Tile tile){
|
||||||
queue.clear();
|
queue.clear();
|
||||||
queue.addLast(tile);
|
queue.addLast(tile);
|
||||||
closedSet.clear();
|
closedSet.clear();
|
||||||
while(queue.size > 0){
|
while(queue.size > 0){
|
||||||
Tile child = queue.removeFirst();
|
Tile child = queue.removeFirst();
|
||||||
child.entity.power.graph = this;
|
|
||||||
add(child);
|
add(child);
|
||||||
for(Tile next : child.block().getPowerConnections(child, outArray2)){
|
for(Tile next : child.block().getPowerConnections(child, outArray2)){
|
||||||
if(next.entity.power != null && next.entity.power.graph == null && !closedSet.contains(next.pos())){
|
if(!closedSet.contains(next.pos())){
|
||||||
queue.addLast(next);
|
queue.addLast(next);
|
||||||
closedSet.add(next.pos());
|
closedSet.add(next.pos());
|
||||||
}
|
}
|
||||||
@@ -224,27 +212,47 @@ public class PowerGraph{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeSingle(Tile tile){
|
||||||
|
all.remove(tile);
|
||||||
|
producers.remove(tile);
|
||||||
|
consumers.remove(tile);
|
||||||
|
batteries.remove(tile);
|
||||||
|
}
|
||||||
|
|
||||||
public void remove(Tile tile){
|
public void remove(Tile tile){
|
||||||
clear();
|
removeSingle(tile);
|
||||||
|
//begin by clearing the closed set
|
||||||
closedSet.clear();
|
closedSet.clear();
|
||||||
|
|
||||||
|
//go through all the connections of this tile
|
||||||
for(Tile other : tile.block().getPowerConnections(tile, outArray1)){
|
for(Tile other : tile.block().getPowerConnections(tile, outArray1)){
|
||||||
if(other.entity.power == null || other.entity.power.graph != null) continue;
|
//a graph has already been assigned to this tile from a previous call, skip it
|
||||||
|
if(other.entity.power.graph != this) continue;
|
||||||
|
|
||||||
|
//create graph for this branch
|
||||||
PowerGraph graph = new PowerGraph();
|
PowerGraph graph = new PowerGraph();
|
||||||
|
graph.add(other);
|
||||||
|
//add to queue for BFS
|
||||||
queue.clear();
|
queue.clear();
|
||||||
queue.addLast(other);
|
queue.addLast(other);
|
||||||
while(queue.size > 0){
|
while(queue.size > 0){
|
||||||
|
//get child from queue
|
||||||
Tile child = queue.removeFirst();
|
Tile child = queue.removeFirst();
|
||||||
child.entity.power.graph = graph;
|
//remove it from this graph
|
||||||
|
removeSingle(child);
|
||||||
|
//add it to the new branch graph
|
||||||
graph.add(child);
|
graph.add(child);
|
||||||
|
//go through connections
|
||||||
for(Tile next : child.block().getPowerConnections(child, outArray2)){
|
for(Tile next : child.block().getPowerConnections(child, outArray2)){
|
||||||
if(next != tile && next.entity.power != null && next.entity.power.graph == null && !closedSet.contains(next.pos())){
|
//make sure it hasn't looped back, and that the new graph being assigned hasn't already been assigned
|
||||||
|
//also skip closed tiles
|
||||||
|
if(next != tile && next.entity.power.graph != graph && !closedSet.contains(next.pos())){
|
||||||
queue.addLast(next);
|
queue.addLast(next);
|
||||||
closedSet.add(next.pos());
|
closedSet.add(next.pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update the graph once so direct consumers without any connected producer lose their power
|
//update the graph once so direct consumers without any connected producer lose their power
|
||||||
graph.update();
|
graph.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,17 +72,15 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
TileEntity entity = tile.entity();
|
TileEntity entity = tile.entity();
|
||||||
|
|
||||||
//clear all graph data first
|
|
||||||
PowerGraph tg = entity.power.graph;
|
|
||||||
tg.clear();
|
|
||||||
|
|
||||||
entity.power.links.removeValue(other.pos());
|
entity.power.links.removeValue(other.pos());
|
||||||
other.entity.power.links.removeValue(tile.pos());
|
other.entity.power.links.removeValue(tile.pos());
|
||||||
|
|
||||||
//reflow from this point, covering all tiles on this side
|
PowerGraph newgraph = new PowerGraph();
|
||||||
tg.reflow(tile);
|
|
||||||
|
|
||||||
if(other.entity.power.graph != tg){
|
//reflow from this point, covering all tiles on this side
|
||||||
|
newgraph.reflow(tile);
|
||||||
|
|
||||||
|
if(other.entity.power.graph != newgraph){
|
||||||
//create new graph for other end
|
//create new graph for other end
|
||||||
PowerGraph og = new PowerGraph();
|
PowerGraph og = new PowerGraph();
|
||||||
//reflow from other end
|
//reflow from other end
|
||||||
@@ -95,9 +93,9 @@ public class PowerNode extends PowerBlock{
|
|||||||
super.setBars();
|
super.setBars();
|
||||||
bars.add("power", entity -> new Bar(() ->
|
bars.add("power", entity -> new Bar(() ->
|
||||||
Core.bundle.format("blocks.powerbalance",
|
Core.bundle.format("blocks.powerbalance",
|
||||||
entity.power.graph == null ? "+0" : ((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + Strings.toFixed(entity.power.graph.getPowerBalance()*60, 1))),
|
((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + Strings.toFixed(entity.power.graph.getPowerBalance()*60, 1))),
|
||||||
() -> Pal.powerBar,
|
() -> Pal.powerBar,
|
||||||
() -> entity.power.graph == null ? 0 : Mathf.clamp(entity.power.graph.getPowerProduced() / entity.power.graph.getPowerNeeded())));
|
() -> Mathf.clamp(entity.power.graph.getPowerProduced() / entity.power.graph.getPowerNeeded())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -125,7 +123,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
if(tile.entity.power.graph != null) tile.entity.power.graph.update();
|
tile.entity.power.graph.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -169,8 +167,8 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
Lines.poly(tile.drawx(), tile.drawy(), 50, laserRange*tilesize);
|
Lines.poly(tile.drawx(), tile.drawy(), 50, laserRange*tilesize);
|
||||||
|
|
||||||
for(int x = (int) (tile.x - laserRange); x <= tile.x + laserRange; x++){
|
for(int x = (int) (tile.x - laserRange - 1); x <= tile.x + laserRange + 1; x++){
|
||||||
for(int y = (int) (tile.y - laserRange); y <= tile.y + laserRange; y++){
|
for(int y = (int) (tile.y - laserRange - 1); y <= tile.y + laserRange + 1; y++){
|
||||||
Tile link = world.tile(x, y);
|
Tile link = world.tile(x, y);
|
||||||
if(link != null) link = link.target();
|
if(link != null) link = link.target();
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ public enum BlockStat{
|
|||||||
drillSpeed(StatCategory.crafting),
|
drillSpeed(StatCategory.crafting),
|
||||||
maxUnits(StatCategory.crafting),
|
maxUnits(StatCategory.crafting),
|
||||||
|
|
||||||
|
repairTime(StatCategory.shooting),
|
||||||
|
range(StatCategory.shooting),
|
||||||
shootRange(StatCategory.shooting),
|
shootRange(StatCategory.shooting),
|
||||||
inaccuracy(StatCategory.shooting),
|
inaccuracy(StatCategory.shooting),
|
||||||
shots(StatCategory.shooting),
|
shots(StatCategory.shooting),
|
||||||
@@ -51,7 +53,9 @@ public enum BlockStat{
|
|||||||
ammo(StatCategory.shooting),
|
ammo(StatCategory.shooting),
|
||||||
|
|
||||||
boostItem(StatCategory.optional),
|
boostItem(StatCategory.optional),
|
||||||
boostLiquid(StatCategory.optional),;
|
boostLiquid(StatCategory.optional),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
public final StatCategory category;
|
public final StatCategory category;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.world.modules;
|
package io.anuke.mindustry.world.modules;
|
||||||
|
|
||||||
|
import io.anuke.annotations.Annotations.NonNull;
|
||||||
import io.anuke.arc.collection.IntArray;
|
import io.anuke.arc.collection.IntArray;
|
||||||
import io.anuke.mindustry.world.blocks.power.PowerGraph;
|
import io.anuke.mindustry.world.blocks.power.PowerGraph;
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class PowerModule extends BlockModule{
|
|||||||
public float satisfaction = 0.0f;
|
public float satisfaction = 0.0f;
|
||||||
/** Specifies power which is required additionally, e.g. while a force projector is being shot at. */
|
/** Specifies power which is required additionally, e.g. while a force projector is being shot at. */
|
||||||
public float extraUse = 0f;
|
public float extraUse = 0f;
|
||||||
public PowerGraph graph = new PowerGraph();
|
public @NonNull PowerGraph graph = new PowerGraph();
|
||||||
public IntArray links = new IntArray();
|
public IntArray links = new IntArray();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||