Experimental power system changes

This commit is contained in:
Anuken 2018-03-23 20:17:35 -04:00
parent 2981dd857f
commit 7d2fd514be
50 changed files with 778 additions and 765 deletions

View File

@ -25,7 +25,7 @@ allprojects {
appName = 'Mindustry'
gdxVersion = '1.9.8'
aiVersion = '1.8.1'
uCoreVersion = 'df5b262'
uCoreVersion = '5e6c99a'
getVersionString = {
String buildVersion = getBuildVersion()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

@ -1,7 +1,7 @@
#Autogenerated file. Do not modify.
#Thu Mar 22 20:36:03 EDT 2018
#Fri Mar 23 20:15:39 EDT 2018
version=release
androidBuildCode=612
androidBuildCode=621
name=Mindustry
code=3.4
build=custom build

View File

@ -413,11 +413,7 @@ public class Renderer extends RendererModule{
//draw config selected block
if(ui.configfrag.isShown()){
Tile tile = ui.configfrag.getSelectedTile();
Draw.color(Colors.get("accent"));
Lines.stroke(1f);
Lines.square(tile.drawx(), tile.drawy(),
tile.block().size * tilesize / 2f + 1f);
Draw.reset();
tile.block().drawConfigure(tile);
}
int tilex = control.input().getBlockX();
@ -460,7 +456,7 @@ public class Renderer extends RendererModule{
Draw.reset();
//draw selected block bars and info
if(input.recipe == null && !ui.hasMouse()){
if(input.recipe == null && !ui.hasMouse() && !ui.configfrag.isShown()){
Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y);
if(tile != null && tile.block() != Blocks.air){

View File

@ -110,6 +110,7 @@ public class UI extends SceneModule{
Colors.put("breakStart", Color.YELLOW);
Colors.put("breakInvalid", Color.RED);
Colors.put("range", Colors.get("accent"));
Colors.put("power", Color.valueOf("fbd367"));
}
@Override

View File

@ -9,16 +9,16 @@ import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.mindustry.world.blocks.types.distribution.Conveyor;
import io.anuke.mindustry.world.blocks.types.distribution.Router;
import io.anuke.mindustry.world.blocks.types.production.Drill;
import io.anuke.mindustry.world.blocks.types.generation.Generator;
import io.anuke.mindustry.world.blocks.types.generation.PowerDistributor;
import io.anuke.mindustry.world.blocks.types.production.Smelter;
import io.anuke.ucore.util.Bundles;
public enum Difficulty {
easy(4f, 2f, 1f, new DestrutiveHeuristic(b -> b instanceof Generator)),
normal(2f, 1f, 1f, new DestrutiveHeuristic(b -> b instanceof Smelter || b instanceof Generator)),
hard(1.5f, 0.5f, 0.75f, new DestrutiveHeuristic(b -> b instanceof Turret || b instanceof Generator || b instanceof Drill || b instanceof Smelter)),
insane(0.5f, 0.25f, 0.5f, new DestrutiveHeuristic(b -> b instanceof Generator || b instanceof Drill || b instanceof Smelter || b instanceof Router)),
purge(0.25f, 0.01f, 0.25f, new DestrutiveHeuristic(b -> b instanceof Generator || b instanceof Drill || b instanceof Router
easy(4f, 2f, 1f, new DestrutiveHeuristic(b -> b instanceof PowerDistributor)),
normal(2f, 1f, 1f, new DestrutiveHeuristic(b -> b instanceof Smelter || b instanceof PowerDistributor)),
hard(1.5f, 0.5f, 0.75f, new DestrutiveHeuristic(b -> b instanceof Turret || b instanceof PowerDistributor || b instanceof Drill || b instanceof Smelter)),
insane(0.5f, 0.25f, 0.5f, new DestrutiveHeuristic(b -> b instanceof PowerDistributor || b instanceof Drill || b instanceof Smelter || b instanceof Router)),
purge(0.25f, 0.01f, 0.25f, new DestrutiveHeuristic(b -> b instanceof PowerDistributor || b instanceof Drill || b instanceof Router
|| b instanceof Smelter || b instanceof Conveyor || b instanceof LiquidBlock || b instanceof PowerBlock));
/**The scaling of how many waves it takes for one more enemy of a type to appear.

View File

@ -496,7 +496,7 @@ public class Tutorial{
blockPlaceX = 4;
blockPlaceY = 4;
blockRotation = 2;
targetBlock = DistributionBlocks.powerlaser;
//targetBlock = DistributionBlocks.powerlaser;
}
void onSwitch(){

View File

@ -43,8 +43,8 @@ public class DesktopInput extends InputHandler{
if((Inputs.keyTap("select") && recipe != null) || Inputs.keyTap("break")){
Vector2 vec = Graphics.world(Gdx.input.getX(), Gdx.input.getY());
mousex = (int)vec.x;
mousey = (int)vec.y;
mousex = vec.x;
mousey = vec.y;
}
if(!Inputs.keyDown("select") && !Inputs.keyDown("break")){
@ -110,7 +110,9 @@ public class DesktopInput extends InputHandler{
if(target != null && Inputs.keyTap("select") && !ui.hasMouse()){
if(target.block().isConfigurable(target)){
ui.configfrag.showConfig(target);
if((!ui.configfrag.isShown()
|| ui.configfrag.getSelectedTile().block().onConfigureTileTapped(ui.configfrag.getSelectedTile(), target)))
ui.configfrag.showConfig(target);
}else if(!ui.configfrag.hasConfigMouse()){
ui.configfrag.hideConfig();
}

View File

@ -12,6 +12,7 @@ import java.io.DataInputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.customMapDirectory;
import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.mapExtension;
public class Maps implements Disposable{
@ -76,7 +77,7 @@ public class Maps implements Disposable{
DataInputStream ds = new DataInputStream(file.read());
MapMeta meta = MapIO.readMapMeta(ds);
Map map = new Map(file.nameWithoutExtension(), meta, custom);
map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta)));
if(!headless) map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta)));
maps.put(map.name, map);
allMaps.add(map);

View File

@ -15,7 +15,7 @@ public class Item implements Comparable<Item>{
}
},
iron = new Item("iron"),
copper = new Item("copper"),
lead = new Item("lead"),
coal = new Item("coal"){
{
explosiveness = 0.2f;

View File

@ -62,7 +62,7 @@ public class Recipes {
//new Recipe(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)),
new Recipe(production, ProductionBlocks.irondrill, stack(Item.iron, 25)),
new Recipe(production, ProductionBlocks.copperdrill, stack(Item.iron, 25)),
new Recipe(production, ProductionBlocks.leaddrill, stack(Item.iron, 25)),
new Recipe(production, ProductionBlocks.coaldrill, stack(Item.iron, 25), stack(Item.iron, 40)),
new Recipe(production, ProductionBlocks.titaniumdrill, stack(Item.iron, 50), stack(Item.steel, 50)),
new Recipe(production, ProductionBlocks.uraniumdrill, stack(Item.iron, 40), stack(Item.steel, 40)),
@ -79,9 +79,7 @@ public class Recipes {
new Recipe(power, ProductionBlocks.largesolarpanel, stack(Item.iron, 30), stack(Item.silicon, 20)),
new Recipe(power, ProductionBlocks.rtgenerator, stack(Item.titanium, 20), stack(Item.steel, 20)),
new Recipe(power, ProductionBlocks.nuclearReactor, stack(Item.titanium, 40), stack(Item.densealloy, 40), stack(Item.steel, 50)),
new Recipe(power, DistributionBlocks.powerlaser, stack(Item.steel, 3), stack(Item.iron, 3)),
new Recipe(power, DistributionBlocks.powerlasercorner, stack(Item.steel, 4), stack(Item.iron, 4)),
new Recipe(power, DistributionBlocks.powerlaserrouter, stack(Item.steel, 5), stack(Item.iron, 5)),
new Recipe(power, DistributionBlocks.powernode, stack(Item.steel, 3), stack(Item.iron, 3)),
new Recipe(power, DistributionBlocks.battery, stack(Item.steel, 5), stack(Item.iron, 5)),
new Recipe(power, DistributionBlocks.batteryLarge, stack(Item.steel, 5), stack(Item.iron, 5)),

View File

@ -17,6 +17,7 @@ import io.anuke.mindustry.world.blocks.BaseBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Mathf;
@ -135,6 +136,20 @@ public class Block extends BaseBlock {
configure(tile, data);
}
/**Called when another tile is tapped while this block is selected.
* Returns whether or not this block should be deselected.*/
public boolean onConfigureTileTapped(Tile tile, Tile other){
return true;
}
public void drawConfigure(Tile tile){
Draw.color("accent");
Lines.stroke(1f);
Lines.square(tile.drawx(), tile.drawy(),
tile.block().size * tilesize / 2f + 1f);
Draw.reset();
}
public boolean isConfigurable(Tile tile){
return false;
}

View File

@ -1,17 +1,23 @@
package io.anuke.mindustry.world;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import java.util.Arrays;
public class Edges {
private static final int maxSize = 11;
private static final int maxRadius = 12;
private static GridPoint2[][] edges = new GridPoint2[maxSize][0];
private static GridPoint2[][] edgeInside = new GridPoint2[maxSize][0];
private static GridPoint2[][] inside = new GridPoint2[maxSize][0];
private static Vector2[][] polygons = new Vector2[12][0];
static{
for(int i = 0; i < maxRadius; i ++){
polygons[i] = Geometry.pixelCircle(i + 1);
}
for(int i = 0; i < maxSize; i ++){
int bot = -(int)(i/2f) - 1;
@ -43,6 +49,11 @@ public class Edges {
}
}
public static Vector2[] getPixelPolygon(int radius){
if(radius < 1 || radius > maxRadius) throw new RuntimeException("Polygon size must be between 1 and " + maxRadius);
return polygons[radius - 1];
}
public static synchronized GridPoint2[] getEdges(int size){
if(size < 0 || size > maxSize) throw new RuntimeException("Block size must be between 0 and " + maxSize);

View File

@ -75,8 +75,8 @@ public class Blocks{
drops = new ItemStack(Item.iron, 1);
}},
copper = new Ore("copper"){{
drops = new ItemStack(Item.copper, 1);
lead = new Ore("lead"){{
drops = new ItemStack(Item.lead, 1);
}},
coal = new Ore("coal"){{

View File

@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.mindustry.world.blocks.types.distribution.PowerLaser;
import io.anuke.mindustry.world.blocks.types.generation.PowerDistributor;
public class DebugBlocks {
public static final Block
@ -14,10 +14,9 @@ public class DebugBlocks {
}
},
powerInfinite = new PowerLaser("powerinfinite") {
powerInfinite = new PowerDistributor("powerinfinite") {
{
powerCapacity = 100f;
laserDirections = 4;
powerCapacity = 10000f;
}
@Override

View File

@ -1,7 +1,9 @@
package io.anuke.mindustry.world.blocks;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.mindustry.world.blocks.types.distribution.*;
import io.anuke.mindustry.world.blocks.types.generation.PowerDistributor;
import io.anuke.mindustry.world.blocks.types.storage.SortedUnloader;
import io.anuke.mindustry.world.blocks.types.storage.Unloader;
import io.anuke.mindustry.world.blocks.types.storage.Vault;
@ -74,23 +76,14 @@ public class DistributionBlocks{
liquidjunction = new LiquidJunction("liquidjunction"){{
}},
powerlaser = new PowerLaser("powerlaser"){{
powernode = new PowerDistributor("powernode"){{
}},
powerlaserrouter = new PowerLaser("powerlaserrouter"){{
laserDirections = 3;
}},
powerlasercorner = new PowerLaser("powerlasercorner"){{
laserDirections = 2;
}},
battery = new PowerLaser("battery"){{
laserDirections = 1;
battery = new PowerBlock("battery"){{
powerCapacity = 320f;
}},
batteryLarge = new PowerLaser("batterylarge"){{
laserDirections = 1;
batteryLarge = new PowerBlock("batterylarge"){{
size = 3;
powerCapacity = 2000f;
base = "batterylarge-base";
}},
teleporter = new Teleporter("teleporter"){{
}},

View File

@ -168,10 +168,10 @@ public class ProductionBlocks{
}
},
copperdrill = new Drill("copperdrill"){
leaddrill = new Drill("leaddrill"){
{
resource = Blocks.copper;
result = Item.copper;
resource = Blocks.lead;
result = Item.lead;
drillTime = 400;
}
},

View File

@ -1,11 +1,9 @@
package io.anuke.mindustry.world.blocks.types;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
public abstract class PowerBlock extends Block{
public float voltage = 0.001f;
public PowerBlock(String name) {
super(name);
@ -14,13 +12,4 @@ public abstract class PowerBlock extends Block{
hasPower = true;
group = BlockGroup.power;
}
@Override
public TileEntity getEntity(){
return new PowerEntity();
}
public static class PowerEntity extends TileEntity{
public float time; //generator time. this is a bit of a hack
}
}

View File

@ -24,7 +24,6 @@ public class ShieldBlock extends PowerBlock{
public ShieldBlock(String name) {
super(name);
voltage = powerDrain;
powerCapacity = 80f;
hasInventory = false;
}
@ -82,7 +81,7 @@ public class ShieldBlock extends PowerBlock{
entity.power.amount -= bullet.getDamage() * powerPerDamage;
}
static class ShieldEntity extends PowerEntity{
static class ShieldEntity extends TileEntity{
Shield shield;
}
}

View File

@ -20,7 +20,6 @@ public class ShieldedWallBlock extends PowerBlock{
super(name);
destructible = true;
update = false;
voltage = 0.00001f;
}
@Override
@ -72,7 +71,7 @@ public class ShieldedWallBlock extends PowerBlock{
return new ShieldedWallEntity();
}
static class ShieldedWallEntity extends PowerEntity{
static class ShieldedWallEntity extends TileEntity{
public float hit;
}
}

View File

@ -1,46 +0,0 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.generation.Generator;
import io.anuke.ucore.graphics.Draw;
public class PowerLaser extends Generator{
public Color color = Color.valueOf("e54135");
public String base = null;
public PowerLaser(String name) {
super(name);
rotate = true;
solid = true;
explosive = false;
laserDirections = 1;
health = 50;
hasInventory = false;
}
@Override
public TextureRegion[] getIcon(){
String bname = base == null ? "laser-base" : base;
return new TextureRegion[]{Draw.region(bname), Draw.region(name)};
}
@Override
public void draw(Tile tile) {
Draw.rect(base == null ? "laser-base" : base, tile.drawx(), tile.drawy());
Draw.rect(name(), tile.drawx(), tile.drawy(), tile.getRotation() * 90 - 90);
}
@Override
public void update(Tile tile){
distributeLaserPower(tile);
}
@Override
public boolean acceptPower(Tile tile, Tile from, float amount){
PowerEntity entity = tile.entity();
return entity.power.amount <= powerCapacity;
}
}

View File

@ -138,7 +138,7 @@ public class Teleporter extends PowerBlock{
@Override
public void handleItem(Item item, Tile tile, Tile source){
PowerEntity entity = tile.entity();
TeleporterEntity entity = tile.entity();
Array<Tile> links = findLinks(tile);
@ -154,7 +154,7 @@ public class Teleporter extends PowerBlock{
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
PowerEntity entity = tile.entity();
TeleporterEntity entity = tile.entity();
return !(source.block() instanceof Teleporter) && entity.power.amount >= powerPerItem && findLinks(tile).size > 0;
}
@ -189,7 +189,7 @@ public class Teleporter extends PowerBlock{
return returns;
}
public static class TeleporterEntity extends PowerEntity{
public static class TeleporterEntity extends TileEntity{
public byte color = 0;
@Override

View File

@ -1,266 +0,0 @@
package io.anuke.mindustry.world.blocks.types.generation;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.world.Layer;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class Generator extends PowerBlock{
public static boolean drawRangeOverlay = false;
public static final float thicknessScl = 0.85f * 0.7f;
public static final float laserMinValue = 0f;
public static final Color laserFrom = Color.valueOf("d0bdd2");
public static final Color laserTo = Color.valueOf("ffe7a8");
protected Translator t1 = new Translator();
protected Translator t2 = new Translator();
public int laserRange = 6;
public int laserDirections = 4;
public float powerSpeed = 0.5f;
public boolean explosive = true;
public boolean hasLasers = true;
public boolean outputOnly = false;
public Generator(String name){
super(name);
expanded = true;
layer = Layer.power;
}
@Override
public void setStats(){
super.setStats();
if(hasLasers){
stats.add("lasertilerange", laserRange);
stats.add("maxpowertransfersecond", Strings.toFixed(powerSpeed * 60, 2));
}
//TODO fix this
if(explosive){
stats.add("explosive", "!!! //TODO");
}
}
@Override
public void drawSelect(Tile tile){
super.drawSelect(tile);
if(drawRangeOverlay){
int rotation = tile.getRotation();
if(hasLasers){
Draw.color(Color.YELLOW);
Lines.stroke(2f);
for(int i = 0; i < laserDirections; i++){
int dir = Mathf.mod(i + rotation - laserDirections / 2, 4);
float lx = Geometry.d4[dir].x, ly = Geometry.d4[dir].y;
float dx = lx * laserRange * tilesize;
float dy = ly * laserRange * tilesize;
Lines.dashLine(
tile.worldx() + lx * tilesize / 2,
tile.worldy() + ly * tilesize / 2,
tile.worldx() + dx - lx * tilesize,
tile.worldy() + dy - ly * tilesize, 9);
}
Draw.reset();
}
}
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
if(hasLasers){
Draw.color("place");
Lines.stroke(2f);
for(int i = 0; i < laserDirections; i++){
int dir = Mathf.mod(i + rotation - laserDirections / 2, 4);
float lx = Geometry.d4[dir].x, ly = Geometry.d4[dir].y;
float dx = lx * laserRange * tilesize;
float dy = ly * laserRange * tilesize;
Lines.dashLine(
x * tilesize + lx * tilesize / 2,
y * tilesize + ly * tilesize / 2,
x * tilesize + dx - lx * tilesize,
y * tilesize + dy - ly * tilesize, 9);
}
Draw.reset();
}
}
@Override
public void onDestroyed(Tile tile){
if(explosive){
float x = tile.worldx(), y = tile.worldy();
Effects.effect(Fx.shellsmoke, x, y);
Effects.effect(Fx.blastsmoke, x, y);
Timers.run(Mathf.random(8f + Mathf.random(6f)), () -> {
Effects.shake(6f, 8f, x, y);
Effects.effect(Fx.generatorexplosion, x, y);
Effects.effect(Fx.shockwave, x, y);
//TODO better explosion effect!
Effects.sound(explosionSound, x, y);
});
}else{
super.onDestroyed(tile);
}
}
@Override
public void drawLayer(Tile tile){
if(!Settings.getBool("lasers")) return;
GeneratorEntity entity = tile.entity();
if(entity.power.amount > powerSpeed){
entity.laserThickness = Mathf.lerpDelta(entity.laserThickness, 1f, 0.05f);
}else{
entity.laserThickness = Mathf.lerpDelta(entity.laserThickness, laserMinValue, 0.05f);
}
for(int i = 0; i < laserDirections; i++){
drawLaserTo(tile, (tile.getRotation() + i) - laserDirections / 2);
}
Draw.color();
}
//@Override
//public boolean acceptPower(Tile tile, Tile source, float amount){
// return false;
//}
@Override
public TileEntity getEntity() {
return new GeneratorEntity();
}
public static class GeneratorEntity extends PowerEntity{
float laserThickness = laserMinValue;
}
protected void distributeLaserPower(Tile tile){
PowerEntity entity = tile.entity();
for(int i = 0; i < laserDirections; i++){
int rot = (tile.getRotation() + i) - laserDirections / 2;
Tile target = laserTarget(tile, rot);
if(target == null)
continue;
if(isInterfering(target, rot)){
float fract = tile.entity.power.amount / powerCapacity;
float ofract = target.entity.power.amount / target.block().powerCapacity;
if(ofract > fract) continue;
}
float transmit = Math.min(powerSpeed * Timers.delta(), entity.power.amount);
if(target.block().acceptPower(target, tile, transmit)){
float accepted = target.block().addPower(target, transmit);
entity.power.amount -= accepted;
}
}
}
protected void drawLaserTo(Tile tile, int rotation){
Tile target = laserTarget(tile, rotation);
GeneratorEntity entity = tile.entity();
float scale = thicknessScl;
if(target != null){
boolean interfering = isInterfering(target, rotation);
t1.trns(rotation * 90, tilesize / 2 + 2f +
(interfering ? Vector2.dst(tile.worldx(), tile.worldy(), target.worldx(),
target.worldy()) / 2f - tilesize / 2f * 1 : 0));
t2.trns(rotation * 90, size * tilesize / 2 + 2f);
Draw.tint(Hue.mix(laserFrom, laserTo, entity.laserThickness * 0.93f + Mathf.sin(Timers.time(), 1.7f, 0.07f)));
int relative = tile.sizedRelativeTo(target.x, target.y);
if(relative == -1){
Shapes.laser("laser", "laserend", tile.worldx() + t2.x, tile.worldy() + t2.y,
target.worldx() - t1.x,
target.worldy() - t1.y, scale);
}else{
float lf = 1f;
float s = interfering ? 12f : 18f;
float sclx = (relative == 1 || relative == 3) ? lf : 1f;
float scly = (relative == 1 || relative == 3) ? 1f : lf;
Draw.rect("laserfull",
tile.worldx() + Geometry.d4[relative].x * size * tilesize / 2f,
tile.worldy() + Geometry.d4[relative].y * size * tilesize / 2f , s * sclx, s * scly);
}
Draw.color();
}
}
protected boolean isInterfering(Tile target, int rotation){
if(target.block() instanceof Generator){
Generator other = (Generator) target.block();
int relrot = (rotation + 2) % 4;
if(other.hasLasers){
for(int i = 0; i < other.laserDirections; i ++){
if(Mathf.mod(target.getRotation() + i - other.laserDirections/2, 4) == relrot){
return true;
}
}
}
}
return false;
}
protected Tile laserTarget(Tile tile, int rotation){
rotation = Mathf.mod(rotation, 4);
GridPoint2 point = Geometry.d4[rotation];
for(int i = 1; i < laserRange; i++){
Tile other = world.tile(tile.x + i * point.x, tile.y + i * point.y);
if(other != null && other.block().hasPower){
Tile linked = other.getLinked();
if((linked == null || linked.block().hasPower) && linked != tile){
return other;
}
}
}
return null;
}
}

View File

@ -6,6 +6,7 @@ import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.generation.PowerGenerator.GeneratorEntity;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
@ -13,7 +14,7 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
public class ItemPowerGenerator extends Generator{
public class ItemPowerGenerator extends PowerGenerator {
public int itemCapacity = 20;
public Item generateItem;
public float powerOutput;
@ -23,7 +24,6 @@ public class ItemPowerGenerator extends Generator{
public ItemPowerGenerator(String name) {
super(name);
outputOnly = true;
}
@Override
@ -43,12 +43,12 @@ public class ItemPowerGenerator extends Generator{
@Override
public void draw(Tile tile){
super.draw(tile);
GeneratorEntity entity = tile.entity();
PowerEntity entity = tile.entity();
if(entity.time > 0){
if(entity.generateTime > 0){
Draw.color(heatColor);
float alpha = (entity.inventory.hasItem(generateItem) ? 1f : Mathf.clamp(entity.time));
float alpha = (entity.inventory.hasItem(generateItem) ? 1f : Mathf.clamp(entity.generateTime));
alpha = alpha * 0.7f + Mathf.absin(Timers.time(), 12f, 0.3f) * alpha;
Draw.alpha(alpha);
Draw.rect(name + "-top", tile.worldx(), tile.worldy());
@ -63,24 +63,24 @@ public class ItemPowerGenerator extends Generator{
@Override
public void update(Tile tile){
PowerEntity entity = tile.entity();
GeneratorEntity entity = tile.entity();
float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta());
float mfract = maxPower/(powerOutput);
if(entity.time > 0f){
entity.time -= 1f/itemDuration*mfract;
if(entity.generateTime > 0f){
entity.generateTime -= 1f/itemDuration*mfract;
entity.power.amount += maxPower;
entity.time = Mathf.clamp(entity.time);
entity.generateTime = Mathf.clamp(entity.generateTime);
}
if(entity.time <= 0f && entity.inventory.hasItem(generateItem)){
if(entity.generateTime <= 0f && entity.inventory.hasItem(generateItem)){
Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f));
entity.inventory.removeItem(generateItem, 1);
entity.time = 1f;
entity.generateTime = 1f;
}
distributeLaserPower(tile);
distributePower(tile);
}

View File

@ -11,7 +11,7 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
public class LiquidPowerGenerator extends Generator{
public class LiquidPowerGenerator extends PowerGenerator {
public Liquid generateLiquid;
public float powerPerLiquid = 0.13f;
/**Maximum liquid used per frame.*/
@ -20,7 +20,6 @@ public class LiquidPowerGenerator extends Generator{
public LiquidPowerGenerator(String name) {
super(name);
outputOnly = true;
liquidCapacity = 30f;
hasLiquids = true;
}
@ -66,8 +65,7 @@ public class LiquidPowerGenerator extends Generator{
}
}
distributeLaserPower(tile);
distributePower(tile);
}
@Override

View File

@ -46,7 +46,6 @@ public class NuclearReactor extends LiquidPowerGenerator{
itemCapacity = 30;
liquidCapacity = 50;
explosionEffect = Fx.nuclearShockwave;
explosive = true;
powerCapacity = 80f;
powerSpeed = 0.5f;
}
@ -111,7 +110,7 @@ public class NuclearReactor extends LiquidPowerGenerator{
if(entity.heat >= 1f){
entity.damage((int)entity.health);
}else{
distributeLaserPower(tile);
distributePower(tile);
}
}
@ -192,7 +191,7 @@ public class NuclearReactor extends LiquidPowerGenerator{
return new NuclearReactorEntity();
}
public static class NuclearReactorEntity extends GeneratorEntity{
public static class NuclearReactorEntity extends GeneratorEntity {
public float heat;
public float flash;

View File

@ -0,0 +1,217 @@
package io.anuke.mindustry.world.blocks.types.generation;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Layer;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.Translator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class PowerDistributor extends PowerBlock{
public static final float thicknessScl = 0.7f;
public static final float flashScl = 0.07f;
public static final float laserMinValue = 0f;
public static final Color laserFrom = Color.valueOf("e3e3e3");
public static final Color laserTo = Color.valueOf("ffe7a8");
//last distribution block placed
private static int lastPlaced = -1;
protected Translator t1 = new Translator();
protected Translator t2 = new Translator();
public int laserRange = 6;
public float powerSpeed = 0.5f;
public PowerDistributor(String name){
super(name);
expanded = true;
layer = Layer.power;
hasInventory = false;
}
@Override
public void placed(Tile tile) {
Tile before = world.tile(lastPlaced);
if(linkValid(tile, before)){
tile.<DistributorEntity>entity().links.add(before.packedPosition());
}
lastPlaced = tile.packedPosition();
}
@Override
public boolean isConfigurable(Tile tile){
return true;
}
@Override
public void setStats(){
super.setStats();
stats.add("lasertilerange", laserRange);
stats.add("maxpowertransfersecond", Strings.toFixed(powerSpeed * 60, 2));
}
@Override
public void update(Tile tile){
distributeLaserPower(tile);
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
DistributorEntity entity = tile.entity();
if(linkValid(tile, other)){
if(entity.links.contains(other.packedPosition())){
entity.links.removeValue(other.packedPosition());
}else{
entity.links.add(other.packedPosition());
}
return false;
}
return true;
}
@Override
public void drawSelect(Tile tile){
super.drawSelect(tile);
Draw.color("power");
Lines.stroke(1f);
Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize/2, tile.worldy() - tilesize/2, tilesize);
Draw.reset();
}
@Override
public void drawConfigure(Tile tile){
Draw.color("accent");
Lines.stroke(1f);
Lines.square(tile.drawx(), tile.drawy(),
tile.block().size * tilesize / 2f + 1f);
Lines.stroke(1f);
Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize/2, tile.worldy() - tilesize/2, tilesize);
Draw.color("power");
for(int x = tile.x - laserRange; x <= tile.x + laserRange; x ++){
for(int y = tile.y - laserRange; y <= tile.y + laserRange; y ++){
Tile link = world.tile(x, y);
if(link != tile && linkValid(tile, link)){
Lines.square(link.drawx(), link.drawy(),
link.block().size * tilesize / 2f + 1f);
}
}
}
Draw.reset();
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Draw.color("place");
Lines.stroke(1f);
Lines.poly(Edges.getPixelPolygon(laserRange), x * tilesize - tilesize/2, y * tilesize - tilesize/2, tilesize);
Draw.reset();
}
@Override
public void drawLayer(Tile tile){
if(!Settings.getBool("lasers")) return;
DistributorEntity entity = tile.entity();
if(entity.power.amount > powerSpeed){
entity.laserColor = Mathf.lerpDelta(entity.laserColor, 1f, 0.05f);
}else{
entity.laserColor = Mathf.lerpDelta(entity.laserColor, laserMinValue, 0.05f);
}
Draw.color(laserFrom, laserTo, entity.laserColor * (1f-flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl));
for(int i = 0; i < entity.links.size; i ++){
Tile link = world.tile(entity.links.get(i));
if(linkValid(tile, link)) drawLaser(tile, link);
}
Draw.color();
}
protected void distributeLaserPower(Tile tile){
DistributorEntity entity = tile.entity();
//TODO implement
}
protected boolean linkValid(Tile tile, Tile link){
return tile != link && link != null && link.block() instanceof PowerDistributor &&
Vector2.dst(tile.worldx(), tile.worldy(), link.worldx(), link.worldy()) < Math.max(laserRange * tilesize,
((PowerDistributor)link.block()).laserRange * tilesize);
}
protected void drawLaser(Tile tile, Tile target){
float x1 = tile.drawx(), y1 = tile.drawy(),
x2 = target.drawx(), y2 = target.drawy();
float angle1 = Angles.angle(x1, y1, x2, y2);
float angle2 = angle1 + 180f;
t1.trns(angle1, tile.block().size * tilesize/2f + 1f);
t2.trns(angle2,tile.block().size * tilesize/2f + 1f);
Shapes.laser("laser", "laser-end", x1 + t1.x, y1 + t1.y,
x2 + t2.x, y2 + t2.y, thicknessScl);
}
@Override
public TileEntity getEntity() {
return new DistributorEntity();
}
public static class DistributorEntity extends TileEntity{
public float laserColor = laserMinValue;
public IntArray links = new IntArray();
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeShort(links.size);
for(int i = 0; i < links.size; i ++){
stream.writeInt(links.get(i));
}
}
@Override
public void read(DataInputStream stream) throws IOException {
short amount = stream.readShort();
for(int i = 0; i < amount; i ++){
links.add(stream.readInt());
}
}
}
}

View File

@ -0,0 +1,48 @@
package io.anuke.mindustry.world.blocks.types.generation;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
public class PowerGenerator extends PowerBlock {
protected float powerSpeed = 1f;
public PowerGenerator(String name) {
super(name);
}
protected void distributePower(Tile tile){
//TODO!
}
@Override
public void onDestroyed(Tile tile){
float x = tile.worldx(), y = tile.worldy();
Effects.effect(Fx.shellsmoke, x, y);
Effects.effect(Fx.blastsmoke, x, y);
Timers.run(Mathf.random(8f + Mathf.random(6f)), () -> {
Effects.shake(6f, 8f, x, y);
Effects.effect(Fx.generatorexplosion, x, y);
Effects.effect(Fx.shockwave, x, y);
//TODO better explosion effect!
Effects.sound(explosionSound, x, y);
});
}
@Override
public TileEntity getEntity() {
return new GeneratorEntity();
}
public static class GeneratorEntity extends TileEntity{
public float generateTime;
}
}

View File

@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks.types.generation;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
public class SolarGenerator extends Generator {
public class SolarGenerator extends PowerGenerator {
/**power generated per frame*/
protected float generation = 0.005f;
@ -16,7 +16,7 @@ public class SolarGenerator extends Generator {
public void update(Tile tile){
addPower(tile, generation * Timers.delta());
distributeLaserPower(tile);
distributePower(tile);
}
}

View File

@ -160,7 +160,7 @@ public class PowerSmelter extends PowerBlock {
return new PowerSmelterEntity();
}
class PowerSmelterEntity extends PowerEntity{
class PowerSmelterEntity extends TileEntity{
public float heat;
}
}

View File

@ -0,0 +1,109 @@
package io.anuke.mindustry.server.mapgen;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntIntMap;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.ucore.util.Mathf;
public class Colorizer {
Color tmp = new Color();
float[] hsv1 = new float[3];
float[] hsv2 = new float[3];
float target = 240f;
float shift = 12f;
float e = 0.05f;
public void process(FileHandle in, FileHandle out){
for(FileHandle child : in.list()){
if(child.isDirectory()){
process(child, out);
}else if(child.extension().equals("png")){
PixmapIO.writePNG(out.child(child.name()), colorize(new Pixmap(child)));
}
}
}
public Pixmap colorize(Pixmap pixmap){
Array<Array<Color>> colors = new Array<>();
IntSet used = new IntSet();
for(int x = 0; x < pixmap.getWidth(); x ++){
for(int y = 0; y < pixmap.getHeight(); y ++){
tmp.set(pixmap.getPixel(x, y));
if(tmp.a <= 0.1f || used.contains(Color.rgba8888(tmp))) continue;
used.add(Color.rgba8888(tmp));
boolean found = false;
outer:
for(Array<Color> arr : colors){
for(Color color : arr){
if(isSameShade(color, tmp)){
arr.add(tmp.cpy());
found = true;
break outer;
}
}
}
if(!found){
colors.add(Array.with(tmp.cpy()));
}
}
}
colors.forEach(a -> a.sort((c1, c2) -> Float.compare(c1.toHsv(hsv1)[2], c2.toHsv(hsv2)[2])));
IntIntMap map = new IntIntMap();
for(Array<Color> arr : colors){
for(int i = 0; i < arr.size; i ++){
int shift = arr.size - 1 - i;
map.put(Color.rgba8888(arr.get(i)), Color.rgba8888(shift(arr.get(i), shift)));
}
}
Pixmap result = new Pixmap(pixmap.getWidth(), pixmap.getHeight(), pixmap.getFormat());
for(int x = 0; x < pixmap.getWidth(); x ++) {
for (int y = 0; y < pixmap.getHeight(); y++) {
result.drawPixel(x, y, map.get(pixmap.getPixel(x, y), 0));
}
}
return result;
}
Color shift(Color color, int amount){
color.toHsv(hsv1);
float h = hsv1[0];
/*if(hsv1[1] < e){
hsv1[1] += amount * 0.1f;
h = Mathf.lerp(0f, target, amount * 0.08f);
}*/
float s = amount * shift;
if(Math.abs(h - target) < s){
h = target;
}else{
if(h > target) h -= s;
if(h < target) h += s;
}
hsv1[0] = h;
tmp.fromHsv(hsv1);
tmp.a = color.a;
return tmp;
}
boolean isSameShade(Color a, Color b){
a.toHsv(hsv1);
b.toHsv(hsv2);
return Mathf.near(hsv1[0], hsv2[0], e*360f) && Mathf.near(hsv1[1], hsv2[1], e);
}
}