Power transfer algo fix / Battery link fix / Fireball fix / 'and'

This commit is contained in:
Anuken 2018-06-30 23:59:38 -04:00
parent cc5910f997
commit b2c99fd0fd
13 changed files with 383 additions and 379 deletions

View File

@ -394,7 +394,7 @@ item.thorium.description=A dense, radioactive metal used as structural support a
item.silicon.name=Silicon
item.silcion.description=An extremely useful semiconductor, with applications in solar panels and many complex electronics.
item.plastanium.name=Plastanium
item.plastanium.description=A light, ductile material used in advanced aircraft and and fragmentation ammunition.
item.plastanium.description=A light, ductile material used in advanced aircraft and fragmentation ammunition.
item.phase-matter.name=Phase Matter
item.surge-alloy.name=Surge Alloy
item.biomatter.name=Biomatter

View File

@ -18,6 +18,7 @@ public class UnitTypes implements ContentList {
maxVelocity = 0.8f;
ammoCapacity = 0;
range = 50f;
healSpeed = 0.05f;
health = 45;
}};
@ -67,7 +68,7 @@ public class UnitTypes implements ContentList {
health = 45;
buildPower = 0.9f;
minePower = 1.1f;
healSpeed = 0.3f;
healSpeed = 0.09f;
}};
}

View File

