diff --git a/core/assets/shaders/planet.vertex.glsl b/core/assets/shaders/planet.vertex.glsl index e173b4d57e..b579d9b41d 100755 --- a/core/assets/shaders/planet.vertex.glsl +++ b/core/assets/shaders/planet.vertex.glsl @@ -10,7 +10,6 @@ uniform vec3 u_ambientColor; varying vec4 v_col; const vec3 ambientColor = vec3(1.0); -const vec3 ambientDir = normalize(vec3(1.0, 1.0, 1.0)); const vec3 diffuse = vec3(0.2); const vec3 v1 = vec3(1.0, 0.0, 1.0); const vec3 v2 = vec3(1.0, 0.5, 0.0); diff --git a/core/src/mindustry/entities/def/TileComp.java b/core/src/mindustry/entities/def/TileComp.java index a975b1fc82..a8183ce087 100644 --- a/core/src/mindustry/entities/def/TileComp.java +++ b/core/src/mindustry/entities/def/TileComp.java @@ -409,6 +409,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{ public void offloadNear(Item item){ Array proximity = proximity(); int dump = rotation(); + useContent(item); for(int i = 0; i < proximity.size; i++){ incrementDump(proximity.size); @@ -544,8 +545,8 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{ return out; } - public float getProgressIncrease(Tilec entity, float baseTime){ - return 1f / baseTime * entity.delta() * entity.efficiency(); + public float getProgressIncrease(float baseTime){ + return 1f / baseTime * delta() * efficiency(); } /** @return whether this block should play its active sound.*/ @@ -654,16 +655,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{ } } - public float percentSolid(int x, int y){ - Tile tile = world.tile(x, y); - if(tile == null) return 0; - float sum = 0; - for(Tile other : tile.getLinkedTilesAs(block, tempTiles)){ - sum += !other.floor().isLiquid ? 1f : 0f; - } - return sum / block.size / block.size; - } - /** Called when arbitrary configuration is applied to a tile. */ public void configured(@Nullable Playerc player, @Nullable Object value){ //null is of type Void.class; anonymous classes use their superclass. diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index bb51635a4e..d5365649bf 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -51,10 +51,10 @@ public class EventType{ public static class MapPublishEvent{} public static class CommandIssueEvent{ - public final Tile tile; + public final Tilec tile; public final UnitCommand command; - public CommandIssueEvent(Tile tile, UnitCommand command){ + public CommandIssueEvent(Tilec tile, UnitCommand command){ this.tile = tile; this.command = command; } diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 743a68d862..2fb8a88d07 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -168,6 +168,7 @@ public class Block extends UnlockableContent{ //TODO move public static TextureRegion[][] cracks; protected static final Array tempTiles = new Array<>(); + protected static final Array tempTileEnts = new Array<>(); /** Dump timer ID.*/ protected final int timerDump = timers++; @@ -189,6 +190,16 @@ public class Block extends UnlockableContent{ } } + public float percentSolid(int x, int y){ + Tile tile = world.tile(x, y); + if(tile == null) return 0; + float sum = 0; + for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ + sum += !other.floor().isLiquid ? 1f : 0f; + } + return sum / size / size; + } + public void drawLayer(Tile tile){ if(tile.entity != null) tile.entity.drawLayer(); } diff --git a/core/src/mindustry/world/blocks/Autotiler.java b/core/src/mindustry/world/blocks/Autotiler.java index d9fa14a3df..a2f8f13dd1 100644 --- a/core/src/mindustry/world/blocks/Autotiler.java +++ b/core/src/mindustry/world/blocks/Autotiler.java @@ -37,7 +37,7 @@ public interface Autotiler{ return buildBlending(req.tile(), req.rotation, directionals, req.worldContext); } - default int[] buildBlending(int rotation, BuildRequest[] directional, boolean world){ + default int[] buildBlending(Tile tile, int rotation, BuildRequest[] directional, boolean world){ int[] blendresult = AutotilerHolder.blendresult; blendresult[0] = 0; blendresult[1] = blendresult[2] = 1; @@ -71,7 +71,7 @@ public interface Autotiler{ } } - default boolean blends(int rotation, @Nullable BuildRequest[] directional, int direction, boolean checkWorld){ + default boolean blends(Tile tile, int rotation, @Nullable BuildRequest[] directional, int direction, boolean checkWorld){ int realDir = Mathf.mod(rotation - direction, 4); if(directional != null && directional[realDir] != null){ BuildRequest req = directional[realDir]; @@ -82,21 +82,21 @@ public interface Autotiler{ return checkWorld && blends(tile, rotation, direction); } - default boolean blends(int rotation, int direction){ + default boolean blends(Tile tile, int rotation, int direction){ Tilec other = tile.getNearbyEntity(Mathf.mod(rotation - direction, 4)); - return other != null && other.team() == team && blends(tile, rotation, other.tileX(), other.tileY(), other.rotation(), other.block()); + return other != null && other.team() == tile.team() && blends(tile, rotation, other.tileX(), other.tileY(), other.rotation(), other.block()); } - default boolean blendsArmored(int rotation, int otherx, int othery, int otherrot, Block otherblock){ + default boolean blendsArmored(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery) || ((!otherblock.rotate && Edges.getFacingEdge(otherblock, otherx, othery, tile) != null && Edges.getFacingEdge(otherblock, otherx, othery, tile).relativeTo(tile) == rotation) || (otherblock.rotate && Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y)))); } - default boolean lookingAt(int rotation, int otherx, int othery, int otherrot, Block otherblock){ + default boolean lookingAt(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery) || (!otherblock.rotate || Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y))); } - boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock); + boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock); } diff --git a/core/src/mindustry/world/blocks/BuildBlock.java b/core/src/mindustry/world/blocks/BuildBlock.java index cedf195f24..640ddbb2d7 100644 --- a/core/src/mindustry/world/blocks/BuildBlock.java +++ b/core/src/mindustry/world/blocks/BuildBlock.java @@ -49,27 +49,27 @@ public class BuildBlock extends Block{ } @Remote(called = Loc.server) - public static void onDeconstructFinish(Block block, int builderID){ - Team team = team; - Fx.breakBlock.at(x, y, block.size); + public static void onDeconstructFinish(Tile tile, Block block, int builderID){ + Team team = tile.team(); + Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size); Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, true)); tile.remove(); if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false)); } @Remote(called = Loc.server) - public static void onConstructFinish(Block block, int builderID, byte rotation, Team team, boolean skipConfig){ + public static void onConstructFinish(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){ if(tile == null) return; - float healthf = tile.healthf(); + float healthf = tile.entity.healthf(); tile.setBlock(block, team, (int)rotation); - tile.health(block.health * healthf); + tile.entity.health(block.health * healthf); //last builder was this local client player, call placed() if(!headless && builderID == player.unit().id()){ if(!skipConfig){ - tile.playerPlaced(); + tile.entity.playerPlaced(); } } - Fx.placeBlock.at(x, y, block.size); + Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size); } static boolean shouldPlay(){ @@ -96,9 +96,9 @@ public class BuildBlock extends Block{ } } - public static void constructed(Block block, int builderID, byte rotation, Team team, boolean skipConfig){ + public static void constructed(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){ Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig); - tile.placed(); + tile.entity.placed(); Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false)); if(shouldPlay()) Sounds.place.at(tile, calcPitch(true)); diff --git a/core/src/mindustry/world/blocks/distribution/ArmoredConveyor.java b/core/src/mindustry/world/blocks/distribution/ArmoredConveyor.java index fc3dbd49d7..82a6f418da 100644 --- a/core/src/mindustry/world/blocks/distribution/ArmoredConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/ArmoredConveyor.java @@ -11,8 +11,8 @@ public class ArmoredConveyor extends Conveyor{ } @Override - public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock) { - return otherblock.outputsItems() && blendsArmored(rotation, otherx, othery, otherrot, otherblock); + public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock) { + return otherblock.outputsItems() && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock); } public class ArmoredConveyorEntity extends ConveyorEntity{ diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index 83fb2b4315..cdf4f6a751 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -76,8 +76,8 @@ public class Conveyor extends Block implements Autotiler{ } @Override - public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){ - return otherblock.outputsItems() && lookingAt(rotation, otherx, othery, otherrot, otherblock); + public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ + return otherblock.outputsItems() && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock); } @Override @@ -138,7 +138,7 @@ public class Conveyor extends Block implements Autotiler{ public void onProximityUpdate(){ super.onProximityUpdate(); - int[] bits = buildBlending(rotation(), null, true); + int[] bits = buildBlending(tile, rotation(), null, true); blendbits = bits[0]; blendsclx = bits[1]; blendscly = bits[2]; diff --git a/core/src/mindustry/world/blocks/distribution/MassDriver.java b/core/src/mindustry/world/blocks/distribution/MassDriver.java index 26b666a288..1bded3cd96 100644 --- a/core/src/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/mindustry/world/blocks/distribution/MassDriver.java @@ -41,8 +41,8 @@ public class MassDriver extends Block{ hasPower = true; outlineIcon = true; //point2 is relative - config(Point2.class, (tile, point) -> tile.ent().link = Point2.pack(point.x + tile.x, point.y + tile.y)); - config(Integer.class, (tile, point) -> tile.ent().link = point); + config(Point2.class, (tile, point) -> ((MassDriverEntity)tile).link = Point2.pack(point.x + tile.tileX(), point.y + tile.tileY())); + config(Integer.class, (tile, point) -> ((MassDriverEntity)tile).link = point); } @Override @@ -57,114 +57,20 @@ public class MassDriver extends Block{ baseRegion = Core.atlas.find(name + "-base"); } - @Override - public void updateTile(){ - Tile link = world.tile(link); - boolean hasLink = linkValid(tile); - - //reload regardless of state - if(reload > 0f){ - reload = Mathf.clamp(reload - delta() / reloadTime * efficiency()); - } - - //cleanup waiting shooters that are not valid - if(!shooterValid(tile, currentShooter())){ - waitingShooters.remove(currentShooter()); - } - - //switch states - if(state == DriverState.idle){ - //start accepting when idle and there's space - if(!waitingShooters.isEmpty() && (itemCapacity - items.total() >= minDistribute)){ - state = DriverState.accepting; - }else if(hasLink){ //switch to shooting if there's a valid link. - state = DriverState.shooting; - } - } - - //dump when idle or accepting - if(state == DriverState.idle || state == DriverState.accepting){ - tryDump(tile); - } - - //skip when there's no power - if(!consValid()){ - return; - } - - if(state == DriverState.accepting){ - //if there's nothing shooting at this, bail - OR, items full - if(currentShooter() == null || (itemCapacity - items.total() < minDistribute)){ - state = DriverState.idle; - return; - } - - //align to shooter rotation - rotation = Mathf.slerpDelta(rotation, tile.angleTo(currentShooter()), rotateSpeed * efficiency()); - }else if(state == DriverState.shooting){ - //if there's nothing to shoot at OR someone wants to shoot at this thing, bail - if(!hasLink || (!waitingShooters.isEmpty() && (itemCapacity - items.total() >= minDistribute))){ - state = DriverState.idle; - return; - } - - float targetRotation = tile.angleTo(link); - - if( - tile.items.total() >= minDistribute && //must shoot minimum amount of items - link.block().itemCapacity - link.items.total() >= minDistribute //must have minimum amount of space - ){ - MassDriverEntity other = link.ent(); - other.waitingShooters.add(tile); - - if(reload <= 0.0001f){ - - //align to target location - rotation = Mathf.slerpDelta(rotation, targetRotation, rotateSpeed * efficiency()); - - //fire when it's the first in the queue and angles are ready. - if(other.currentShooter() == tile && - other.state == DriverState.accepting && - Angles.near(rotation, targetRotation, 2f) && Angles.near(other.rotation, targetRotation + 180f, 2f)){ - //actually fire - fire(tile, link); - //remove waiting shooters, it's done firing - other.waitingShooters.remove(tile); - //set both states to idle - state = DriverState.idle; - other.state = DriverState.idle; - } - } - } - } - } - - @Override - public void draw(){ - Draw.rect(baseRegion, x, y); - } - - @Override - public void drawLayer(){ - Draw.rect(region, - x + Angles.trnsx(rotation + 180f, reload * knockback), - y + Angles.trnsy(rotation + 180f, reload * knockback), rotation - 90); - } - @Override public void drawPlace(int x, int y, int rotation, boolean valid){ Drawf.dashCircle(x * tilesize, y*tilesize, range, Pal.accent); //check if a mass driver is selected while placing this driver if(!control.input.frag.config.isShown()) return; - Tile selected = control.input.frag.config.getSelectedTile(); + Tilec selected = control.input.frag.config.getSelectedTile(); if(selected == null || !(selected.block() instanceof MassDriver) || !(selected.dst(x * tilesize, y * tilesize) <= range)) return; //if so, draw a dotted line towards it while it is in range float sin = Mathf.absin(Time.time(), 6f, 1f); - Tmp.v1.set(x * tilesize + offset(), y * tilesize + offset()).sub(selected.drawx(), selected.drawy()).limit((size / 2f + 1) * tilesize + sin + 0.5f); + Tmp.v1.set(x * tilesize + offset(), y * tilesize + offset()).sub(selected.x(), selected.y()).limit((size / 2f + 1) * tilesize + sin + 0.5f); float x2 = x * tilesize - Tmp.v1.x, y2 = y * tilesize - Tmp.v1.y, - x1 = selected.drawx() + Tmp.v1.x, y1 = selected.drawy() + Tmp.v1.y; + x1 = selected.x() + Tmp.v1.x, y1 = selected.y() + Tmp.v1.y; int segs = (int)(selected.dst(x * tilesize, y * tilesize) / tilesize); Lines.stroke(4f, Pal.gray); @@ -174,119 +80,6 @@ public class MassDriver extends Block{ Draw.reset(); } - @Override - public void drawConfigure(){ - float sin = Mathf.absin(Time.time(), 6f, 1f); - - Draw.color(Pal.accent); - Lines.stroke(1f); - Drawf.circles(x, y, (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent); - - for(Tile shooter : waitingShooters){ - Drawf.circles(shooter.drawx(), shooter.drawy(), (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place); - Drawf.arrow(shooter.drawx(), shooter.drawy(), x, y, size * tilesize + sin, 4f + sin, Pal.place); - } - - if(linkValid(tile)){ - Tile target = world.tile(link); - Drawf.circles(target.drawx(), target.drawy(), (target.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place); - Drawf.arrow(x, y, target.drawx(), target.drawy(), size * tilesize + sin, 4f + sin); - } - - Drawf.dashCircle(x, y, range, Pal.accent); - } - - @Override - public boolean onConfigureTileTapped(Tile other){ - if(tile == other) return false; - - if(link == other.pos()){ - tile.configure(-1); - return false; - }else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.team() == team){ - tile.configure(other.pos()); - return false; - } - - return true; - } - - @Override - public boolean acceptItem(Tilec source, Item item){ - //mass drivers that ouput only cannot accept items - return tile.items.total() < itemCapacity && linkValid(tile); - } - - protected void fire(Tile target){ - MassDriverEntity other = target.ent(); - - //reset reload, use power. - reload = 1f; - - DriverBulletData data = Pools.obtain(DriverBulletData.class, DriverBulletData::new); - data.from = entity; - data.to = other; - int totalUsed = 0; - for(int i = 0; i < content.items().size; i++){ - int maxTransfer = Math.min(items.get(content.item(i)), ((MassDriver)tile.block()).itemCapacity - totalUsed); - data.items[i] = maxTransfer; - totalUsed += maxTransfer; - items.remove(content.item(i), maxTransfer); - } - - float angle = tile.angleTo(target); - - Bullets.driverBolt.create(entity, team(), - x + Angles.trnsx(angle, translation), y + Angles.trnsy(angle, translation), - angle, -1f, 1f, 1f, data); - - shootEffect.at(x + Angles.trnsx(angle, translation), - y + Angles.trnsy(angle, translation), angle); - - smokeEffect.at(x + Angles.trnsx(angle, translation), - y + Angles.trnsy(angle, translation), angle); - - Effects.shake(shake, shake, entity); - } - - protected void handlePayload(MassDriverEntity entity, Bulletc bullet, DriverBulletData data){ - int totalItems = items.total(); - - //add all the items possible - for(int i = 0; i < data.items.length; i++){ - int maxAdd = Math.min(data.items[i], itemCapacity * 2 - totalItems); - items.add(content.item(i), maxAdd); - data.items[i] -= maxAdd; - totalItems += maxAdd; - - if(totalItems >= itemCapacity * 2){ - break; - } - } - - Effects.shake(shake, shake, entity); - recieveEffect.at(bullet); - - reload = 1f; - bullet.remove(); - } - - protected boolean shooterValid(Tile other){ - - if(other == null) return true; - if(!(other.block() instanceof MassDriver)) return false; - MassDriverEntity entity = other.ent(); - return link == tile.pos() && tile.dst(other) <= range; - } - - protected boolean linkValid(){ - if(tile == null) return false; - if(entity == null || link == -1) return false; - Tile link = world.tile(link); - - return link != null && link.block() instanceof MassDriver && link.team() == team && tile.dst(link) <= range; - } - public class DriverBulletData implements Poolable{ public MassDriverEntity from, to; public int[] items = new int[content.items().size]; @@ -309,8 +102,209 @@ public class MassDriver extends Block{ return waitingShooters.isEmpty() ? null : waitingShooters.first(); } + @Override + public void updateTile(){ + Tilec link = world.ent(this.link); + boolean hasLink = linkValid(); + + //reload regardless of state + if(reload > 0f){ + reload = Mathf.clamp(reload - delta() / reloadTime * efficiency()); + } + + //cleanup waiting shooters that are not valid + if(!shooterValid(currentShooter())){ + waitingShooters.remove(currentShooter()); + } + + //switch states + if(state == DriverState.idle){ + //start accepting when idle and there's space + if(!waitingShooters.isEmpty() && (itemCapacity - items.total() >= minDistribute)){ + state = DriverState.accepting; + }else if(hasLink){ //switch to shooting if there's a valid link. + state = DriverState.shooting; + } + } + + //dump when idle or accepting + if(state == DriverState.idle || state == DriverState.accepting){ + dump(); + } + + //skip when there's no power + if(!consValid()){ + return; + } + + if(state == DriverState.accepting){ + //if there's nothing shooting at this, bail - OR, items full + if(currentShooter() == null || (itemCapacity - items.total() < minDistribute)){ + state = DriverState.idle; + return; + } + + //align to shooter rotation + rotation = Mathf.slerpDelta(rotation, tile.angleTo(currentShooter()), rotateSpeed * efficiency()); + }else if(state == DriverState.shooting){ + //if there's nothing to shoot at OR someone wants to shoot at this thing, bail + if(!hasLink || (!waitingShooters.isEmpty() && (itemCapacity - items.total() >= minDistribute))){ + state = DriverState.idle; + return; + } + + float targetRotation = tile.angleTo(link); + + if( + items.total() >= minDistribute && //must shoot minimum amount of items + link.block().itemCapacity - link.items().total() >= minDistribute //must have minimum amount of space + ){ + MassDriverEntity other = (MassDriverEntity)link; + other.waitingShooters.add(tile); + + if(reload <= 0.0001f){ + + //align to target location + rotation = Mathf.slerpDelta(rotation, targetRotation, rotateSpeed * efficiency()); + + //fire when it's the first in the queue and angles are ready. + if(other.currentShooter() == tile && + other.state == DriverState.accepting && + Angles.near(rotation, targetRotation, 2f) && Angles.near(other.rotation, targetRotation + 180f, 2f)){ + //actually fire + fire(other); + //remove waiting shooters, it's done firing + other.waitingShooters.remove(tile); + //set both states to idle + state = DriverState.idle; + other.state = DriverState.idle; + } + } + } + } + } + + @Override + public void draw(){ + Draw.rect(baseRegion, x, y); + } + + @Override + public void drawLayer(){ + Draw.rect(region, + x + Angles.trnsx(rotation + 180f, reload * knockback), + y + Angles.trnsy(rotation + 180f, reload * knockback), rotation - 90); + } + + @Override + public void drawConfigure(){ + float sin = Mathf.absin(Time.time(), 6f, 1f); + + Draw.color(Pal.accent); + Lines.stroke(1f); + Drawf.circles(x, y, (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent); + + for(Tile shooter : waitingShooters){ + Drawf.circles(shooter.drawx(), shooter.drawy(), (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place); + Drawf.arrow(shooter.drawx(), shooter.drawy(), x, y, size * tilesize + sin, 4f + sin, Pal.place); + } + + if(linkValid()){ + Tile target = world.tile(link); + Drawf.circles(target.drawx(), target.drawy(), (target.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place); + Drawf.arrow(x, y, target.drawx(), target.drawy(), size * tilesize + sin, 4f + sin); + } + + Drawf.dashCircle(x, y, range, Pal.accent); + } + + @Override + public boolean onConfigureTileTapped(Tilec other){ + if(this == other) return false; + + if(link == other.pos()){ + tile.configure(-1); + return false; + }else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.team() == team){ + tile.configure(other.pos()); + return false; + } + + return true; + } + + @Override + public boolean acceptItem(Tilec source, Item item){ + //mass drivers that ouput only cannot accept items + return items.total() < itemCapacity && linkValid(); + } + + protected void fire(MassDriverEntity target){ + //reset reload, use power. + reload = 1f; + + DriverBulletData data = Pools.obtain(DriverBulletData.class, DriverBulletData::new); + data.from = this; + data.to = target; + int totalUsed = 0; + for(int i = 0; i < content.items().size; i++){ + int maxTransfer = Math.min(items.get(content.item(i)), ((MassDriver)tile.block()).itemCapacity - totalUsed); + data.items[i] = maxTransfer; + totalUsed += maxTransfer; + items.remove(content.item(i), maxTransfer); + } + + float angle = tile.angleTo(target); + + Bullets.driverBolt.create(this, team(), + x + Angles.trnsx(angle, translation), y + Angles.trnsy(angle, translation), + angle, -1f, 1f, 1f, data); + + shootEffect.at(x + Angles.trnsx(angle, translation), + y + Angles.trnsy(angle, translation), angle); + + smokeEffect.at(x + Angles.trnsx(angle, translation), + y + Angles.trnsy(angle, translation), angle); + + Effects.shake(shake, shake, this); + } + public void handlePayload(Bulletc bullet, DriverBulletData data){ - ((MassDriver)block()).handlePayload(this, bullet, data); + int totalItems = items.total(); + + //add all the items possible + for(int i = 0; i < data.items.length; i++){ + int maxAdd = Math.min(data.items[i], itemCapacity * 2 - totalItems); + items.add(content.item(i), maxAdd); + data.items[i] -= maxAdd; + totalItems += maxAdd; + + if(totalItems >= itemCapacity * 2){ + break; + } + } + + Effects.shake(shake, shake, this); + recieveEffect.at(bullet); + + reload = 1f; + bullet.remove(); + } + + protected boolean shooterValid(Tile other){ + + if(other == null) return true; + if(!(other.block() instanceof MassDriver)) return false; + MassDriverEntity entity = other.ent(); + return link == tile.pos() && tile.dst(other) <= range; + } + + protected boolean linkValid(){ + if(tile == null) return false; + if(link == -1) return false; + Tilec link = world.ent(this.link); + + return link != null && link.block() instanceof MassDriver && link.team() == team && tile.dst(link) <= range; } @Override diff --git a/core/src/mindustry/world/blocks/liquid/ArmoredConduit.java b/core/src/mindustry/world/blocks/liquid/ArmoredConduit.java index 7c3e460292..65c47b4766 100644 --- a/core/src/mindustry/world/blocks/liquid/ArmoredConduit.java +++ b/core/src/mindustry/world/blocks/liquid/ArmoredConduit.java @@ -21,8 +21,8 @@ public class ArmoredConduit extends Conduit{ } @Override - public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){ - return otherblock.outputsLiquid && blendsArmored(rotation, otherx, othery, otherrot, otherblock); + public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ + return otherblock.outputsLiquid && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock); } public class ArmoredConduitEntity extends TileEntity{ diff --git a/core/src/mindustry/world/blocks/liquid/Conduit.java b/core/src/mindustry/world/blocks/liquid/Conduit.java index 203fc05f91..db82b8cbd6 100644 --- a/core/src/mindustry/world/blocks/liquid/Conduit.java +++ b/core/src/mindustry/world/blocks/liquid/Conduit.java @@ -74,8 +74,8 @@ public class Conduit extends LiquidBlock implements Autotiler{ } @Override - public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){ - return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(rotation, otherx, othery, otherrot, otherblock); + public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){ + return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock); } @Override @@ -106,7 +106,7 @@ public class Conduit extends LiquidBlock implements Autotiler{ public void onProximityUpdate(){ super.onProximityUpdate(); - blendbits = buildBlending(rotation(), null, true)[0]; + blendbits = buildBlending(tile, rotation(), null, true)[0]; } @Override diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 29bec1c63d..1d394fe54e 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -128,10 +128,10 @@ public class PowerNode extends PowerBlock{ Drawf.circles(x * tilesize + offset(), y * tilesize + offset(), laserRange * tilesize); getPotentialLinks(tile, other -> { - Drawf.square(other.drawx(), other.drawy(), other.block().size * tilesize / 2f + 2f, Pal.place); + Drawf.square(other.x(), other.y(), other.block().size * tilesize / 2f + 2f, Pal.place); - insulators(tile.x, tile.y, other.x, other.y, cause -> { - Drawf.square(cause.drawx(), cause.drawy(), cause.block().size * tilesize / 2f + 2f, Pal.plastanium); + insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> { + Drawf.square(cause.x(), cause.y(), cause.block().size * tilesize / 2f + 2f, Pal.plastanium); }); }); @@ -165,6 +165,10 @@ public class PowerNode extends PowerBlock{ return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), other.getHitbox(Tmp.r1)); } + protected boolean overlaps(Tilec src, Tilec other, float range){ + return overlaps(src.x(), src.y(), other.tile(), range); + } + protected boolean overlaps(Tile src, Tile other, float range){ return overlaps(src.drawx(), src.drawy(), other, range); } @@ -177,26 +181,26 @@ public class PowerNode extends PowerBlock{ protected void getPotentialLinks(Tile tile, Cons others){ Boolf valid = other -> other != null && other.tile() != tile && other.power() != null && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && - overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.team() == player.team() - && !other.proximity().contains(tile) && !graphs.contains(other.power().graph); + overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other.tile(), laserRange * tilesize) && other.team() == player.team() + && !other.proximity().contains(e -> e.tile() == tile) && !graphs.contains(other.power().graph); - tempTiles.clear(); + tempTileEnts.clear(); graphs.clear(); Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> { - Tile other = world.ltile(x, y); - if(valid.get(other) && !tempTiles.contains(other)){ - tempTiles.add(other); + Tilec other = world.ent(x, y); + if(valid.get(other) && !tempTileEnts.contains(other)){ + tempTileEnts.add(other); } }); - tempTiles.sort((a, b) -> { + tempTileEnts.sort((a, b) -> { int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode); if(type != 0) return type; return Float.compare(a.dst2(tile), b.dst2(tile)); }); - tempTiles.each(valid, t -> { - graphs.add(t.power.graph); + tempTileEnts.each(valid, t -> { + graphs.add(t.power().graph); others.get(t); }); } @@ -219,6 +223,26 @@ public class PowerNode extends PowerBlock{ } } + public boolean linkValid(Tilec tile, Tilec link){ + return linkValid(tile, link, true); + } + + public boolean linkValid(Tilec tile, Tilec link, boolean checkMaxNodes){ + if(tile == link || link == null || !link.block().hasPower || tile.team() != link.team()) return false; + + if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, ((PowerNode)link.block()).laserRange * tilesize))){ + if(checkMaxNodes && link.block() instanceof PowerNode){ + return link.power().links.size < ((PowerNode)link.block()).maxNodes || link.power().links.contains(tile.pos()); + } + return true; + } + return false; + } + + public static boolean insulated(Tile tile, Tile other){ + return insulated(tile.x, tile.y, other.x, other.y); + } + public static boolean insulated(Tilec tile, Tilec other){ return insulated(tile.tileX(), tile.tileY(), other.tileX(), other.tileY()); } @@ -251,23 +275,23 @@ public class PowerNode extends PowerBlock{ (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(this, other) && !other.proximity().contains(this) && other.power().graph != power.graph; - tempTiles.clear(); + tempTileEnts.clear(); Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> { - Tile other = world.ltile(x, y); + Tilec other = world.ent(x, y); if(valid.get(other)){ - if(!insulated(tile, other)){ - tempTiles.add(other); + if(!insulated(this, other)){ + tempTileEnts.add(other); } } }); - tempTiles.sort((a, b) -> { + tempTileEnts.sort((a, b) -> { int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode); if(type != 0) return type; return Float.compare(a.dst2(tile), b.dst2(tile)); }); - tempTiles.each(valid, other -> { - if(!tile.power.links.contains(other.pos())){ + tempTileEnts.each(valid, other -> { + if(!power.links.contains(other.pos())){ tile.configureAny(other.pos()); } }); @@ -277,24 +301,21 @@ public class PowerNode extends PowerBlock{ @Override public void updateTile(){ - tile.power.graph.update(); + power.graph.update(); } @Override - public boolean onConfigureTileTapped(Tile other){ - Tilec entity = tile.ent(); - other = other.link(); - - if(linkValid(tile, other)){ + public boolean onConfigureTileTapped(Tilec other){ + if(linkValid(this, other)){ tile.configure(other.pos()); return false; } - if(tile == other){ - if(other.power.links.size == 0){ + if(this == other){ + if(other.power().links.size == 0){ int[] total = {0}; getPotentialLinks(tile, link -> { - if(!insulated(tile, link) && total[0]++ < maxNodes){ + if(!insulated(this, link) && total[0]++ < maxNodes){ tile.configure(link.pos()); } }); @@ -335,13 +356,13 @@ public class PowerNode extends PowerBlock{ for(int x = (int)(tile.x - laserRange - 2); x <= tile.x + laserRange + 2; x++){ for(int y = (int)(tile.y - laserRange - 2); y <= tile.y + laserRange + 2; y++){ - Tile link = world.ltile(x, y); + Tilec link = world.ent(x, y); - if(link != tile && linkValid(tile, link, false)){ - boolean linked = linked(tile, link); + if(link != this && linkValid(this, link, false)){ + boolean linked = linked(link); if(linked){ - Drawf.square(link.drawx(), link.drawy(), link.block().size * tilesize / 2f + 1f, Pal.place); + Drawf.square(link.x(), link.y(), link.block().size * tilesize / 2f + 1f, Pal.place); } } } @@ -357,40 +378,24 @@ public class PowerNode extends PowerBlock{ Tilec entity = tile.ent(); for(int i = 0; i < power.links.size; i++){ - Tile link = world.tile(power.links.get(i)); + Tilec link = world.ent(power.links.get(i)); - if(!linkValid(tile, link)) continue; + if(!linkValid(this, link)) continue; if(link.block() instanceof PowerNode && !(link.pos() < tile.pos())) continue; - drawLaser(tile, link); + drawLaserTo(link); } Draw.reset(); } - protected boolean linked(Tile other){ - return tile.power.links.contains(other.pos()); + protected boolean linked(Tilec other){ + return power.links.contains(other.pos()); } - public boolean linkValid(Tilec tile, Tilec link){ - return linkValid(tile, link, true); - } - - public boolean linkValid(Tilec tile, Tilec link, boolean checkMaxNodes){ - if(tile == link || link == null || !link.block().hasPower || team != link.team()) return false; - - if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, link.cblock().laserRange * tilesize))){ - if(checkMaxNodes && link.block() instanceof PowerNode){ - return link.power.links.size < link.cblock().maxNodes || link.power.links.contains(tile.pos()); - } - return true; - } - return false; - } - - protected void drawLaser(Tile target){ - drawLaser(x, y, target.drawx(), target.drawy(), power.graph.getSatisfaction(), size, target.block().size); + protected void drawLaserTo(Tilec target){ + drawLaser(x, y, target.x(), target.y(), power.graph.getSatisfaction(), size, target.block().size); } @Override diff --git a/core/src/mindustry/world/blocks/production/Cultivator.java b/core/src/mindustry/world/blocks/production/Cultivator.java index d49659d41a..61dc368784 100644 --- a/core/src/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/mindustry/world/blocks/production/Cultivator.java @@ -7,14 +7,10 @@ import arc.math.*; import arc.util.*; import arc.util.io.*; import mindustry.content.*; -import mindustry.gen.*; import mindustry.graphics.*; import mindustry.ui.*; -import mindustry.world.*; import mindustry.world.meta.*; -import java.io.*; - public class Cultivator extends GenericCrafter{ public Color plantColor = Color.valueOf("5541b1"); public Color plantColorLight = Color.valueOf("7457ce"); @@ -38,13 +34,6 @@ public class Cultivator extends GenericCrafter{ topRegion = Core.atlas.find(name + "-top"); } - @Override - public void updateTile(){ - super.updateTile(); - - warmup = Mathf.lerpDelta(warmup, consValid() ? 1f : 0f, 0.015f); - } - @Override public void setBars(){ super.setBars(); @@ -67,54 +56,60 @@ public class Cultivator extends GenericCrafter{ drawPlaceText(Core.bundle.formatFloat("bar.efficiency", (1 + sumAttribute(attribute, x, y)) * 100, 1), x, y, valid); } - @Override - public void draw(){ - Draw.rect(region, x, y); - - Draw.color(plantColor); - Draw.alpha(warmup); - Draw.rect(middleRegion, x, y); - - Draw.color(bottomColor, plantColorLight, warmup); - - random.setSeed(tile.pos()); - for(int i = 0; i < 12; i++){ - float offset = random.nextFloat() * 999999f; - float x = random.range(4f), y = random.range(4f); - float life = 1f - (((Time.time() + offset) / 50f) % recurrence); - - if(life > 0){ - Lines.stroke(warmup * (life * 1f + 0.2f)); - Lines.poly(x + x, y + y, 8, (1f - life) * 3f); - } - } - - Draw.color(); - Draw.rect(topRegion, x, y); - } - @Override public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top"),}; } - @Override - public void onProximityAdded(){ - super.onProximityAdded(); - - boost = sumAttribute(attribute, tile.x, tile.y); - } - - @Override - protected float getProgressIncrease(Tilec entity, float baseTime){ - CultivatorEntity c = (CultivatorEntity)entity; - return super.getProgressIncrease(entity, baseTime) * (1f + c.boost); - } - public class CultivatorEntity extends GenericCrafterEntity{ public float warmup; public float boost; + @Override + public void updateTile(){ + super.updateTile(); + + warmup = Mathf.lerpDelta(warmup, consValid() ? 1f : 0f, 0.015f); + } + + @Override + public void draw(){ + Draw.rect(region, x, y); + + Draw.color(plantColor); + Draw.alpha(warmup); + Draw.rect(middleRegion, x, y); + + Draw.color(bottomColor, plantColorLight, warmup); + + random.setSeed(tile.pos()); + for(int i = 0; i < 12; i++){ + float offset = random.nextFloat() * 999999f; + float x = random.range(4f), y = random.range(4f); + float life = 1f - (((Time.time() + offset) / 50f) % recurrence); + + if(life > 0){ + Lines.stroke(warmup * (life * 1f + 0.2f)); + Lines.poly(x + x, y + y, 8, (1f - life) * 3f); + } + } + + Draw.color(); + Draw.rect(topRegion, x, y); + } + + @Override + public void onProximityUpdate(){ + super.onProximityAdded(); + + boost = sumAttribute(attribute, tile.x, tile.y); + } + + @Override + public float getProgressIncrease(float baseTime){ + return super.getProgressIncrease(baseTime) * (1f + boost); + } + @Override public void write(Writes write){ super.write(write); diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index 57e6eaa0c4..e43b10be03 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -1,10 +1,10 @@ package mindustry.world.blocks.production; import arc.*; -import arc.struct.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; +import arc.struct.*; import arc.util.*; import mindustry.content.*; import mindustry.entities.*; @@ -62,7 +62,7 @@ public class Drill extends Block{ hasLiquids = true; liquidCapacity = 5f; hasItems = true; - idleSound = Sounds.drill; + idleSound = Sounds.drill; idleSoundVolume = 0.003f; } @@ -73,7 +73,7 @@ public class Drill extends Block{ bars.add("drillspeed", e -> { DrillEntity entity = (DrillEntity)e; - return new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(lastDrillSpeed * 60 * timeScale(), 2)), () -> Pal.ammo, () -> warmup); + return new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(entity.lastDrillSpeed * 60 * entity.timeScale(), 2)), () -> Pal.ammo, () -> entity.warmup); }); } @@ -85,50 +85,22 @@ public class Drill extends Block{ topRegion = Core.atlas.find(name + "-top"); } - @Override - public void drawCracks(){} + public Item getDrop(Tile tile){ + return tile.drop(); + } @Override - public void draw(){ - float s = 0.3f; - float ts = 0.6f; - - Draw.rect(region, x, y); - super.drawCracks(); - - if(drawRim){ - Draw.color(heatColor); - Draw.alpha(warmup * ts * (1f - s + Mathf.absin(Time.time(), 3f, s))); - Draw.blend(Blending.additive); - Draw.rect(rimRegion, x, y); - Draw.blend(); - Draw.color(); + public boolean canPlaceOn(Tile tile){ + if(isMultiblock()){ + for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ + if(canMine(other)){ + return true; + } + } + return false; + }else{ + return canMine(tile); } - - Draw.rect(rotatorRegion, x, y, drillTime * rotateSpeed); - - Draw.rect(topRegion, x, y); - - if(dominantItem != null && drawMineItem){ - Draw.color(dominantItem.color); - Draw.rect("drill-top", x, y, 1f); - Draw.color(); - } - } - - @Override - public TextureRegion[] generateIcons(){ - return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; - } - - @Override - public boolean shouldConsume(){ - return tile.items.total() < itemCapacity; - } - - @Override - public boolean shouldIdleSound(){ - return tile.efficiency() > 0.01f; } @Override @@ -154,17 +126,6 @@ public class Drill extends Block{ } } - @Override - public void drawSelect(){ - if(dominantItem != null){ - float dx = x - size * tilesize/2f, dy = y + size * tilesize/2f; - Draw.mixcol(Color.darkGray, 1f); - Draw.rect(dominantItem.icon(Cicon.small), dx, dy - 1); - Draw.reset(); - Draw.rect(dominantItem.icon(Cicon.small), dx, dy); - } - } - @Override public void setStats(){ super.setStats(); @@ -195,7 +156,12 @@ public class Drill extends Block{ } } - void countOre(){ + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; + } + + void countOre(Tile tile){ returnItem = null; returnCount = 0; @@ -203,7 +169,7 @@ public class Drill extends Block{ itemArray.clear(); for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ - if(isValid(other)){ + if(canMine(other)){ oreCount.getAndIncrement(getDrop(other), 0, 1); } } @@ -228,84 +194,7 @@ public class Drill extends Block{ returnCount = oreCount.get(itemArray.peek(), 0); } - @Override - public void onProximityUpdate(){ - countOre(tile); - dominantItem = returnItem; - dominantItems = returnCount; - } - - @Override - public void updateTile(){ - if(dominantItem == null){ - return; - } - - if(timer(timerDump, dumpTime)){ - tryDump(tile, dominantItem); - } - - drillTime += warmup * delta(); - - if(items.total() < itemCapacity && dominantItems > 0 && consValid()){ - - float speed = 1f; - - if(cons().optionalValid()){ - speed = liquidBoostIntensity; - } - - speed *= efficiency(); // Drill slower when not at full power - - lastDrillSpeed = (speed * dominantItems * warmup) / (drillTime + hardnessDrillMultiplier * dominantItem.hardness); - warmup = Mathf.lerpDelta(warmup, speed, warmupSpeed); - progress += delta() - * dominantItems * speed * warmup; - - if(Mathf.chance(Time.delta() * updateEffectChance * warmup)) - updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f)); - }else{ - lastDrillSpeed = 0f; - warmup = Mathf.lerpDelta(warmup, 0f, warmupSpeed); - return; - } - - if(dominantItems > 0 && progress >= drillTime + hardnessDrillMultiplier * dominantItem.hardness && tile.items.total() < itemCapacity){ - - offloadNear(tile, dominantItem); - - useContent(tile, dominantItem); - - index++; - progress = 0f; - - drillEffect.at(getX() + Mathf.range(size), getY() + Mathf.range(size), dominantItem.color); - } - } - - @Override - public boolean canPlaceOn(){ - if(isMultiblock()){ - for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ - if(isValid(other)){ - return true; - } - } - return false; - }else{ - return isValid(tile); - } - } - - public int tier(){ - return tier; - } - - public Item getDrop(){ - return tile.drop(); - } - - public boolean isValid(){ + public boolean canMine(Tile tile){ if(tile == null) return false; Item drops = tile.drop(); return drops != null && drops.hardness <= tier; @@ -320,6 +209,112 @@ public class Drill extends Block{ int dominantItems; Item dominantItem; + + + @Override + public boolean shouldConsume(){ + return items.total() < itemCapacity; + } + + @Override + public boolean shouldIdleSound(){ + return efficiency() > 0.01f; + } + + @Override + public void drawSelect(){ + if(dominantItem != null){ + float dx = x - size * tilesize/2f, dy = y + size * tilesize/2f; + Draw.mixcol(Color.darkGray, 1f); + Draw.rect(dominantItem.icon(Cicon.small), dx, dy - 1); + Draw.reset(); + Draw.rect(dominantItem.icon(Cicon.small), dx, dy); + } + } + + @Override + public void onProximityUpdate(){ + countOre(tile); + dominantItem = returnItem; + dominantItems = returnCount; + } + + @Override + public void updateTile(){ + if(dominantItem == null){ + return; + } + + if(timer(timerDump, dumpTime)){ + dump(dominantItem); + } + + drillTime += warmup * delta(); + + if(items.total() < itemCapacity && dominantItems > 0 && consValid()){ + + float speed = 1f; + + if(cons().optionalValid()){ + speed = liquidBoostIntensity; + } + + speed *= efficiency(); // Drill slower when not at full power + + lastDrillSpeed = (speed * dominantItems * warmup) / (drillTime + hardnessDrillMultiplier * dominantItem.hardness); + warmup = Mathf.lerpDelta(warmup, speed, warmupSpeed); + progress += delta() + * dominantItems * speed * warmup; + + if(Mathf.chance(Time.delta() * updateEffectChance * warmup)) + updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f)); + }else{ + lastDrillSpeed = 0f; + warmup = Mathf.lerpDelta(warmup, 0f, warmupSpeed); + return; + } + + if(dominantItems > 0 && progress >= drillTime + hardnessDrillMultiplier * dominantItem.hardness && items.total() < itemCapacity){ + offloadNear(dominantItem); + useContent(dominantItem); + + index++; + progress = 0f; + + drillEffect.at(getX() + Mathf.range(size), getY() + Mathf.range(size), dominantItem.color); + } + } + + @Override + public void drawCracks(){} + + @Override + public void draw(){ + float s = 0.3f; + float ts = 0.6f; + + Draw.rect(region, x, y); + super.drawCracks(); + + if(drawRim){ + Draw.color(heatColor); + Draw.alpha(warmup * ts * (1f - s + Mathf.absin(Time.time(), 3f, s))); + Draw.blend(Blending.additive); + Draw.rect(rimRegion, x, y); + Draw.blend(); + Draw.color(); + } + + Draw.rect(rotatorRegion, x, y, drillTime * rotateSpeed); + + Draw.rect(topRegion, x, y); + + if(dominantItem != null && drawMineItem){ + Draw.color(dominantItem.color); + Draw.rect("drill-top", x, y, 1f); + Draw.color(); + } + } } } diff --git a/core/src/mindustry/world/blocks/production/Fracker.java b/core/src/mindustry/world/blocks/production/Fracker.java index b028d29a9a..e476f0e06f 100644 --- a/core/src/mindustry/world/blocks/production/Fracker.java +++ b/core/src/mindustry/world/blocks/production/Fracker.java @@ -2,7 +2,6 @@ package mindustry.world.blocks.production; import arc.*; import arc.graphics.g2d.*; -import mindustry.world.*; import mindustry.world.meta.*; public class Fracker extends SolidPump{ @@ -38,54 +37,54 @@ public class Fracker extends SolidPump{ return false; } - @Override - public void drawCracks(){} - - @Override - public boolean shouldConsume(){ - return tile.liquids.get(result) < liquidCapacity - 0.01f; - } - - @Override - public void draw(){ - Draw.rect(region, x, y); - super.drawCracks(); - - Draw.color(result.color); - Draw.alpha(tile.liquids.get(result) / liquidCapacity); - Draw.rect(liquidRegion, x, y); - Draw.color(); - - Draw.rect(rotatorRegion, x, y, pumpTime); - Draw.rect(topRegion, x, y); - } - @Override public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; } - @Override - public void updateTile(){ - if(consValid()){ - if(accumulator >= itemUseTime){ - consume(); - accumulator -= itemUseTime; - } - - super.updateTile(); - accumulator += delta() * efficiency(); - }else{ - tryDumpLiquid(tile, result); - } - } - - @Override - public float typeLiquid(){ - return tile.liquids.get(result); - } - public class FrackerEntity extends SolidPumpEntity{ public float accumulator; + + @Override + public void drawCracks(){} + + @Override + public boolean shouldConsume(){ + return liquids.get(result) < liquidCapacity - 0.01f; + } + + @Override + public void draw(){ + Draw.rect(region, x, y); + super.drawCracks(); + + Draw.color(result.color); + Draw.alpha(liquids.get(result) / liquidCapacity); + Draw.rect(liquidRegion, x, y); + Draw.color(); + + Draw.rect(rotatorRegion, x, y, pumpTime); + Draw.rect(topRegion, x, y); + } + + @Override + public void updateTile(){ + if(consValid()){ + if(accumulator >= itemUseTime){ + consume(); + accumulator -= itemUseTime; + } + + super.updateTile(); + accumulator += delta() * efficiency(); + }else{ + dumpLiquid(result); + } + } + + @Override + public float typeLiquid(){ + return liquids.get(result); + } } } diff --git a/core/src/mindustry/world/blocks/production/GenericCrafter.java b/core/src/mindustry/world/blocks/production/GenericCrafter.java index b89f3fd47c..7915a32792 100644 --- a/core/src/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/mindustry/world/blocks/production/GenericCrafter.java @@ -55,97 +55,97 @@ public class GenericCrafter extends Block{ } } - @Override - public boolean shouldIdleSound(Tilec tile){ - return tile.cons().valid(); - } - @Override public void init(){ outputsLiquid = outputLiquid != null; super.init(); } - @Override - public void draw(){ - if(drawer == null){ - super.draw(); - }else{ - drawer.get(tile); - } - } - @Override public TextureRegion[] generateIcons(){ return drawIcons == null ? super.generateIcons() : drawIcons.get(); } - @Override - public void updateTile(){ - if(consValid()){ - - progress += getProgressIncrease(entity, craftTime); - totalProgress += delta(); - warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); - - if(Mathf.chance(Time.delta() * updateEffectChance)){ - updateEffect.at(getX() + Mathf.range(size * 4f), getY() + Mathf.range(size * 4)); - } - }else{ - warmup = Mathf.lerp(warmup, 0f, 0.02f); - } - - if(progress >= 1f){ - consume(); - - if(outputItem != null){ - useContent(tile, outputItem.item); - for(int i = 0; i < outputItem.amount; i++){ - offloadNear(tile, outputItem.item); - } - } - - if(outputLiquid != null){ - useContent(tile, outputLiquid.liquid); - handleLiquid(tile, tile, outputLiquid.liquid, outputLiquid.amount); - } - - craftEffect.at(x, y); - progress = 0f; - } - - if(outputItem != null && timer(timerDump, dumpTime)){ - tryDump(tile, outputItem.item); - } - - if(outputLiquid != null){ - tryDumpLiquid(tile, outputLiquid.liquid); - } - } - @Override public boolean outputsItems(){ return outputItem != null; } - @Override - public boolean shouldConsume(){ - if(outputItem != null && tile.items.get(outputItem.item) >= itemCapacity){ - return false; - } - return outputLiquid == null || !(tile.liquids.get(outputLiquid.liquid) >= liquidCapacity - 0.001f); - } - - @Override - public int getMaximumAccepted(Item item){ - return itemCapacity; - } - public class GenericCrafterEntity extends TileEntity{ public float progress; public float totalProgress; public float warmup; + @Override + public void draw(){ + if(drawer == null){ + super.draw(); + }else{ + drawer.get(this); + } + } + + @Override + public boolean shouldConsume(){ + if(outputItem != null && items.get(outputItem.item) >= itemCapacity){ + return false; + } + return outputLiquid == null || !(liquids.get(outputLiquid.liquid) >= liquidCapacity - 0.001f); + } + + @Override + public void updateTile(){ + if(consValid()){ + + progress += getProgressIncrease(craftTime); + totalProgress += delta(); + warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); + + if(Mathf.chance(Time.delta() * updateEffectChance)){ + updateEffect.at(getX() + Mathf.range(size * 4f), getY() + Mathf.range(size * 4)); + } + }else{ + warmup = Mathf.lerp(warmup, 0f, 0.02f); + } + + if(progress >= 1f){ + consume(); + + if(outputItem != null){ + useContent(outputItem.item); + for(int i = 0; i < outputItem.amount; i++){ + offloadNear(outputItem.item); + } + } + + if(outputLiquid != null){ + useContent(outputLiquid.liquid); + handleLiquid(this, outputLiquid.liquid, outputLiquid.amount); + } + + craftEffect.at(x, y); + progress = 0f; + } + + if(outputItem != null && timer(timerDump, dumpTime)){ + dump(outputItem.item); + } + + if(outputLiquid != null){ + dumpLiquid(outputLiquid.liquid); + } + } + + @Override + public int getMaximumAccepted(Item item){ + return itemCapacity; + } + + @Override + public boolean shouldIdleSound(){ + return cons.valid(); + } + @Override public void write(Writes write){ super.write(write); diff --git a/core/src/mindustry/world/blocks/production/GenericSmelter.java b/core/src/mindustry/world/blocks/production/GenericSmelter.java index f80cb0b29e..f09882146b 100644 --- a/core/src/mindustry/world/blocks/production/GenericSmelter.java +++ b/core/src/mindustry/world/blocks/production/GenericSmelter.java @@ -5,7 +5,6 @@ import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; import arc.util.*; -import mindustry.world.*; import static mindustry.Vars.renderer; @@ -24,30 +23,32 @@ public class GenericSmelter extends GenericCrafter{ topRegion = Core.atlas.find(name + "-top"); } - @Override - public void draw(){ - super.draw(); + public class SmelterEntity extends GenericCrafterEntity{ + @Override + public void draw(){ + super.draw(); - //draw glowing center - if(warmup > 0f && flameColor.a > 0.001f){ - float g = 0.3f; - float r = 0.06f; - float cr = Mathf.random(0.1f); + //draw glowing center + if(warmup > 0f && flameColor.a > 0.001f){ + float g = 0.3f; + float r = 0.06f; + float cr = Mathf.random(0.1f); - Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * warmup); + Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * warmup); - Draw.tint(flameColor); - Fill.circle(x, y, 3f + Mathf.absin(Time.time(), 5f, 2f) + cr); - Draw.color(1f, 1f, 1f, warmup); - Draw.rect(topRegion, x, y); - Fill.circle(x, y, 1.9f + Mathf.absin(Time.time(), 5f, 1f) + cr); + Draw.tint(flameColor); + Fill.circle(x, y, 3f + Mathf.absin(Time.time(), 5f, 2f) + cr); + Draw.color(1f, 1f, 1f, warmup); + Draw.rect(topRegion, x, y); + Fill.circle(x, y, 1.9f + Mathf.absin(Time.time(), 5f, 1f) + cr); - Draw.color(); + Draw.color(); + } + } + + @Override + public void drawLight(){ + renderer.lights.add(x, y, (60f + Mathf.absin(10f, 5f)) * warmup * size, flameColor, 0.65f); } } - - @Override - public void drawLight(){ - renderer.lights.add(x, y, (60f + Mathf.absin(10f, 5f)) * warmup * size, flameColor, 0.65f); - } } diff --git a/core/src/mindustry/world/blocks/production/Incinerator.java b/core/src/mindustry/world/blocks/production/Incinerator.java index 45d0f0c1a9..e5db4e17d9 100644 --- a/core/src/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/mindustry/world/blocks/production/Incinerator.java @@ -1,17 +1,14 @@ package mindustry.world.blocks.production; -import arc.graphics.Color; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.Fill; -import arc.math.Mathf; -import arc.util.Time; -import mindustry.content.Fx; +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.util.*; +import mindustry.content.*; import mindustry.entities.*; import mindustry.gen.*; -import mindustry.type.Item; -import mindustry.type.Liquid; -import mindustry.world.Block; -import mindustry.world.Tile; +import mindustry.type.*; +import mindustry.world.*; public class Incinerator extends Block{ public Effect effect = Fx.fuelburn; @@ -25,59 +22,59 @@ public class Incinerator extends Block{ solid = true; } - @Override - public void updateTile(){ - if(consValid()){ - heat = Mathf.lerpDelta(heat, 1f, 0.04f); - }else{ - heat = Mathf.lerpDelta(heat, 0f, 0.02f); - } - } - - @Override - public void draw(){ - super.draw(); - - if(heat > 0f){ - float g = 0.3f; - float r = 0.06f; - - Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * heat); - - Draw.tint(flameColor); - Fill.circle(x, y, 2f); - Draw.color(1f, 1f, 1f, heat); - Fill.circle(x, y, 1f); - - Draw.color(); - } - } - - @Override - public void handleItem(Tilec source, Item item){ - if(Mathf.chance(0.3)){ - effect.at(x, y); - } - } - - @Override - public boolean acceptItem(Tilec source, Item item){ - return heat > 0.5f; - } - - @Override - public void handleLiquid(Tile source, Liquid liquid, float amount){ - if(Mathf.chance(0.02)){ - effect.at(x, y); - } - } - - @Override - public boolean acceptLiquid(Tile source, Liquid liquid, float amount){ - return heat > 0.5f; - } - public class IncineratorEntity extends TileEntity{ public float heat; + + @Override + public void updateTile(){ + if(consValid()){ + heat = Mathf.lerpDelta(heat, 1f, 0.04f); + }else{ + heat = Mathf.lerpDelta(heat, 0f, 0.02f); + } + } + + @Override + public void draw(){ + super.draw(); + + if(heat > 0f){ + float g = 0.3f; + float r = 0.06f; + + Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * heat); + + Draw.tint(flameColor); + Fill.circle(x, y, 2f); + Draw.color(1f, 1f, 1f, heat); + Fill.circle(x, y, 1f); + + Draw.color(); + } + } + + @Override + public void handleItem(Tilec source, Item item){ + if(Mathf.chance(0.3)){ + effect.at(x, y); + } + } + + @Override + public boolean acceptItem(Tilec source, Item item){ + return heat > 0.5f; + } + + @Override + public void handleLiquid(Tilec source, Liquid liquid, float amount){ + if(Mathf.chance(0.02)){ + effect.at(x, y); + } + } + + @Override + public boolean acceptLiquid(Tilec source, Liquid liquid, float amount){ + return heat > 0.5f; + } } } diff --git a/core/src/mindustry/world/blocks/production/LiquidConverter.java b/core/src/mindustry/world/blocks/production/LiquidConverter.java index 522b850e0c..1b63548e62 100644 --- a/core/src/mindustry/world/blocks/production/LiquidConverter.java +++ b/core/src/mindustry/world/blocks/production/LiquidConverter.java @@ -1,9 +1,7 @@ package mindustry.world.blocks.production; -import mindustry.world.Tile; -import mindustry.world.consumers.ConsumeLiquidBase; -import mindustry.world.consumers.ConsumeType; -import mindustry.world.meta.BlockStat; +import mindustry.world.consumers.*; +import mindustry.world.meta.*; public class LiquidConverter extends GenericCrafter{ @@ -32,29 +30,31 @@ public class LiquidConverter extends GenericCrafter{ stats.add(BlockStat.output, outputLiquid.liquid, outputLiquid.amount * craftTime, false); } - @Override - public void drawLight(){ - if(hasLiquids && drawLiquidLight && outputLiquid.liquid.lightColor.a > 0.001f){ - drawLiquidLight(tile, outputLiquid.liquid, tile.liquids.get(outputLiquid.liquid)); - } - } - - @Override - public void updateTile(){ - ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid); - - if(tile.cons().valid()){ - float use = Math.min(cl.amount * delta(), liquidCapacity - liquids.get(outputLiquid.liquid)) * efficiency(); - - useContent(tile, outputLiquid.liquid); - progress += use / cl.amount / craftTime; - liquids.add(outputLiquid.liquid, use); - if(progress >= 1f){ - consume(); - progress = 0f; + public class LiquidConverterEntity extends GenericCrafterEntity{ + @Override + public void drawLight(){ + if(hasLiquids && drawLiquidLight && outputLiquid.liquid.lightColor.a > 0.001f){ + drawLiquidLight(outputLiquid.liquid, liquids.get(outputLiquid.liquid)); } } - tryDumpLiquid(tile, outputLiquid.liquid); + @Override + public void updateTile(){ + ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid); + + if(cons.valid()){ + float use = Math.min(cl.amount * delta(), liquidCapacity - liquids.get(outputLiquid.liquid)) * efficiency(); + + useContent(outputLiquid.liquid); + progress += use / cl.amount / craftTime; + liquids.add(outputLiquid.liquid, use); + if(progress >= 1f){ + consume(); + progress = 0f; + } + } + + dumpLiquid(outputLiquid.liquid); + } } } diff --git a/core/src/mindustry/world/blocks/production/Pump.java b/core/src/mindustry/world/blocks/production/Pump.java index f68724418e..f8a7f0f0f8 100644 --- a/core/src/mindustry/world/blocks/production/Pump.java +++ b/core/src/mindustry/world/blocks/production/Pump.java @@ -1,24 +1,18 @@ package mindustry.world.blocks.production; -import arc.Core; -import arc.struct.Array; -import arc.graphics.Color; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.TextureRegion; -import mindustry.graphics.Layer; -import mindustry.type.Liquid; -import mindustry.ui.Cicon; -import mindustry.world.Tile; -import mindustry.world.blocks.liquid.LiquidBlock; +import arc.*; +import arc.graphics.*; +import arc.graphics.g2d.*; +import mindustry.graphics.*; +import mindustry.type.*; +import mindustry.ui.*; +import mindustry.world.*; +import mindustry.world.blocks.liquid.*; import mindustry.world.meta.*; -import static mindustry.Vars.tilesize; -import static mindustry.Vars.world; +import static mindustry.Vars.*; public class Pump extends LiquidBlock{ - protected final Array drawTiles = new Array<>(); - protected final Array updateTiles = new Array<>(); - public final int timerContentCheck = timers++; /** Pump amount, total. */ @@ -44,16 +38,6 @@ public class Pump extends LiquidBlock{ stats.add(BlockStat.output, 60f * pumpAmount, StatUnit.liquidSecond); } - @Override - public void draw(){ - Draw.rect(name, x, y); - - Draw.color(tile.liquids.current().color); - Draw.alpha(tile.liquids.total() / liquidCapacity); - Draw.rect(liquidRegion, x, y); - Draw.color(); - } - @Override public void drawPlace(int x, int y, int rotation, boolean valid) { Tile tile = world.tile(x, y); @@ -63,7 +47,7 @@ public class Pump extends LiquidBlock{ Liquid liquidDrop = null; for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ - if(isValid(other)){ + if(canPump(other)){ liquidDrop = other.floor().liquidDrop; tiles++; } @@ -85,10 +69,10 @@ public class Pump extends LiquidBlock{ } @Override - public boolean canPlaceOn(){ + public boolean canPlaceOn(Tile tile){ if(isMultiblock()){ Liquid last = null; - for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ + for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ if(other.floor().liquidDrop == null) continue; if(other.floor().liquidDrop != last && last != null) @@ -97,41 +81,54 @@ public class Pump extends LiquidBlock{ } return last != null; }else{ - return isValid(tile); + return canPump(tile); } } - @Override - public void updateTile(){ - float tiles = 0f; - Liquid liquidDrop = null; - - if(isMultiblock()){ - for(Tile other : tile.getLinkedTiles(updateTiles)){ - if(isValid(other)){ - liquidDrop = other.floor().liquidDrop; - tiles++; - } - } - }else{ - tiles = 1f; - liquidDrop = tile.floor().liquidDrop; - } - - if(tile.cons().valid() && liquidDrop != null){ - float maxPump = Math.min(liquidCapacity - tile.liquids.total(), tiles * pumpAmount * tile.delta() / size / size) * tile.efficiency(); - tile.liquids.add(liquidDrop, maxPump); - } - - if(tile.liquids.currentAmount() > 0f && timer(timerContentCheck, 10)){ - useContent(tile, tile.liquids.current()); - } - - tryDumpLiquid(tile, tile.liquids.current()); - } - - protected boolean isValid(){ + protected boolean canPump(Tile tile){ return tile != null && tile.floor().liquidDrop != null; } + public class PumpEntity extends LiquidBlockEntity{ + + @Override + public void draw(){ + Draw.rect(name, x, y); + + Draw.color(liquids.current().color); + Draw.alpha(liquids.total() / liquidCapacity); + Draw.rect(liquidRegion, x, y); + Draw.color(); + } + + @Override + public void updateTile(){ + float tiles = 0f; + Liquid liquidDrop = null; + + if(isMultiblock()){ + for(Tile other : tile.getLinkedTiles(tempTiles)){ + if(canPump(other)){ + liquidDrop = other.floor().liquidDrop; + tiles++; + } + } + }else{ + tiles = 1f; + liquidDrop = tile.floor().liquidDrop; + } + + if(cons.valid() && liquidDrop != null){ + float maxPump = Math.min(liquidCapacity - liquids.total(), tiles * pumpAmount * delta() / size / size) * efficiency(); + liquids.add(liquidDrop, maxPump); + } + + if(liquids.currentAmount() > 0f && timer(timerContentCheck, 10)){ + useContent(liquids.current()); + } + + dumpLiquid(liquids.current()); + } + } + } diff --git a/core/src/mindustry/world/blocks/production/Separator.java b/core/src/mindustry/world/blocks/production/Separator.java index 7891992b88..ad424b2051 100644 --- a/core/src/mindustry/world/blocks/production/Separator.java +++ b/core/src/mindustry/world/blocks/production/Separator.java @@ -4,9 +4,10 @@ import arc.*; import arc.graphics.g2d.*; import arc.math.*; import arc.util.ArcAnnotate.*; +import arc.util.io.*; +import mindustry.gen.*; import mindustry.type.*; import mindustry.world.*; -import mindustry.world.blocks.production.GenericCrafter.*; import mindustry.world.consumers.*; import mindustry.world.meta.*; import mindustry.world.meta.values.*; @@ -51,64 +52,88 @@ public class Separator extends Block{ stats.add(BlockStat.productionTime, craftTime / 60f, StatUnit.seconds); } - @Override - public boolean shouldConsume(){ - return tile.items.total() < itemCapacity; - } + public class SeparatorEntity extends TileEntity{ + public float progress; + public float totalProgress; + public float warmup; - @Override - public void draw(){ - super.draw(); - - Draw.color(tile.liquids.current().color); - Draw.alpha(tile.liquids.total() / liquidCapacity); - Draw.rect(reg(liquidRegion), x, y); - - Draw.reset(); - if(Core.atlas.isFound(reg(spinnerRegion))){ - Draw.rect(reg(spinnerRegion), x, y, totalProgress * spinnerSpeed); - } - } - - @Override - public void updateTile(){ - totalProgress += warmup * delta(); - - if(consValid()){ - progress += getProgressIncrease(entity, craftTime); - warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); - }else{ - warmup = Mathf.lerpDelta(warmup, 0f, 0.02f); + @Override + public boolean shouldIdleSound(){ + return cons.valid(); } - if(progress >= 1f){ - progress = 0f; - int sum = 0; - for(ItemStack stack : results) sum += stack.amount; + @Override + public boolean shouldConsume(){ + return items.total() < itemCapacity; + } - int i = Mathf.random(sum); - int count = 0; - Item item = null; + @Override + public void draw(){ + super.draw(); - //TODO guaranteed desync since items are random - for(ItemStack stack : results){ - if(i >= count && i < count + stack.amount){ - item = stack.item; - break; + Draw.color(liquids.current().color); + Draw.alpha(liquids.total() / liquidCapacity); + Draw.rect(reg(liquidRegion), x, y); + + Draw.reset(); + if(Core.atlas.isFound(reg(spinnerRegion))){ + Draw.rect(reg(spinnerRegion), x, y, totalProgress * spinnerSpeed); + } + } + + @Override + public void updateTile(){ + totalProgress += warmup * delta(); + + if(consValid()){ + progress += getProgressIncrease(craftTime); + warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); + }else{ + warmup = Mathf.lerpDelta(warmup, 0f, 0.02f); + } + + if(progress >= 1f){ + progress = 0f; + int sum = 0; + for(ItemStack stack : results) sum += stack.amount; + + int i = Mathf.random(sum); + int count = 0; + Item item = null; + + //TODO guaranteed desync since items are random + for(ItemStack stack : results){ + if(i >= count && i < count + stack.amount){ + item = stack.item; + break; + } + count += stack.amount; + } + + consume(); + + if(item != null && items.get(item) < itemCapacity){ + offloadNear(item); } - count += stack.amount; } - consume(); - - if(item != null && items.get(item) < itemCapacity){ - useContent(tile, item); - offloadNear(tile, item); + if(timer(timerDump, dumpTime)){ + dump(); } } - if(timer(timerDump, dumpTime)){ - tryDump(tile); + @Override + public void write(Writes write){ + super.write(write); + write.f(progress); + write.f(warmup); + } + + @Override + public void read(Reads read, byte revision){ + super.read(read, revision); + progress = read.f(); + warmup = read.f(); } } } diff --git a/core/src/mindustry/world/blocks/production/SolidPump.java b/core/src/mindustry/world/blocks/production/SolidPump.java index 97063907d9..13211f7558 100644 --- a/core/src/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/mindustry/world/blocks/production/SolidPump.java @@ -1,21 +1,17 @@ package mindustry.world.blocks.production; -import arc.Core; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.TextureRegion; -import arc.math.Mathf; -import arc.util.*; +import arc.*; +import arc.graphics.g2d.*; +import arc.math.*; import arc.util.ArcAnnotate.*; -import mindustry.content.Fx; -import mindustry.content.Liquids; +import arc.util.*; +import mindustry.content.*; import mindustry.entities.*; -import mindustry.gen.*; -import mindustry.graphics.Pal; -import mindustry.type.Liquid; -import mindustry.ui.Bar; -import mindustry.world.Tile; -import mindustry.world.meta.Attribute; -import mindustry.world.meta.BlockStat; +import mindustry.graphics.*; +import mindustry.type.*; +import mindustry.ui.*; +import mindustry.world.*; +import mindustry.world.meta.*; /** * Pump that makes liquid from solids and takes in power. Only works on solid floor blocks. @@ -69,14 +65,22 @@ public class SolidPump extends Pump{ } @Override - public void draw(){ - Draw.rect(region, x, y); - Draw.color(tile.liquids.current().color); - Draw.alpha(tile.liquids.total() / liquidCapacity); - Draw.rect(liquidRegion, x, y); - Draw.color(); - Draw.rect(name + "-rotator", x, y, pumpTime * rotateSpeed); - Draw.rect(name + "-top", x, y); + public boolean canPlaceOn(Tile tile){ + if(isMultiblock()){ + for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){ + if(canPump(other)){ + return true; + } + } + return false; + }else{ + return canPump(tile); + } + } + + @Override + protected boolean canPump(Tile tile){ + return tile != null && !tile.floor().isLiquid; } @Override @@ -84,76 +88,68 @@ public class SolidPump extends Pump{ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")}; } - @Override - public void updateTile(){ - float fraction = 0f; - - if(isMultiblock()){ - for(Tile other : tile.getLinkedTiles(tempTiles)){ - if(isValid(other)){ - fraction += 1f / (size * size); - } - } - }else{ - if(isValid(tile)) fraction = 1f; - } - - fraction += boost; - - if(tile.cons().valid() && typeLiquid(tile) < liquidCapacity - 0.001f){ - float maxPump = Math.min(liquidCapacity - typeLiquid(tile), pumpAmount * delta() * fraction * efficiency()); - tile.liquids.add(result, maxPump); - lastPump = maxPump; - warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); - if(timer(timerContentCheck, 10)) useContent(tile, result); - if(Mathf.chance(delta() * updateEffectChance)) - updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f)); - }else{ - warmup = Mathf.lerpDelta(warmup, 0f, 0.02f); - lastPump = 0f; - } - - pumpTime += warmup * delta(); - - tryDumpLiquid(tile, result); - } - - @Override - public boolean canPlaceOn(){ - if(isMultiblock()){ - for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){ - if(isValid(other)){ - return true; - } - } - return false; - }else{ - return isValid(tile); - } - } - - @Override - protected boolean isValid(){ - return tile != null && !tile.floor().isLiquid; - } - - @Override - public void onProximityAdded(){ - super.onProximityAdded(); - - if(attribute != null){ - boost = sumAttribute(attribute, tile.x, tile.y); - } - } - - public float typeLiquid(){ - return tile.liquids.total(); - } - - public class SolidPumpEntity extends TileEntity{ + public class SolidPumpEntity extends PumpEntity{ public float warmup; public float pumpTime; public float boost; public float lastPump; + + @Override + public void draw(){ + Draw.rect(region, x, y); + Draw.color(liquids.current().color); + Draw.alpha(liquids.total() / liquidCapacity); + Draw.rect(liquidRegion, x, y); + Draw.color(); + Draw.rect(name + "-rotator", x, y, pumpTime * rotateSpeed); + Draw.rect(name + "-top", x, y); + } + + @Override + public void updateTile(){ + float fraction = 0f; + + if(isMultiblock()){ + for(Tile other : tile.getLinkedTiles(tempTiles)){ + if(canPump(other)){ + fraction += 1f / (size * size); + } + } + }else{ + if(canPump(tile)) fraction = 1f; + } + + fraction += boost; + + if(cons.valid() && typeLiquid() < liquidCapacity - 0.001f){ + float maxPump = Math.min(liquidCapacity - typeLiquid(), pumpAmount * delta() * fraction * efficiency()); + liquids.add(result, maxPump); + lastPump = maxPump; + warmup = Mathf.lerpDelta(warmup, 1f, 0.02f); + if(timer(timerContentCheck, 10)) useContent(result); + if(Mathf.chance(delta() * updateEffectChance)) + updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f)); + }else{ + warmup = Mathf.lerpDelta(warmup, 0f, 0.02f); + lastPump = 0f; + } + + pumpTime += warmup * delta(); + + dumpLiquid(result); + } + + @Override + public void onProximityUpdate(){ + super.onProximityAdded(); + + if(attribute != null){ + boost = sumAttribute(attribute, tile.x, tile.y); + } + } + + public float typeLiquid(){ + return liquids.total(); + } } } diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index f4b841bdcb..25ff63b207 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -99,7 +99,7 @@ public class CoreBlock extends StorageBlock{ storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0); proximity.each(this::isContainer, t -> { t.items(items); - ((StorageBlockEntity)t).linkedCore = tile; + ((StorageBlockEntity)t).linkedCore = this; }); for(Tilec other : state.teams.cores(team)){ diff --git a/core/src/mindustry/world/blocks/storage/LaunchPad.java b/core/src/mindustry/world/blocks/storage/LaunchPad.java index 0e5ba4a466..5987d8d172 100644 --- a/core/src/mindustry/world/blocks/storage/LaunchPad.java +++ b/core/src/mindustry/world/blocks/storage/LaunchPad.java @@ -1,20 +1,16 @@ package mindustry.world.blocks.storage; import arc.*; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.Lines; -import arc.math.Mathf; -import arc.util.Time; -import mindustry.Vars; -import mindustry.content.Fx; -import mindustry.gen.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.util.*; +import mindustry.*; +import mindustry.content.*; import mindustry.game.EventType.*; -import mindustry.graphics.Pal; -import mindustry.type.Item; -import mindustry.type.ItemType; -import mindustry.world.Tile; -import mindustry.world.meta.BlockStat; -import mindustry.world.meta.StatUnit; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.type.*; +import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -37,49 +33,50 @@ public class LaunchPad extends StorageBlock{ stats.add(BlockStat.launchTime, launchTime / 60f, StatUnit.seconds); } - @Override - public boolean acceptItem(Tilec source, Item item){ - return item.type == ItemType.material && tile.items.total() < itemCapacity; - } + public class LaunchPadEntity extends StorageBlockEntity{ + @Override + public void draw(){ + super.draw(); - @Override - public void draw(){ - super.draw(); + //TODO broken + float progress = Mathf.clamp(Mathf.clamp((items.total() / (float)itemCapacity)) * ((timer().getTime(timerLaunch) / (launchTime / timeScale())))); + float scale = size / 3f; - //TODO broken - float progress = Mathf.clamp(Mathf.clamp((tile.items.total() / (float)itemCapacity)) * ((timer().getTime(timerLaunch) / (launchTime / tile.timeScale())))); - float scale = size / 3f; + Lines.stroke(2f); + Draw.color(Pal.accentBack); + Lines.poly(x, y, 4, scale * 10f * (1f - progress), 45 + 360f * progress); - Lines.stroke(2f); - Draw.color(Pal.accentBack); - Lines.poly(x, y, 4, scale * 10f * (1f - progress), 45 + 360f * progress); + Draw.color(Pal.accent); - Draw.color(Pal.accent); + if(cons.valid()){ + for(int i = 0; i < 3; i++){ + float f = (Time.time() / 200f + i * 0.5f) % 1f; - if(tile.cons().valid()){ - for(int i = 0; i < 3; i++){ - float f = (Time.time() / 200f + i * 0.5f) % 1f; - - Lines.stroke(((2f * (2f - Math.abs(0.5f - f) * 2f)) - 2f + 0.2f)); - Lines.poly(x, y, 4, (1f - f) * 10f * scale); + Lines.stroke(((2f * (2f - Math.abs(0.5f - f) * 2f)) - 2f + 0.2f)); + Lines.poly(x, y, 4, (1f - f) * 10f * scale); + } } + + Draw.reset(); } - Draw.reset(); - } + @Override + public boolean acceptItem(Tilec source, Item item){ + return item.type == ItemType.material && items.total() < itemCapacity; + } - @Override - public void updateTile(){ - Tilec entity = tile.entity; + @Override + public void updateTile(){ - if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){ - for(Item item : Vars.content.items()){ - Events.fire(Trigger.itemLaunch); - Fx.padlaunch.at(tile); - int used = Math.min(items.get(item), itemCapacity); - data.addItem(item, used); - items.remove(item, used); - Events.fire(new LaunchItemEvent(item, used)); + if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){ + for(Item item : Vars.content.items()){ + Events.fire(Trigger.itemLaunch); + Fx.padlaunch.at(tile); + int used = Math.min(items.get(item), itemCapacity); + data.addItem(item, used); + items.remove(item, used); + Events.fire(new LaunchItemEvent(item, used)); + } } } } diff --git a/core/src/mindustry/world/blocks/storage/StorageBlock.java b/core/src/mindustry/world/blocks/storage/StorageBlock.java index 1486446d17..79b2b73028 100644 --- a/core/src/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/mindustry/world/blocks/storage/StorageBlock.java @@ -2,32 +2,17 @@ package mindustry.world.blocks.storage; import arc.util.ArcAnnotate.*; import mindustry.gen.*; -import mindustry.type.Item; -import mindustry.world.Block; -import mindustry.world.Tile; +import mindustry.type.*; +import mindustry.world.*; public abstract class StorageBlock extends Block{ public StorageBlock(String name){ super(name); hasItems = true; - } - - @Override - public boolean acceptItem(Tilec source, Item item){ - return linkedCore != null ? linkedCore.acceptItem(linkedCore, source, item) : tile.items.get(item) < getMaximumAccepted(tile, item); - } - - @Override - public int getMaximumAccepted(Item item){ - return itemCapacity; - } - - @Override - public void drawSelect(){ - if(linkedCore != null){ - linkedCore.block().drawSelect(linkedCore); - } + solid = true; + update = false; + destructible = true; } @Override @@ -35,40 +20,54 @@ public abstract class StorageBlock extends Block{ return false; } - /** - * Removes an item and returns it. If item is not null, it should return the item. - * Returns null if no items are there. - */ - public Item removeItem(Item item){ - Tilec entity = tile.entity; - - if(item == null){ - return items.take(); - }else{ - if(items.has(item)){ - items.remove(item, 1); - return item; - } - - return null; - } - } - - /** - * Returns whether this storage block has the specified item. - * If the item is null, it should return whether it has ANY items. - */ - public boolean hasItem(Item item){ - Tilec entity = tile.entity; - if(item == null){ - return items.total() > 0; - }else{ - return items.has(item); - } - } - public class StorageBlockEntity extends TileEntity{ - protected @Nullable - Tile linkedCore; + protected @Nullable Tilec linkedCore; + + /** + * Removes an item and returns it. If item is not null, it should return the item. + * Returns null if no items are there. + */ + @Nullable + public Item removeItem(@Nullable Item item){ + if(item == null){ + return items.take(); + }else{ + if(items.has(item)){ + items.remove(item, 1); + return item; + } + + return null; + } + } + + /** + * Returns whether this storage block has the specified item. + * If the item is null, it should return whether it has ANY items. + */ + public boolean hasItem(@Nullable Item item){ + if(item == null){ + return items.total() > 0; + }else{ + return items.has(item); + } + } + + @Override + public boolean acceptItem(Tilec source, Item item){ + return linkedCore != null ? linkedCore.acceptItem(source, item) : items.get(item) < getMaximumAccepted(item); + } + + @Override + public int getMaximumAccepted(Item item){ + return itemCapacity; + } + + @Override + public void drawSelect(){ + if(linkedCore != null){ + linkedCore.drawSelect(); + } + } } } diff --git a/core/src/mindustry/world/blocks/storage/Unloader.java b/core/src/mindustry/world/blocks/storage/Unloader.java index 899f245a92..ce9ca1167d 100644 --- a/core/src/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/mindustry/world/blocks/storage/Unloader.java @@ -26,12 +26,12 @@ public class Unloader extends Block{ health = 70; hasItems = true; configurable = true; - config(Item.class, (tile, item) -> { - tile.items.clear(); - tile.ent().sortItem = item; + config(Item.class, (tile, item) -> { + tile.items().clear(); + ((UnloaderEntity)tile).sortItem = item; }); - configClear(tile -> tile.ent().sortItem = null); + configClear(tile -> ((UnloaderEntity)tile).sortItem = null); } @Override @@ -39,89 +39,76 @@ public class Unloader extends Block{ drawRequestConfigCenter(req, (Item)req.config, "unloader-center"); } - @Override - public boolean canDump(Tile to, Item item){ - return !(to.block() instanceof StorageBlock); - } - @Override public void setBars(){ super.setBars(); bars.remove("items"); } - @Override - public void playerPlaced(){ - if(lastItem != null){ - tile.configure(lastItem); - } - } - - @Override - public void updateTile(){ - if(timer(timerUnload, speed / timeScale()) && tile.items.total() == 0){ - for(Tile other : tile.proximity()){ - if(other.interactable(team) && other.block().unloadable && other.block().hasItems && items.total() == 0 && - ((sortItem == null && other.items.total() > 0) || hasItem(other, sortItem))){ - offloadNear(tile, removeItem(other, sortItem)); - } - } - } - - if(items.total() > 0){ - tryDump(tile); - } - } - - /** - * Removes an item and returns it. If item is not null, it should return the item. - * Returns null if no items are there. - */ - private Item removeItem(Item item){ - Tilec entity = tile.entity; - - if(item == null){ - return items.take(); - }else{ - if(items.has(item)){ - items.remove(item, 1); - return item; - } - - return null; - } - } - - /** - * Returns whether this storage block has the specified item. - * If the item is null, it should return whether it has ANY items. - */ - private boolean hasItem(Item item){ - Tilec entity = tile.entity; - if(item == null){ - return items.total() > 0; - }else{ - return items.has(item); - } - } - - @Override - public void draw(){ - super.draw(); - - Draw.color(sortItem == null ? Color.clear : sortItem.color); - Draw.rect("unloader-center", x, y); - Draw.color(); - } - - @Override - public void buildConfiguration(Table table){ - ItemSelection.buildTable(table, content.items(), () -> tile.ent().sortItem, item -> tile.configure(lastItem = item)); - } - public class UnloaderEntity extends TileEntity{ public Item sortItem = null; + private Item removeItem(Tilec tile, Item item){ + if(item == null){ + return tile.items().take(); + }else{ + if(tile.items().has(item)){ + tile.items().remove(item, 1); + return item; + } + + return null; + } + } + + private boolean hasItem(Tilec tile, Item item){ + if(item == null){ + return tile.items().total() > 0; + }else{ + return tile.items().has(item); + } + } + + @Override + public void playerPlaced(){ + if(lastItem != null){ + tile.configure(lastItem); + } + } + + @Override + public void updateTile(){ + if(timer(timerUnload, speed / timeScale()) && items.total() == 0){ + for(Tilec other : proximity){ + if(other.interactable(team) && other.block().unloadable && other.block().hasItems && items.total() == 0 && + ((sortItem == null && items.total() > 0) || hasItem(other, sortItem))){ + offloadNear(removeItem(other, sortItem)); + } + } + } + + dump(); + } + + @Override + public void draw(){ + super.draw(); + + Draw.color(sortItem == null ? Color.clear : sortItem.color); + Draw.rect("unloader-center", x, y); + Draw.color(); + } + + @Override + public void buildConfiguration(Table table){ + ItemSelection.buildTable(table, content.items(), () -> tile.ent().sortItem, item -> tile.configure(lastItem = item)); + } + + @Override + public boolean canDump(Tilec to, Item item){ + return !(to.block() instanceof StorageBlock); + } + @Override public Item config(){ return sortItem; diff --git a/core/src/mindustry/world/blocks/storage/Vault.java b/core/src/mindustry/world/blocks/storage/Vault.java deleted file mode 100644 index dcfad3942f..0000000000 --- a/core/src/mindustry/world/blocks/storage/Vault.java +++ /dev/null @@ -1,12 +0,0 @@ -package mindustry.world.blocks.storage; - -public class Vault extends StorageBlock{ - - public Vault(String name){ - super(name); - solid = true; - update = false; - destructible = true; - } - -} diff --git a/core/src/mindustry/world/blocks/units/CommandCenter.java b/core/src/mindustry/world/blocks/units/CommandCenter.java index 893a66402d..7c83fbdfb6 100644 --- a/core/src/mindustry/world/blocks/units/CommandCenter.java +++ b/core/src/mindustry/world/blocks/units/CommandCenter.java @@ -34,44 +34,22 @@ public class CommandCenter extends Block{ destructible = true; solid = true; configurable = true; - config(Integer.class, (tile, value) -> { + config(Integer.class, (tile, value) -> { UnitCommand command = UnitCommand.all[value]; ((CommandCenter)tile.block()).effect.at(tile); - for(Tile center : indexer.getAllied(team, BlockFlag.comandCenter)){ + for(Tile center : indexer.getAllied(tile.team(), BlockFlag.comandCenter)){ if(center.block() instanceof CommandCenter){ CommandCenterEntity entity = center.ent(); - command = command; + entity.command = command; } } - Groups.unit.each(t -> t.team() == team, u -> u.controller().command(command)); + Groups.unit.each(t -> t.team() == tile.team(), u -> u.controller().command(command)); Events.fire(new CommandIssueEvent(tile, command)); }); } - @Override - public void placed(){ - super.placed(); - ObjectSet set = indexer.getAllied(team, BlockFlag.comandCenter); - - if(set.size > 0){ - CommandCenterEntity oe = set.first().ent(); - command = oe.command; - } - } - - @Override - public void removed(){ - super.removed(); - - ObjectSet set = indexer.getAllied(team, BlockFlag.comandCenter); - - if(set.size == 1){ - Groups.unit.each(t -> t.team() == team, u -> u.controller().command(UnitCommand.all[0])); - } - } - @Override public void load(){ super.load(); @@ -83,36 +61,58 @@ public class CommandCenter extends Block{ } } - @Override - public void draw(){ - super.draw(); - - float size = 6f; - - Draw.color(bottomColor); - Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y - 1, size, size); - Draw.color(topColor); - Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y, size, size); - Draw.color(); - } - - @Override - public void buildConfiguration(Table table){ - ButtonGroup group = new ButtonGroup<>(); - Table buttons = new Table(); - - for(UnitCommand cmd : UnitCommand.all){ - buttons.addImageButton(commandRegions[cmd.ordinal()], Styles.clearToggleTransi, () -> tile.configure(cmd.ordinal())) - .size(44).group(group).update(b -> b.setChecked(command == cmd)); - } - table.add(buttons); - table.row(); - table.label(() -> command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center); - } - public class CommandCenterEntity extends TileEntity{ public UnitCommand command = UnitCommand.attack; + @Override + public void draw(){ + super.draw(); + + float size = 6f; + + Draw.color(bottomColor); + Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y - 1, size, size); + Draw.color(topColor); + Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y, size, size); + Draw.color(); + } + + @Override + public void buildConfiguration(Table table){ + ButtonGroup group = new ButtonGroup<>(); + Table buttons = new Table(); + + for(UnitCommand cmd : UnitCommand.all){ + buttons.addImageButton(commandRegions[cmd.ordinal()], Styles.clearToggleTransi, () -> tile.configure(cmd.ordinal())) + .size(44).group(group).update(b -> b.setChecked(command == cmd)); + } + table.add(buttons); + table.row(); + table.label(() -> command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center); + } + + @Override + public void placed(){ + super.placed(); + ObjectSet set = indexer.getAllied(team, BlockFlag.comandCenter); + + if(set.size > 0){ + CommandCenterEntity oe = set.first().ent(); + command = oe.command; + } + } + + @Override + public void onRemoved(){ + super.onRemoved(); + + ObjectSet set = indexer.getAllied(team, BlockFlag.comandCenter); + + if(set.size == 1){ + Groups.unit.each(t -> t.team() == team, u -> u.controller().command(UnitCommand.all[0])); + } + } + @Override public Integer config(){ return command.ordinal(); diff --git a/core/src/mindustry/world/blocks/units/MechPad.java b/core/src/mindustry/world/blocks/units/MechPad.java deleted file mode 100644 index 4f72e4684c..0000000000 --- a/core/src/mindustry/world/blocks/units/MechPad.java +++ /dev/null @@ -1,147 +0,0 @@ -package mindustry.world.blocks.units; - -import arc.graphics.g2d.*; -import arc.math.*; -import arc.math.geom.*; -import arc.struct.*; -import arc.util.ArcAnnotate.*; -import arc.util.*; -import arc.util.io.*; -import mindustry.annotations.Annotations.*; -import mindustry.content.*; -import mindustry.gen.*; -import mindustry.graphics.*; -import mindustry.type.*; -import mindustry.world.*; -import mindustry.world.meta.*; - -import java.io.*; - -import static mindustry.Vars.*; - -//TODO remove -public class MechPad extends Block{ - public @NonNull UnitType mech; - public float buildTime = 60 * 5; - - public MechPad(String name){ - super(name); - update = true; - solid = false; - hasPower = true; - layer = Layer.overlay; - flags = EnumSet.of(BlockFlag.mechPad); - } - - @Override - public void setStats(){ - super.setStats(); - - stats.add(BlockStat.productionTime, buildTime / 60f, StatUnit.seconds); - } - - @Remote(targets = Loc.both, called = Loc.server) - public static void onMechFactoryTap(Playerc player, Tile tile){ - if(player == null || tile == null || !(tile.block() instanceof MechPad) || !checkValidTap(tile, player)) return; - - if(!consValid()) return; - //player.beginRespawning(entity); - sameMech = false; - } - - @Remote(called = Loc.server) - public static void onMechFactoryDone(){ - if(!(tile.entity instanceof MechFactoryEntity)) return; - - Fx.spawn.at(entity); - - if(player == null) return; - //Mech mech = ((MechPad)tile.block()).mech; - //boolean resetSpawner = !sameMech && player.mech == mech; - //player.mech = !sameMech && player.mech == mech ? UnitTypes.starter : mech; - - Playerc player = player; - - //progress = 0; - //player.onRespawn(tile); - //if(resetSpawner) player.lastSpawner = null; - //player = null; - - //Events.fire(new MechChangeEvent(player, player.mech)); - } - - protected static boolean checkValidTap(Playerc player){ - return false;//!player.dead() && tile.interactable(player.team()) && Math.abs(player.x - x) <= tile.block().size * tilesize && - //Math.abs(player.y - y) <= tile.block().size * tilesize && consValid() && player == null; - } - - @Override - public void drawSelect(){ - Draw.color(Pal.accent); - for(int i = 0; i < 4; i++){ - float length = tilesize * size / 2f + 3 + Mathf.absin(Time.time(), 5f, 2f); - Draw.rect("transfer-arrow", x + Geometry.d4[i].x * length, y + Geometry.d4[i].y * length, (i + 2) * 90); - } - Draw.color(); - } - - @Override - public void tapped(Playerc player){ - if(checkValidTap(tile, player)){ - Call.onMechFactoryTap(player, tile); - }else if(player.isLocal() && mobile && !player.dead() && consValid() && player == null){ - //deselect on double taps - //TODO remove - //player.moveTarget = player.moveTarget == tile.entity ? null : tile.entity; - } - } - - @Override - public void drawLayer(){ - if(player != null){ - //TODO remove - //RespawnBlock.drawRespawn(tile, heat, progress, time, player, (!sameMech && player.mech == mech ? UnitTypes.starter : mech)); - } - } - - @Override - public void updateTile(){ - if(player != null){ - player.set(x, y); - heat = Mathf.lerpDelta(heat, 1f, 0.1f); - progress += 1f / buildTime * delta(); - - time += 0.5f * delta(); - - if(progress >= 1f){ - Call.onMechFactoryDone(tile); - } - }else{ - heat = Mathf.lerpDelta(heat, 0f, 0.1f); - } - } - - public class MechFactoryEntity extends TileEntity{ - Playerc player; - boolean sameMech; - float progress; - float time; - float heat; - - @Override - public void write(Writes write){ - super.write(write); - write.f(progress); - write.f(time); - write.f(heat); - } - - @Override - public void read(Reads read, byte revision){ - super.read(read, revision); - progress = read.f(); - time = read.f(); - heat = read.f(); - } - } -} diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index f6aaa07e21..e74fcd8b67 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -1,18 +1,16 @@ package mindustry.world.blocks.units; -import arc.Core; -import arc.struct.EnumSet; -import arc.graphics.Color; +import arc.*; +import arc.graphics.*; import arc.graphics.g2d.*; -import arc.math.Angles; -import arc.math.Mathf; -import arc.math.geom.Rect; -import arc.util.Time; -import mindustry.entities.Units; +import arc.math.*; +import arc.math.geom.*; +import arc.struct.*; +import arc.util.*; +import mindustry.entities.*; import mindustry.gen.*; import mindustry.graphics.*; -import mindustry.world.Block; -import mindustry.world.Tile; +import mindustry.world.*; import mindustry.world.meta.*; import static mindustry.Vars.tilesize; @@ -60,76 +58,76 @@ public class RepairPoint extends Block{ super.init(); } - @Override - public void drawSelect(){ - Drawf.dashCircle(x, y, repairRadius, Pal.accent); - } - @Override public void drawPlace(int x, int y, int rotation, boolean valid){ Drawf.dashCircle(x * tilesize + offset(), y * tilesize + offset(), repairRadius, Pal.accent); } - @Override - public void draw(){ - Draw.rect(baseRegion, x, y); - } - - @Override - public void drawLayer(){ - Draw.rect(region, x, y, rotation - 90); - } - - @Override - public void drawLayer2(){ - if(target != null && - Angles.angleDist(angleTo(target), rotation) < 30f){ - float ang = angleTo(target); - float len = 5f; - - Draw.color(Color.valueOf("e8ffd7")); - Drawf.laser(laser, laserEnd, - x + Angles.trnsx(ang, len), y + Angles.trnsy(ang, len), - target.x(), target.y(), strength); - Draw.color(); - } - } - @Override public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name + "-base"), Core.atlas.find(name)}; } - @Override - public void updateTile(){ - boolean targetIsBeingRepaired = false; - if(target != null && (target.dead() || target.dst(tile) > repairRadius || target.health() >= target.maxHealth())){ - target = null; - }else if(target != null && consValid()){ - target.heal(repairSpeed * Time.delta() * strength * efficiency()); - rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.5f); - targetIsBeingRepaired = true; - } - - if(target != null && targetIsBeingRepaired){ - strength = Mathf.lerpDelta(strength, 1f, 0.08f * Time.delta()); - }else{ - strength = Mathf.lerpDelta(strength, 0f, 0.07f * Time.delta()); - } - - if(timer(timerTarget, 20)){ - rect.setSize(repairRadius * 2).setCenter(x, y); - target = Units.closest(team, x, y, repairRadius, Unitc::damaged); - } - } - - @Override - public boolean shouldConsume(){ - return target != null; - } - public class RepairPointEntity extends TileEntity{ public Unitc target; public float strength, rotation = 90; + + @Override + public void draw(){ + Draw.rect(baseRegion, x, y); + } + + @Override + public void drawLayer(){ + Draw.rect(region, x, y, rotation - 90); + } + + @Override + public void drawLayer2(){ + if(target != null && + Angles.angleDist(angleTo(target), rotation) < 30f){ + float ang = angleTo(target); + float len = 5f; + + Draw.color(Color.valueOf("e8ffd7")); + Drawf.laser(laser, laserEnd, + x + Angles.trnsx(ang, len), y + Angles.trnsy(ang, len), + target.x(), target.y(), strength); + Draw.color(); + } + } + + @Override + public void drawSelect(){ + Drawf.dashCircle(x, y, repairRadius, Pal.accent); + } + + @Override + public void updateTile(){ + boolean targetIsBeingRepaired = false; + if(target != null && (target.dead() || target.dst(tile) > repairRadius || target.health() >= target.maxHealth())){ + target = null; + }else if(target != null && consValid()){ + target.heal(repairSpeed * Time.delta() * strength * efficiency()); + rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.5f); + targetIsBeingRepaired = true; + } + + if(target != null && targetIsBeingRepaired){ + strength = Mathf.lerpDelta(strength, 1f, 0.08f * Time.delta()); + }else{ + strength = Mathf.lerpDelta(strength, 0f, 0.07f * Time.delta()); + } + + if(timer(timerTarget, 20)){ + rect.setSize(repairRadius * 2).setCenter(x, y); + target = Units.closest(team, x, y, repairRadius, Unitc::damaged); + } + } + + @Override + public boolean shouldConsume(){ + return target != null; + } } } diff --git a/core/src/mindustry/world/blocks/units/RespawnBlock.java b/core/src/mindustry/world/blocks/units/RespawnBlock.java deleted file mode 100644 index 16197da656..0000000000 --- a/core/src/mindustry/world/blocks/units/RespawnBlock.java +++ /dev/null @@ -1,74 +0,0 @@ -package mindustry.world.blocks.units; - -import arc.graphics.g2d.*; -import arc.math.*; -import mindustry.gen.*; -import mindustry.graphics.*; -import mindustry.type.*; -import mindustry.ui.*; -import mindustry.world.*; - -import static mindustry.Vars.net; - -//TODO remove ? -public class RespawnBlock{ - - public static void drawRespawn(float heat, float progress, float time, Playerc player, UnitType to){ - progress = Mathf.clamp(progress); - - Draw.color(Pal.darkMetal); - Lines.stroke(2f * heat); - Fill.poly(x, y, 4, 10f * heat); - - Draw.reset(); - if(player != null){ - TextureRegion region = to.icon(Cicon.full); - - Draw.color(0f, 0f, 0f, 0.4f * progress); - Draw.rect("circle-shadow", x, y, region.getWidth() / 3f, region.getWidth() / 3f); - Draw.color(); - - Shaders.build.region = region; - Shaders.build.progress = progress; - Shaders.build.color.set(Pal.accent); - Shaders.build.time = -time / 10f; - - Draw.shader(Shaders.build, true); - Draw.rect(region, x, y); - Draw.shader(); - - Draw.color(Pal.accentBack); - - float pos = Mathf.sin(time, 6f, 8f); - - Lines.lineAngleCenter(x + pos, y, 90, 16f - Math.abs(pos) * 2f); - - Draw.reset(); - } - - Lines.stroke(2f * heat); - - Draw.color(Pal.accentBack); - Lines.poly(x, y, 4, 8f * heat); - - float oy = -7f, len = 6f * heat; - Lines.stroke(5f); - Draw.color(Pal.darkMetal); - Lines.line(x - len, y + oy, x + len, y + oy, CapStyle.none); - for(int i : Mathf.signs){ - Fill.tri(x + len * i, y + oy - Lines.getStroke()/2f, x + len * i, y + oy + Lines.getStroke()/2f, x + (len + Lines.getStroke() * heat) * i, y + oy); - } - - Lines.stroke(3f); - Draw.color(Pal.accent); - Lines.line(x - len, y + oy, x - len + len*2 * progress, y + oy, CapStyle.none); - for(int i : Mathf.signs){ - Fill.tri(x + len * i, y + oy - Lines.getStroke()/2f, x + len * i, y + oy + Lines.getStroke()/2f, x + (len + Lines.getStroke() * heat) * i, y + oy); - } - Draw.reset(); - - if(net.active() && player != null){ - tile.drawPlaceText(player.name(), tile.x, tile.y - (Math.max((tile.block().size-1)/2, 0)), true); - } - } -} diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 7776cc2248..45a510718c 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -18,8 +18,6 @@ import mindustry.world.*; import mindustry.world.consumers.*; import mindustry.world.meta.*; -import java.io.*; - import static mindustry.Vars.net; public class UnitFactory extends Block{ @@ -40,20 +38,21 @@ public class UnitFactory extends Block{ } @Remote(called = Loc.server) - public static void onUnitFactorySpawn(int spawns){ + public static void onUnitFactorySpawn(Tile tile, int spawns){ if(!(tile.entity instanceof UnitFactoryEntity) || !(tile.block() instanceof UnitFactory)) return; UnitFactory factory = (UnitFactory)tile.block(); + UnitFactoryEntity entity = tile.ent(); - buildTime = 0f; - spawned = spawns; + entity.buildTime = 0f; + entity.spawned = spawns; Effects.shake(2f, 3f, entity); - Fx.producesmoke.at(x, y); + Fx.producesmoke.at(entity); if(!net.client()){ - Unitc unit = factory.unitType.create(team); - unit.set(x + Mathf.range(4), y + Mathf.range(4)); + Unitc unit = factory.unitType.create(entity.team()); + unit.set(entity.x() + Mathf.range(4), entity.y() + Mathf.range(4)); unit.add(); unit.vel().y = factory.launchVelocity; Events.fire(new UnitCreateEvent(unit)); @@ -101,87 +100,81 @@ public class UnitFactory extends Block{ stats.add(BlockStat.maxUnits, maxSpawn, StatUnit.none); } - @Override - public void unitRemoved(Unitc unit){ - spawned--; - spawned = Math.max(spawned, 0); - } - @Override public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")}; } - @Override - public void draw(){ - TextureRegion region = unitType.icon(Cicon.full); - - Draw.rect(name, x, y); - - Shaders.build.region = region; - Shaders.build.progress = buildTime / produceTime; - Shaders.build.color.set(Pal.accent); - Shaders.build.color.a = speedScl; - Shaders.build.time = -time / 20f; - - Draw.shader(Shaders.build); - Draw.rect(region, x, y); - Draw.shader(); - - Draw.color(Pal.accent); - Draw.alpha(speedScl); - - Lines.lineAngleCenter( - x + Mathf.sin(time, 20f, Vars.tilesize / 2f * size - 2f), - y, - 90, - size * Vars.tilesize - 4f); - - Draw.reset(); - - Draw.rect(topRegion, x, y); - } - - @Override - public void updateTile(){ - if(spawned >= maxSpawn){ - return; - } - - if(consValid() || tile.isEnemyCheat()){ - time += delta() * speedScl * Vars.state.rules.unitBuildSpeedMultiplier * efficiency(); - buildTime += delta() * efficiency() * Vars.state.rules.unitBuildSpeedMultiplier; - speedScl = Mathf.lerpDelta(speedScl, 1f, 0.05f); - }else{ - speedScl = Mathf.lerpDelta(speedScl, 0f, 0.05f); - } - - if(buildTime >= produceTime){ - buildTime = 0f; - - Call.onUnitFactorySpawn(tile, spawned + 1); - useContent(tile, unitType); - - consume(); - } - } - - @Override - public int getMaximumAccepted(Item item){ - return capacities[item.id]; - } - - @Override - public boolean shouldConsume(){ - return spawned < maxSpawn; - } - public class UnitFactoryEntity extends TileEntity{ float buildTime; float time; float speedScl; int spawned; + + @Override + public void draw(){ + TextureRegion region = unitType.icon(Cicon.full); + + Draw.rect(name, x, y); + + Shaders.build.region = region; + Shaders.build.progress = buildTime / produceTime; + Shaders.build.color.set(Pal.accent); + Shaders.build.color.a = speedScl; + Shaders.build.time = -time / 20f; + + Draw.shader(Shaders.build); + Draw.rect(region, x, y); + Draw.shader(); + + Draw.color(Pal.accent); + Draw.alpha(speedScl); + + Lines.lineAngleCenter( + x + Mathf.sin(time, 20f, Vars.tilesize / 2f * size - 2f), + y, + 90, + size * Vars.tilesize - 4f); + + Draw.reset(); + + Draw.rect(topRegion, x, y); + } + + @Override + public void updateTile(){ + if(spawned >= maxSpawn){ + return; + } + + if(consValid() || tile.isEnemyCheat()){ + time += delta() * speedScl * Vars.state.rules.unitBuildSpeedMultiplier * efficiency(); + buildTime += delta() * efficiency() * Vars.state.rules.unitBuildSpeedMultiplier; + speedScl = Mathf.lerpDelta(speedScl, 1f, 0.05f); + }else{ + speedScl = Mathf.lerpDelta(speedScl, 0f, 0.05f); + } + + if(buildTime >= produceTime){ + buildTime = 0f; + + Call.onUnitFactorySpawn(tile, spawned + 1); + useContent(unitType); + consume(); + } + } + + @Override + public int getMaximumAccepted(Item item){ + return capacities[item.id]; + } + + @Override + public boolean shouldConsume(){ + return spawned < maxSpawn; + } + @Override public void write(Writes write){ super.write(write);