mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-25 22:58:47 +07:00
Power transfer algo fix / Battery link fix / Fireball fix / 'and'
This commit is contained in:
parent
cc5910f997
commit
b2c99fd0fd
@ -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
|
||||
|
@ -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;
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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())){
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
317
core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java
Normal file
317
core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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){
|
||||
|
Loading…
Reference in New Issue
Block a user