@ -15,7 +15,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.mindustry.world.blocks.distribution.Sorter;
import io.anuke.mindustry.world.blocks.power.PowerDistributor;
import io.anuke.mindustry.world.blocks.power.PowerNode;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton;
@ -36,7 +36,7 @@ public class DebugBlocks extends BlockList implements ContentList{
}
};
powerInfinite = new PowerDistributor("powerinfinite") {
powerInfinite = new PowerNode("powerinfinite") {
{
powerCapacity = 10000f;
powerSpeed = 100f;

View File

@ -58,20 +58,20 @@ public class PowerBlocks extends BlockList implements ContentList {
health = 600;
}};
battery = new PowerGenerator("battery") {{
battery = new PowerDistributor("battery") {{
powerCapacity = 320f;
}};
batteryLarge = new PowerGenerator("battery-large") {{
batteryLarge = new PowerDistributor("battery-large") {{
size = 3;
powerCapacity = 2000f;
}};
powerNode = new PowerDistributor("power-node") {{
powerNode = new PowerNode("power-node") {{
shadow = "shadow-round-1";
}};
powerNodeLarge = new PowerDistributor("power-node-large") {{
powerNodeLarge = new PowerNode("power-node-large") {{
size = 2;
powerSpeed = 1f;
maxNodes = 5;

View File

@ -79,6 +79,7 @@ public class ProductionBlocks extends BlockList implements ContentList {
result = Liquids.oil;
inputLiquid = Liquids.water;
updateEffect = BlockFx.pulverize;
liquidCapacity = 50f;
updateEffectChance = 0.05f;
inputLiquidUse = 0.3f;
powerUse = 0.6f;

View File

@ -39,7 +39,9 @@ public class TurretBullets extends BulletList implements ContentList {
{
pierce = true;
hitTiles = false;
drag = 0.3f;
collides = false;
collidesTiles = false;
drag = 0.03f;
}
@Override

View File

@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Pools;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.content.fx.EnvironmentFx;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.TileEntity;
@ -117,6 +118,10 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
GridPoint2 p = Mathf.select(Geometry.d4);
Tile other = world.tile(tile.x + p.x, tile.y + p.y);
create(other);
if(Mathf.chance(0.05 * Timers.delta() * Mathf.clamp(flammability / 10.0))){
CallEntity.createBullet(TurretBullets.fireball, x, y, Mathf.random(360f));
}
}
if(Mathf.chance(0.1 * Timers.delta())){

View File

@ -2,9 +2,10 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.game.Team;
@ -60,7 +61,7 @@ public class DebugFragment implements Fragment {
row();
new button("fire", () -> {
for (int i = 0; i < 10; i++) {
Fire.create(world.tileWorld(player.x + Mathf.range(20), player.y + Mathf.range(20)));
Bullet.create(TurretBullets.fireball, player, player.x, player.y, Mathf.random(360f));
}
});
row();

View File

@ -128,7 +128,9 @@ public abstract class BaseBlock {
next = next.target();
if(next.block().hasLiquids && tile.entity.liquids.amount > 0f){
if(next.entity.liquids.liquid == tile.entity.liquids.liquid || next.entity.liquids.amount <= 0.01f) {
if((next.entity.liquids.liquid == tile.entity.liquids.liquid || next.entity.liquids.amount <= 0.01f) &&
next.block().acceptLiquid(next, tile, tile.entity.liquids.liquid, 0f)) {
float ofract = next.entity.liquids.amount / next.block().liquidCapacity;
float fract = tile.entity.liquids.amount / liquidCapacity;
float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (liquidCapacity), tile.entity.liquids.amount);

View File

@ -1,345 +1,55 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.entities.Player;
import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.gen.CallBlocks;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
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.Translator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class PowerDistributor extends PowerBlock {
import static io.anuke.mindustry.Vars.*;
public class PowerDistributor extends PowerBlock{
public static final float thicknessScl = 0.7f;
public static final float flashScl = 0.12f;
//last distribution block placed
private static int lastPlaced = -1;
protected Translator t1 = new Translator();
protected Translator t2 = new Translator();
protected float laserRange = 6;
protected float powerSpeed = 0.5f;
protected int maxNodes = 3;
public PowerDistributor(String name){
super(name);
expanded = true;
layer = Layer.power;
powerCapacity = 5f;
configurable = true;
}
@Override
public void setBars(){}
@Override
public void placed(Tile tile) {
Tile before = world.tile(lastPlaced);
if(linkValid(tile, before) && before.block() instanceof PowerDistributor){
CallBlocks.linkPowerDistributors(null, tile, before);
}
lastPlaced = tile.packedPosition();
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks);
stats.add(BlockStat.powerTransferSpeed, powerSpeed * 60, StatUnit.powerSecond);
}
@Override
public void update(Tile tile){
distributeLaserPower(tile);
public PowerDistributor(String name) {
super(name);
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
DistributorEntity entity = tile.entity();
other = other.target();
protected void distributePower(Tile tile){
TileEntity entity = tile.entity;
int sources = 0;
if(linkValid(tile, other)){
if(linked(tile, other)){
CallBlocks.unlinkPowerDistributors(null, tile, other);
}else if(entity.links.size < maxNodes){
CallBlocks.linkPowerDistributors(null, tile, other);
}
return false;
}
return true;
}
@Override
public void drawSelect(Tile tile){
super.drawSelect(tile);
Draw.color(Palette.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){
DistributorEntity entity = tile.entity();
Draw.color(Palette.accent);
Lines.stroke(1f);
Lines.square(tile.drawx(), tile.drawy(),
tile.block().size * tilesize / 2f + 1f + Mathf.absin(Timers.time(), 4f, 1f));
Lines.stroke(1f);
Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize/2, tile.worldy() - tilesize/2, tilesize);
Draw.color(Palette.power);
for(int x = (int)(tile.x - laserRange); x <= tile.x + laserRange; x ++){
for(int y = (int)(tile.y - laserRange); y <= tile.y + laserRange; y ++){
Tile link = world.tile(x, y);
if(link != null) link = link.target();
if(link != tile && linkValid(tile, link)){
boolean linked = linked(tile, link);
Draw.color(linked ? Palette.place : Palette.breakInvalid);
Lines.square(link.drawx(), link.drawy(),
link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f)));
if(entity.links.size >= maxNodes && !linked){
Draw.color();
Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy());
}
}
}
}
Draw.reset();
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Draw.color(Palette.placing);
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();
entity.laserColor = Mathf.lerpDelta(entity.laserColor, Mathf.clamp(entity.powerRecieved/(powerSpeed)), 0.08f);
Draw.color(Palette.powerLaserFrom, Palette.powerLaserTo, entity.laserColor * (1f-flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl));
for(int i = 0; i < entity.links.size; i ++){
Tile link = world.tile(entity.links.get(i));
if(linkValid(tile, link)) drawLaser(tile, link);
for(GridPoint2 point : Edges.getEdges(size)){
Tile target = tile.getNearby(point);
if(target != null && target.block().hasPower &&
shouldDistribute(tile, target)) sources ++;
}
Draw.color();
}
if(sources == 0) return;
@Override
public float addPower(Tile tile, float amount){
DistributorEntity entity = tile.entity();
float result = entity.power.amount / sources;
if(entity.lastRecieved != threads.getFrameID()){
entity.lastRecieved = threads.getFrameID();
entity.powerRecieved = 0f;
}
for(GridPoint2 point : Edges.getEdges(size)){
Tile target = tile.getNearby(point);
if(target == null) continue;
target = target.target();
float added = super.addPower(tile, amount);
entity.powerRecieved += added;
return added;
}
if(target.block().hasPower && shouldDistribute(tile, target)){
float diff = (tile.entity.power.amount / powerCapacity - target.entity.power.amount / target.block().powerCapacity)/1.4f;
protected boolean shouldDistribute(Tile tile, Tile other) {
return !(other.block() instanceof PowerDistributor)
|| other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
}
protected void distributeLaserPower(Tile tile){
DistributorEntity entity = tile.entity();
int targets = 0;
//validate everything first.
for(int i = 0; i < entity.links.size; i ++){
Tile target = world.tile(entity.links.get(i));
if(!linkValid(tile, target)) {
entity.links.removeIndex(i);
i --;
}else if(shouldDistribute(tile, target)){
targets ++;
}
}
float result = Math.min(entity.power.amount / targets, powerSpeed * Timers.delta());
for(int i = 0; i < entity.links.size; i ++){
Tile target = world.tile(entity.links.get(i));
if(!shouldDistribute(tile, target)) continue;
float transmit = Math.min(result * Timers.delta(), entity.power.amount);
if(target.block().acceptPower(target, tile, transmit)){
entity.power.amount -= target.block().addPower(target, transmit);
}
}
}
/*
protected void link(Tile tile, Tile other){
DistributorEntity entity = tile.entity();
if(!entity.links.contains(other.packedPosition())){
entity.links.add(other.packedPosition());
}
if(other.block() instanceof PowerDistributor){
DistributorEntity oe = other.entity();
if(!oe.links.contains(tile.packedPosition()) ){
oe.links.add(tile.packedPosition());
}
}
}
protected void unlink(Tile tile, Tile other){
DistributorEntity entity = tile.entity();
entity.links.removeValue(other.packedPosition());
if(other.block() instanceof PowerDistributor){
DistributorEntity oe = other.entity();
oe.links.removeValue(tile.packedPosition());
}
}*/
protected boolean linked(Tile tile, Tile other){
return tile.<DistributorEntity>entity().links.contains(other.packedPosition());
}
protected boolean linkValid(Tile tile, Tile link){
if(!(tile != link && link != null && link.block().hasPower)
|| link.block() instanceof PowerGenerator) return false;
if(link.block() instanceof PowerDistributor){
DistributorEntity oe = link.entity();
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize,
((PowerDistributor)link.block()).laserRange * tilesize) - tilesize/2f
+ (link.block().size-1)*tilesize/2f + (tile.block().size-1)*tilesize/2f &&
(oe.links.size < ((PowerDistributor)link.block()).maxNodes || oe.links.contains(tile.packedPosition()));
}else{
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy())
<= laserRange * tilesize - tilesize/2f + (link.block().size-1)*tilesize;
}
}
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, target.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();
float transmit = Math.min(result * Timers.delta(), diff * powerCapacity);
if(target.block().acceptPower(target, tile, transmit)){
float transferred = target.block().addPower(target, transmit);
entity.power.amount -= transferred;
}
}
}
}
@Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true)
public static void linkPowerDistributors(Player player, Tile tile, Tile other){
DistributorEntity entity = tile.entity();
if(!entity.links.contains(other.packedPosition())){
entity.links.add(other.packedPosition());
}
if(other.block() instanceof PowerDistributor){
DistributorEntity oe = other.entity();
if(!oe.links.contains(tile.packedPosition()) ){
oe.links.add(tile.packedPosition());
}
}
}
@Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true)
public static void unlinkPowerDistributors(Player player, Tile tile, Tile other){
DistributorEntity entity = tile.entity();
entity.links.removeValue(other.packedPosition());
if(other.block() instanceof PowerDistributor){
DistributorEntity oe = other.entity();
oe.links.removeValue(tile.packedPosition());
}
}
public static class DistributorEntity extends TileEntity{
public float laserColor = 0f;
public float powerRecieved = 0f;
public long lastRecieved = 0;
public IntArray links = new IntArray();
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeShort(links.size);
for(int i = 0; i < links.size; i ++){
stream.writeInt(links.get(i));
}
}
@Override
public void read(DataInputStream stream) throws IOException {
short amount = stream.readShort();
for(int i = 0; i < amount; i ++){
links.add(stream.readInt());
}
}
}
protected boolean shouldDistribute(Tile tile, Tile other) {
return !(other.block() instanceof PowerGenerator) || other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
}
@Override
public void update(Tile tile) {
distributePower(tile);
}
}

View File

@ -1,15 +1,10 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.EnumSet;
public class PowerGenerator extends PowerBlock {
public class PowerGenerator extends PowerDistributor {
public PowerGenerator(String name) {
super(name);
@ -17,43 +12,6 @@ public class PowerGenerator extends PowerBlock {
flags = EnumSet.of(BlockFlag.producer);
}
protected void distributePower(Tile tile){
TileEntity entity = tile.entity;
int sources = 0;
for(GridPoint2 point : Edges.getEdges(size)){
Tile target = tile.getNearby(point);
if(target != null && target.block().hasPower &&
shouldDistribute(tile, target)) sources ++;
}
if(sources == 0) return;
float result = entity.power.amount / sources;
for(GridPoint2 point : Edges.getEdges(size)){
Tile target = tile.getNearby(point);
if(target == null) continue;
target = target.target();
if(target.block().hasPower && shouldDistribute(tile, target)){
float transmit = Math.min(result * Timers.delta(), entity.power.amount);
if(target.block().acceptPower(target, tile, transmit)){
entity.power.amount -= target.block().addPower(target, transmit);
}
}
}
}
protected boolean shouldDistribute(Tile tile, Tile other) {
return !(other.block() instanceof PowerGenerator) || other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
}
@Override
public void update(Tile tile) {
distributePower(tile);
}
@Override
public TileEntity getEntity() {
return new GeneratorEntity();

View File

@ -0,0 +1,317 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.IntArray;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.gen.CallBlocks;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
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.Translator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class PowerNode extends PowerBlock{
public static final float thicknessScl = 0.7f;
public static final float flashScl = 0.12f;
//last distribution block placed
private static int lastPlaced = -1;
protected Translator t1 = new Translator();
protected Translator t2 = new Translator();
protected float laserRange = 6;
protected float powerSpeed = 0.5f;
protected int maxNodes = 3;
public PowerNode(String name){
super(name);
expanded = true;
layer = Layer.power;
powerCapacity = 5f;
configurable = true;
}
@Override
public void setBars(){}
@Override
public void placed(Tile tile) {
Tile before = world.tile(lastPlaced);
if(linkValid(tile, before) && before.block() instanceof PowerNode){
CallBlocks.linkPowerDistributors(null, tile, before);
}
lastPlaced = tile.packedPosition();
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks);
stats.add(BlockStat.powerTransferSpeed, powerSpeed * 60, StatUnit.powerSecond);
}
@Override
public void update(Tile tile){
distributeLaserPower(tile);
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
DistributorEntity entity = tile.entity();
other = other.target();
if(linkValid(tile, other)){
if(linked(tile, other)){
CallBlocks.unlinkPowerDistributors(null, tile, other);
}else if(entity.links.size < maxNodes){
CallBlocks.linkPowerDistributors(null, tile, other);
}
return false;
}
return true;
}
@Override
public void drawSelect(Tile tile){
super.drawSelect(tile);
Draw.color(Palette.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){
DistributorEntity entity = tile.entity();
Draw.color(Palette.accent);
Lines.stroke(1f);
Lines.square(tile.drawx(), tile.drawy(),
tile.block().size * tilesize / 2f + 1f + Mathf.absin(Timers.time(), 4f, 1f));
Lines.stroke(1f);
Lines.poly(Edges.getPixelPolygon(laserRange), tile.worldx() - tilesize/2, tile.worldy() - tilesize/2, tilesize);
Draw.color(Palette.power);
for(int x = (int)(tile.x - laserRange); x <= tile.x + laserRange; x ++){
for(int y = (int)(tile.y - laserRange); y <= tile.y + laserRange; y ++){
Tile link = world.tile(x, y);
if(link != null) link = link.target();
if(link != tile && linkValid(tile, link)){
boolean linked = linked(tile, link);
Draw.color(linked ? Palette.place : Palette.breakInvalid);
Lines.square(link.drawx(), link.drawy(),
link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Timers.time(), 4f, 1f)));
if(entity.links.size >= maxNodes && !linked){
Draw.color();
Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy());
}
}
}
}
Draw.reset();
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Draw.color(Palette.placing);
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();
entity.laserColor = Mathf.lerpDelta(entity.laserColor, Mathf.clamp(entity.powerRecieved/(powerSpeed)), 0.08f);
Draw.color(Palette.powerLaserFrom, Palette.powerLaserTo, entity.laserColor * (1f-flashScl) + Mathf.sin(Timers.time(), 1.7f, flashScl));
for(int i = 0; i < entity.links.size; i ++){
Tile link = world.tile(entity.links.get(i));
if(linkValid(tile, link)) drawLaser(tile, link);
}
Draw.color();
}
@Override
public float addPower(Tile tile, float amount){
DistributorEntity entity = tile.entity();
if(entity.lastRecieved != threads.getFrameID()){
entity.lastRecieved = threads.getFrameID();
entity.powerRecieved = 0f;
}
float added = super.addPower(tile, amount);
entity.powerRecieved += added;
return added;
}
protected boolean shouldDistribute(Tile tile, Tile other) {
return !(other.block() instanceof PowerNode)
|| other.entity.power.amount / other.block().powerCapacity < tile.entity.power.amount / powerCapacity;
}
protected void distributeLaserPower(Tile tile){
DistributorEntity entity = tile.entity();
int targets = 0;
//validate everything first.
for(int i = 0; i < entity.links.size; i ++){
Tile target = world.tile(entity.links.get(i));
if(!linkValid(tile, target)) {
entity.links.removeIndex(i);
i --;
}else if(shouldDistribute(tile, target)){
targets ++;
}
}
float result = Math.min(entity.power.amount / targets, powerSpeed * Timers.delta());
for(int i = 0; i < entity.links.size; i ++){
Tile target = world.tile(entity.links.get(i));
if(!shouldDistribute(tile, target)) continue;
float transmit = Math.min(result * Timers.delta(), entity.power.amount);
if(target.block().acceptPower(target, tile, transmit)){
entity.power.amount -= target.block().addPower(target, transmit);
}
}
}
protected boolean linked(Tile tile, Tile other){
return tile.<DistributorEntity>entity().links.contains(other.packedPosition());
}
protected boolean linkValid(Tile tile, Tile link){
if(!(tile != link && link != null && link.block().hasPower)
|| link.block() instanceof PowerGenerator) return false;
if(link.block() instanceof PowerNode){
DistributorEntity oe = link.entity();
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy()) <= Math.max(laserRange * tilesize,
((PowerNode)link.block()).laserRange * tilesize) - tilesize/2f
+ (link.block().size-1)*tilesize/2f + (tile.block().size-1)*tilesize/2f &&
(oe.links.size < ((PowerNode)link.block()).maxNodes || oe.links.contains(tile.packedPosition()));
}else{
return Vector2.dst(tile.drawx(), tile.drawy(), link.drawx(), link.drawy())
<= laserRange * tilesize - tilesize/2f + (link.block().size-1)*tilesize;
}
}
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, target.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();
}
@Remote(targets = Loc.both, called = Loc.both, in = In.blocks, forward = true)
public static void linkPowerDistributors(Player player, Tile tile, Tile other){
DistributorEntity entity = tile.entity();
if(!entity.links.contains(other.packedPosition())){
entity.links.add(other.packedPosition());
}
if(other.block() instanceof PowerNode){
DistributorEntity oe = other.entity();
if(!oe.links.contains(tile.packedPosition()) ){
oe.links.add(tile.packedPosition());
}
}
}
@Remote(targets = Loc.both, called = Loc.server, in = In.blocks, forward = true)
public static void unlinkPowerDistributors(Player player, Tile tile, Tile other){
DistributorEntity entity = tile.entity();
entity.links.removeValue(other.packedPosition());
if(other.block() instanceof PowerNode){
DistributorEntity oe = other.entity();
oe.links.removeValue(tile.packedPosition());
}
}
public static class DistributorEntity extends TileEntity{
public float laserColor = 0f;
public float powerRecieved = 0f;
public long lastRecieved = 0;
public IntArray links = new IntArray();
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeShort(links.size);
for(int i = 0; i < links.size; i ++){
stream.writeInt(links.get(i));
}
}
@Override
public void read(DataInputStream stream) throws IOException {
short amount = stream.readShort();
for(int i = 0; i < amount; i ++){
links.add(stream.readInt());
}
}
}
}

View File

@ -10,6 +10,7 @@ import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Log;
public class Fracker extends SolidPump {
protected Liquid inputLiquid;
@ -25,6 +26,7 @@ public class Fracker extends SolidPump {
public Fracker(String name) {
super(name);
hasItems = true;
itemCapacity = 20;
}
@Override
@ -74,7 +76,7 @@ public class Fracker extends SolidPump {
entity.accumulator -= itemUseTime;
}
if(entity.input >= inputLiquidUse * Timers.delta() && entity.accumulator < itemUseTime){
if(entity.input >= Math.min(inputLiquidUse * Timers.delta(), inputCapacity) && entity.accumulator < itemUseTime){
super.update(tile);
entity.input -= inputLiquidUse * Timers.delta();
entity.accumulator += Timers.delta();
@ -83,6 +85,11 @@ public class Fracker extends SolidPump {
}
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source) {
return item == inputItem && tile.entity.items.totalItems() < itemCapacity;
}
@Override
public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
if(liquid != inputLiquid){